Overriding PopulationStrategy per ActionBean

Skip to end of metadata
Go to start of metadata

How to use non-default PopulationStrategy only on particular ActionBean(s)

PopulationStrategy is configurable globally, but sometimes it's convenient if we could use different population strategy for a particular action bean. This entry shows you how to achieve it by using a custom population strategy implementation.

Create the custom population strategy and the annotation

The custom population strategy:

SelectivePopulationStrategy
public class SelectivePopulationStrategy implements PopulationStrategy
{
  private static final Log LOG = Log.getInstance(SelectivePopulationStrategy.class);

  private Configuration config;
  private PopulationStrategy defaultDelegate;
  private Map<Class<? extends PopulationStrategy>, PopulationStrategy> delegates = 
    new HashMap<Class<? extends PopulationStrategy>, PopulationStrategy>();
  private Map<Class<? extends ActionBean>, PopulationStrategy> actionBeanStrategies = 
    new HashMap<Class<? extends ActionBean>, PopulationStrategy>();

  protected PopulationStrategy getDelegate(InputTagSupport tag)
    throws StripesJspException
  {
    ActionBean actionBean = tag.getActionBean();
    if (actionBean == null)
      return defaultDelegate;

    // check cache
    Class<? extends ActionBean> beanType = actionBean.getClass();
    PopulationStrategy delegate = actionBeanStrategies.get(beanType);
    if (delegate != null)
      return delegate;

    CustomPopulationStrategy annotation = 
      beanType.getAnnotation(CustomPopulationStrategy.class);
    if (annotation == null)
    {
      delegate = defaultDelegate;
    }
    else
    {
      Class<? extends PopulationStrategy> type = annotation.value();
      delegate = delegates.get(type);
      if (delegate == null)
      {
        try 
        {
          delegate = type.newInstance();
          delegate.init(config);
          delegates.put(type, delegate);
        }
        catch (Exception e) 
        {
          delegate = defaultDelegate;
          LOG.info("Could not instantiate population strategy"
            + " of name [" + type + "]", e);
        }
      }
    }
    
    // cache and return
    actionBeanStrategies.put(beanType, delegate);
    return delegate;
  }

  public Object getValue(InputTagSupport tag) throws StripesJspException 
  {
    PopulationStrategy strategy = getDelegate(tag);
    Object value = (strategy).getValue(tag);
    return value;
  }

  public void init(Configuration configuration) throws Exception 
  {
    this.config = configuration;
    defaultDelegate = new DefaultPopulationStrategy();
    defaultDelegate.init(config);
  }
}

The annotation:

CusomPopulationStrategy
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomPopulationStrategy 
{
  Class<? extends PopulationStrategy> value() 
    default DefaultPopulationStrategy.class;
}

Annotate your ActionBean

Drop the SelectivePopulationStrategy into Stripes' extensions package and annotate your action bean.
Assuming you want to use BeanFirstPopulationStrategy on your ExampleActionBean, it would look as follows.

@CustomPopulationStrategy(BeanFirstPopulationStrategy.class)
public class ExampleActionBean ...
{
...
}

The other (unannotated) action beans will use the DefaultPopulationStrategy.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.