package com.google.sitebricks.routing;

import com.google.sitebricks.ActionDescriptor;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * An Action that is configured using the at().perform() scheme. See
 * {@link com.google.sitebricks.SitebricksModule} for details.
 *
 * @author dhanji@gmail.com (Dhanji R. Prasanna)
 */
public class SpiAction implements Action {
  private final Action action;
  private final Map<String, String> selectParams;
  private final Map<String,String> selectHeaders;

  public SpiAction(Action action, ActionDescriptor actionDescriptor) {
    this.action = action;
    selectParams = actionDescriptor.getSelectParams();
    selectHeaders = actionDescriptor.getSelectHeaders();
  }

  @Override
  public boolean shouldCall(HttpServletRequest request) {
    boolean should = true;
    if (null != selectParams) {
      for (Map.Entry<String, String> select : selectParams.entrySet()) {
        if (!select.getValue().equals(request.getParameter(select.getKey()))) {
          should = false;
        }
      }
    }

    if (null != selectHeaders) {
      for (Map.Entry<String, String> header : selectHeaders.entrySet()) {
        if (!header.getValue().equals(request.getHeader(header.getKey()))) {
          should = false;
        }
      }
    }
    return should;
  }

  @Override
  public Object call(Object page, Map<String, String> map) {
    return action.call(page, map);
  }
}

package com.google.sitebricks.routing;

import com.google.sitebricks.ActionDescriptor;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * An Action that is configured using the at().perform() scheme. See
 * {@link com.google.sitebricks.SitebricksModule} for details.
 *
 * @author dhanji@gmail.com (Dhanji R. Prasanna)
 */
public class SpiAction implements Action {
  private final Action action;
  private final Map<String, String> selectParams;
  private final Map<String,String> selectHeaders;

  public SpiAction(Action action, ActionDescriptor actionDescriptor) {
    this.action = action;
    selectParams = actionDescriptor.getSelectParams();
    selectHeaders = actionDescriptor.getSelectHeaders();
  }

  @Override
  public boolean shouldCall(HttpServletRequest request) {
    boolean should;

    if (null != selectParams) {
      for (Map.Entry<String, String> select : selectParams.entrySet()) {
        if (!select.getValue().equals(request.getParameter(select.getKey()))) {
          should = false;
        }
      }
    }

    if (null != selectHeaders) {
      for (Map.Entry<String, String> header : selectHeaders.entrySet()) {
        if (!header.getValue().equals(request.getHeader(header.getKey()))) {
          should = false;
        }
      }
    }

    // (JFA) Might be a good idea to pass the value of should as a request attribute
    // so an action can see if what was the value before getting invoked and take a decision based on it.
    should = action.shouldCall(request);  

    return should;
  }

  @Override
  public Object call(Object page, Map<String, String> map) {
    return action.call(page, map);
  }
}

Make sure the Action.shouldCall is always invoked and be override the previous value. This is quite useful for implementing customizable content negotiation.