views:

532

answers:

2

Consider the following class DialgBean.java, which defines the properties of a dialog box on a web page. Below is the class and its bean definition

public class DialogBean{
  private int height;

  public void setHeight(int height)
  ...
}

<bean id="dialogBean" class="org.springhelp.DialogBean">  
 <property name="height" value="${dialogBean.height}"/>
 ...
</bean>

From the above example you can see that the DialogBean's height property is being fetched by a PropertyPlaceholderConfigurer.

The problem is that the application I am working on supports multiple clients, and most clients have separate requirements for the height parameter of a dialog box. Therefore, I can not simply pull the height parameter from one properties file.

So, how do I inject a client specific height parameter into a DialogBean using the bean definition described above, where the client id is stored as the variant in the java.util.Locale object?

Is there a way to pass to a custom bean factory post processor run time data like the Locale?

A: 

Sounds like you need a ResourceBundle or, in Spring parlance, a MessageSource. Inject that into your bean, and programmatically resolve the value you want at runtime.

MessageSource can wrap the basic ResourceBundle, and is much easier to use.

skaffman
Thanks for the proposed solution, and theoretically this will work. But, at the cost of tightly coupling the pojos with spring. Additionally, this approach would require redundant programatic lookups for every bean property in the DialogBean class, which will add to the verbosity and maintenance of an otherwise simple object.And, type casting will have to be done by hand as the MessageSource only manages strings
Salman Paracha
All true, yes, but I don't see any other option. Spring beans are effectively statically-wired, and although there are some tricks you can pull with request-scoped beans, I don't they'd work in this situation.
skaffman
The only compromise I can think off right now is to declare a default dialog bean, which will serve as parent to all client specific beans; wrap the lookup of the beans behind a custom factory that tries to resolve the client specific bean.The fail state being the default parent dialog bean definition
Salman Paracha
A: 

The simpler, but more cumbersome solution, is

  • declare one bean per local variant and extend from a parent (base) bean.
  • create a thin wrapper for the BeanFactory that accepts the Locale
  • upon lookup for a Locale based bean, the wrapper creates bean name options from the parent (base) bean name and the Locale
  • traverse over the list of bean defintion names and find the first one that matches the list of created name options.

Of course, the list of options have to be in order of priority.

Salman Paracha