package org.togglz.core.jndi;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import org.togglz.core.manager.FeatureManager;
import org.togglz.core.manager.FeatureManagerBuilder;
import org.togglz.core.manager.TogglzConfig;
/**
* <p>
* Implementation of {@link ObjectFactory} that creates a {@link FeatureManager}.
* </p>
*
* <p>
* The method {@link #getConfiguration(Object)} is used to obtain the {@link TogglzConfig} instance to use for building the
* manager. The default implementation assumes that the supplied object is a {@link Reference} with an {@link RefAddr} element
* with the name <code>togglzConfig</code>. This behavior can be changed by overwriting this method.
* </p>
*
* @author Christian Kaltepoth
*
* @see http://tomcat.apache.org/tomcat-7.0-doc/jndi-resources-howto.html#Adding_Custom_Resource_Factories
*/
public class FeatureManagerObjectFactory implements ObjectFactory {
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
TogglzConfig config = getConfiguration(obj);
if (config == null) {
throw new IllegalArgumentException("Unable to find TogglzConfig implementation..");
}
return new FeatureManagerBuilder().togglzConfig(config).build();
}
/**
* This class looks up the {@link TogglzConfig} to use when building the {@link FeatureManager}.
*
* @param obj The {@link Object} obtained from {@link #getObjectInstance(Object, Name, Context, Hashtable)}.
*/
protected TogglzConfig getConfiguration(Object obj) {
if (obj instanceof Reference) {
Reference reference = (Reference) obj;
Enumeration<RefAddr> addrs = reference.getAll();
while (addrs.hasMoreElements()) {
RefAddr refAddr = addrs.nextElement();
if ("togglzConfig".equals(refAddr.getType())) {
String classname = refAddr.getContent().toString().trim();
return (TogglzConfig) createInstance(classname);
}
}
}
return null;
}
/**
* Creates an instance of the supplied class.
*/
protected Object createInstance(String classname) {
// get the classloader to use
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = this.getClass().getClassLoader();
}
// create an instance of the class using the default constructor
try {
return classLoader.loadClass(classname).newInstance();
} catch (InstantiationException e) {
throw new IllegalStateException(e);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
}