Overriding PopulationStrategy per ActionBean
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.