Monday, February 7, 2011

Setting datasource name programmatically for ADF Application

While working on an enterprise application for my client, i received a request from the client that data source name should not be hardcoded in the application and it should be configurable because client wants to deploy it more than one instance of application on the same server for different purposes like preview, production etc. So i googled it, and found excellent article 11g Dynamic JDBC Credentials for Model 1, Struts, Trinidad, and ADF Faces Rich Client
Here it is simplified version:
You will have to extend two following classes:

  • EnvInfoProvider
  • DefaultSessionCookieFactory

EnvInfoProvider
This is main interface and datasource name will be set in the implementation of this interace. You will have to implement following three methods:

  • public Object getInfo(String propName, Object object)
  • public void modifyInitialContext(Object initialContext)
  • public int getNumOfRetries()
Only important method for our scenario is getInfo method. It is used to set new datasource name. Sample implementation is given below:

public Object getInfo(String propName, Object object) {
String myDataSourceName = "test"; // You can set it through your logic
if (object instanceof Hashtable) {
Hashtable connectionEnv = (Hashtable)object;
System.out.println(connectionEnv.get(Configuration.JDBC_CONNECTION_NAME));
String contextPath = (String)ADFContext.getCurrent().getSessionScope().get("contextPath");
connectionEnv.put(Configuration.JDBC_DS_NAME,"java:comp/env/jdbc/"+myDataSourceName );
}
return null;
}

public void modifyInitialContext(Object initialContext) {
}

public int getNumOfRetries() {
return 0;
}

DefaultSessionCookieFactory
In order to configure custom implementation of EnvInfoProvider, you will have to extend DefaultSessionCookieFactory and override createSessionCookie method. Sample implementation is given below:
public SessionCookie createSessionCookie(String name,
String value,
ApplicationPool pool,
Properties properties) {

SessionCookie cookie = super.createSessionCookie(name, value, pool, properties);
Hashtable env = pool.getEnvironment();

env.remove(Configuration.JDBC_CONNECTION_NAME);
EnvInfoProvider provider = new MyEnvInfoProvider();
cookie.setEnvInfoProvider(provider);
return cookie;
}
Now last step is to configure this custom SessionCookieFactory. Open bc4j.xcfg of application module and add following element as a child of respected AppModuleConfig element

No comments: