package org.jboss.fresh.deployer;
import javax.naming.*;
import org.jboss.fresh.registry.RegistryContext;
import org.jboss.fresh.naming.StaticObjectStore;
public abstract class RegistryNamingBinder extends ServiceModule implements RegistryNamingBinderMBean {
private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(RegistryNamingBinder.class);
private String m_jndiName;
private String m_bindName;
private boolean doBindNative = true;
private String nativeJNDIName;
private Object sobj;
private boolean doBindByReference = true;
public String getName() {
return "CP2 Registry Binder Service";
}
public void setJNDIName(String name) {
m_jndiName = name;
}
public String getJNDIName() {
return m_jndiName;
}
public void setServiceObject(Object obj) {
this.sobj = obj;
}
public Object getServiceObject() {
return sobj;
}
public void doStart() throws Exception {
try {
bind();
} catch (NamingException x) {
log.error("Bind failed!", x);
throw x;
}
}
public void doStop() {
try {
unbind();
} catch (NamingException x) {
log.error("Unbind failed!", x);
}
}
abstract protected String getBindClass();
abstract protected Object classToInstance(Class c);
protected Object getBindInstance() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = null;
String bindClassName = getBindClass();
if (bindClassName != null) {
try {
clazz = cl.loadClass(bindClassName);
return classToInstance(clazz);
} catch (ClassNotFoundException e) {
throw new RuntimeException("No such class: " + bindClassName + " : " + e.toString());
}
}
return null;
}
private void bind() throws NamingException {
Context ctx = new RegistryContext();
String name = getJNDIName();
if (name == null)
return;
log.info("name: "+name);
// if (!name.startsWith("java:/")) {
// name = "java:/" + name;
// }
m_bindName = name;
// Ah ! This class isn't serializable, so we use a helper class
// Make this work - oneliner for binding
//ctx.bind(m_bindName, getBindInstance());
Name n = ctx.getNameParser("").parse(m_bindName);
while (n.size() > 1) {
String ctxName = n.get(0);
try {
ctx = (Context) ctx.lookup(ctxName);
} catch (NameNotFoundException e) {
ctx = ctx.createSubcontext(ctxName);
}
n = n.getSuffix(1);
}
Object bindInstance = getBindInstance();
ctx.bind(n.get(0), bindInstance);
log.info(getName() + ": '" + getJNDIName() + "' bound to '" + m_bindName + "' in registry");
icBind(bindInstance);
}
private void icBind(Object bindInstance) throws NamingException {
Context cx = new InitialContext();
String name = getNativeBindName();
if (name == null)
return;
log.debug("native bindName: " + name);
Name n = cx.getNameParser("").parse(name);
Context ctx = cx;
while (n.size() > 1) {
String ctxName = n.get(0);
log.debug("native CtxName: " + ctxName);
try {
cx = (Context) ctx.lookup(ctxName);
if (cx == null){ //to workaround resin bug!
log.debug("Lookup retured null, will create new subcontext");
cx = ctx.createSubcontext(ctxName);
}
} catch (NameNotFoundException e) {
log.debug("Creating subcontext: " + ctxName);
cx = ctx.createSubcontext(ctxName);
}
ctx = cx;
n = n.getSuffix(1);
}
Object binst = bindInstance;
log.info("bindInstance() ? " + binst + " [" + (binst == null ? "" : binst.getClass().getName()) + "]");
// each service decides how it's gonna bind
// - default is by value
if(doBindByReference) {
StringRefAddr addr = new StringRefAddr("nns", name);
Reference ref = new Reference(getBindClass(), addr, StaticObjectStore.class.getName(), null);
StaticObjectStore.put(name, binst);
ctx.bind(n.get(0), ref);
} else {
ctx.bind(n.get(0), binst);
}
log.info(getName() + ": '" + getJNDIName() + "' bound to '" + name + "' in JNDI");
}
private void unbind() throws NamingException {
if (m_bindName != null) {
new RegistryContext().unbind(m_bindName);
log.info(getName() + ": '" + getJNDIName() + "' removed from registry");
}
icUnbind();
}
private void icUnbind() throws NamingException {
String name = getNativeBindName();
if (name != null) {
new InitialContext().unbind(name);
StaticObjectStore.remove(name);
log.info(getName() + ": '" + getNativeBindName() + "' removed from JNDI.");
}
}
public String getNativeBindName() {
if(!doBindNative)
return null;
else if(nativeJNDIName != null)
return nativeJNDIName;
else
return m_jndiName;
}
public void setBindNative(boolean bnat) {
this.doBindNative = bnat;
}
public boolean getBindNative() {
return this.doBindNative;
}
public void setNativeJNDIName(String jndiName) {
this.nativeJNDIName = jndiName;
}
public String getNativeJNDIName() {
return nativeJNDIName;
}
public boolean getBindByReference() {
return doBindByReference;
}
public void setBindByReference(boolean val) {
this.doBindByReference = val;
}
}