User: stark
Date: 01/03/13 22:40:54
Modified: src/main/org/jboss/naming ExternalContext.java
ExternalContextMBean.java
NonSerializableFactory.java
Log:
Updated to allow for remote access of the external context if the
RemoteAccess attribute is true.
Revision Changes Path
1.3 +230 -89 jboss/src/main/org/jboss/naming/ExternalContext.java
Index: ExternalContext.java
===================================================================
RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/naming/ExternalContext.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ExternalContext.java 2001/01/17 03:29:17 1.2
+++ ExternalContext.java 2001/03/14 06:40:53 1.3
@@ -8,6 +8,9 @@
import java.io.InputStream;
import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.util.Hashtable;
@@ -19,9 +22,12 @@
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
+import javax.naming.RefAddr;
import javax.naming.Reference;
+import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.naming.ldap.Control;
+import javax.naming.spi.ObjectFactory;
import org.jnp.server.Main;
@@ -29,47 +35,70 @@
import org.jboss.util.ServiceMBeanSupport;
/** A MBean that binds an arbitrary InitialContext into the JBoss default
-InitialContext as a Reference to a nonserializable object.
+InitialContext as a Reference. If RemoteAccess is enabled, the reference
+is a Serializable object that is capable of creating the InitialContext
+remotely. If RemoteAccess if false, the reference is to a nonserializable object
+that can only be used from within this VM.
@see org.jboss.naming.NonSerializableFactory
@author [EMAIL PROTECTED]
-@version $Revision: 1.2 $
- */
+@version $Revision: 1.3 $
+*/
public class ExternalContext extends ServiceMBeanSupport implements
ExternalContextMBean
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
- private String jndiName;
- private Class contextClass = javax.naming.InitialContext.class;
- private Properties contextProps;
+ private boolean remoteAccess;
+ private SerializableInitialContext contextInfo = new
SerializableInitialContext();
- // Static --------------------------------------------------------
-
// Constructors --------------------------------------------------
public ExternalContext()
{
}
- public ExternalContext(String jndiName, String contextPropsURL) throws
IOException
+ public ExternalContext(String jndiName, String contextPropsURL)
+ throws IOException, NamingException
{
setJndiName(jndiName);
setProperties(contextPropsURL);
}
- // Public --------------------------------------------------------
/** Set the jndi name under which the external context is bound.
*/
public String getJndiName()
{
- return jndiName;
+ return contextInfo.getJndiName();
}
/** Set the jndi name under which the external context is bound.
*/
- public void setJndiName(String jndiName)
+ public void setJndiName(String jndiName) throws NamingException
+ {
+ contextInfo.setJndiName(jndiName);
+ if( super.getState() == STARTED )
+ {
+ unbind(jndiName);
+ try
+ {
+ rebind();
+ }
+ catch(Exception e)
+ {
+ NamingException ne = new NamingException("Failed to update
jndiName");
+ ne.setRootCause(e);
+ throw ne;
+ }
+ }
+ }
+
+ public boolean getRemoteAccess()
{
- this.jndiName = jndiName;
+ return remoteAccess;
}
+ public void setRemoteAccess(boolean remoteAccess)
+ {
+ this.remoteAccess = remoteAccess;
+ }
/** Get the class name of the InitialContext implementation to
use. Should be one of:
@@ -80,7 +109,7 @@
*/
public String getInitialContext()
{
- return contextClass.getName();
+ return contextInfo.getInitialContext();
}
/** Set the class name of the InitialContext implementation to
@@ -93,79 +122,69 @@
*/
public void setInitialContext(String className) throws ClassNotFoundException
{
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- contextClass = loader.loadClass(className);
+ contextInfo.loadClass(className);
}
+ /** Set the InitialContex class environment properties.
+ */
public void setProperties(String contextPropsURL) throws IOException
{
- InputStream is = null;
- IOException ex = null;
- contextProps = new Properties();
+ contextInfo.loadProperties(contextPropsURL);
+ }
- // See if this is a URL we can load
- try
- {
- URL url = new URL(contextPropsURL);
- is = url.openStream();
- contextProps.load(is);
- return;
- }
- catch(IOException e)
- { // Failed, try to locate a classpath resource below
- is = null;
- ex = e;
- }
+ public String getName()
+ {
+ return "ExternalContext(" + contextInfo.getJndiName() + ")";
+ }
- is =
Thread.currentThread().getContextClassLoader().getResourceAsStream(contextPropsURL);
- if( is == null )
- {
- if( ex != null )
- throw ex;
- throw new IOException("Failed to locate context props as URL or
resource:"+contextPropsURL);
- }
- contextProps.load(is);
- if( log != null )
- log.debug("ContextProps: "+contextProps);
+ public void initService() throws Exception
+ {
}
- public ObjectName getObjectName(MBeanServer server, ObjectName name)
- throws javax.management.MalformedObjectNameException
+ /** Start the service by binding the external context into the
+ JBoss InitialContext.
+ */
+ public void startService() throws Exception
{
- return new ObjectName(OBJECT_NAME);
+ rebind();
}
- public String getName()
+ /** Stop the service by unbinding the external context into the
+ JBoss InitialContext.
+ */
+ public void stopService()
{
- return "ExternalContext(" + jndiName + ")";
+ unbind(contextInfo.getJndiName());
}
- public void initService()
- throws Exception
+ // Protected -----------------------------------------------------
+ private static Context createContext(Context rootContext, Name name) throws
NamingException
{
+ Context subctx = rootContext;
+ for(int n = 0; n < name.size(); n ++)
+ {
+ String atom = name.get(n);
+ try
+ {
+ Object obj = subctx.lookup(atom);
+ subctx = (Context) obj;
+ }
+ catch(NamingException e)
+ { // No binding exists, create a subcontext
+ subctx = subctx.createSubcontext(atom);
+ }
+ }
+
+ return subctx;
}
- public void startService()
- throws Exception
- {
- Class[] types = {Hashtable.class};
- Class[] ldapTypes = {Hashtable.class, Control[].class};
- Context ctx = null;
- try
- {
- Constructor ctor = contextClass.getConstructor(types);
- Object[] args = {contextProps};
- ctx = (Context) ctor.newInstance(args);
- }
- catch(NoSuchMethodException e)
- { // Try the ldap constructor
- Constructor ctor = contextClass.getConstructor(ldapTypes);
- Object[] args = {contextProps, null};
- ctx = (Context) ctor.newInstance(args);
- }
+ private void rebind() throws Exception
+ {
+ Context ctx = contextInfo.newContext();
Context rootCtx = (Context) new InitialContext();
log.debug("ctx="+ctx+", env="+ctx.getEnvironment());
// Get the parent context into which we are to bind
+ String jndiName = contextInfo.getJndiName();
Name fullName = rootCtx.getNameParser("").parse(jndiName);
log.debug("fullName="+fullName);
Name parentName = fullName;
@@ -176,19 +195,26 @@
log.debug("parentName="+parentName);
Context parentCtx = createContext(rootCtx, parentName);
log.debug("parentCtx="+parentCtx);
- // Place the external context into the NonSerializableFactory hashmap
- NonSerializableFactory.rebind(jndiName, ctx);
-
- // Bind a reference to the extern context using NonSerializableFactory as
the ObjectFactory
- String className = "javax.naming.Context";
- String factory = NonSerializableFactory.class.getName();
- StringRefAddr addr = new StringRefAddr("nns", jndiName);
- Reference memoryRef = new Reference(className, addr, factory, null);
- Name atom = fullName.getSuffix(fullName.size()-1);
- parentCtx.rebind(atom, memoryRef);
+ Name atomName = fullName.getSuffix(fullName.size()-1);
+ String atom = atomName.get(0);
+ if( remoteAccess == true )
+ {
+ // Bind contextInfo as a Referenceable
+ parentCtx.rebind(atom, contextInfo);
+ /* Cache the context in the NonSerializableFactory to avoid creating
+ more than one context for in VM lookups
+ */
+ NonSerializableFactory.rebind(atom, ctx);
+ }
+ else
+ {
+ /* Bind a reference to the extern context using
+ NonSerializableFactory as the ObjectFactory */
+ NonSerializableFactory.rebind(parentCtx, atom, ctx);
+ }
}
- public void stopService()
+ private void unbind(String jndiName)
{
try
{
@@ -205,24 +231,139 @@
}
}
- // Protected -----------------------------------------------------
- private static Context createContext(Context rootContext, Name name) throws
NamingException
+ /** The external InitialContext information class. It acts as the
+ RefAddr and ObjectFactory for the external IntialContext and can
+ be marshalled to a remote client.
+ */
+ public static class SerializableInitialContext extends RefAddr
+ implements Referenceable, Serializable, ObjectFactory
{
- Context subctx = rootContext;
- for(int n = 0; n < name.size(); n ++)
+ private static final long serialVersionUID = -6512260531255770463L;
+ private String jndiName;
+ private Class contextClass = javax.naming.InitialContext.class;
+ private Properties contextProps;
+ private transient Context initialContext;
+
+ public SerializableInitialContext()
{
- String atom = name.get(n);
+ this("SerializableInitialContext");
+ }
+ public SerializableInitialContext(String addrType)
+ {
+ super(addrType);
+ }
+
+ public String getJndiName()
+ {
+ return jndiName;
+ }
+ public void setJndiName(String jndiName)
+ {
+ this.jndiName = jndiName;
+ }
+ public String getInitialContext()
+ {
+ return contextClass.getName();
+ }
+ public void loadClass(String className) throws ClassNotFoundException
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ contextClass = loader.loadClass(className);
+ }
+ public void loadProperties(String contextPropsURL) throws IOException
+ {
+ InputStream is = null;
+ IOException ex = null;
+ contextProps = new Properties();
+
+ // See if this is a URL we can load
try
{
- Object obj = subctx.lookup(atom);
- subctx = (Context) obj;
+ URL url = new URL(contextPropsURL);
+ is = url.openStream();
+ contextProps.load(is);
+ return;
}
- catch(NamingException e)
- { // No binding exists, create a subcontext
- subctx = subctx.createSubcontext(atom);
+ catch(IOException e)
+ { // Failed, try to locate a classpath resource below
+ is = null;
+ ex = e;
}
+
+ is =
Thread.currentThread().getContextClassLoader().getResourceAsStream(contextPropsURL);
+ if( is == null )
+ {
+ if( ex != null )
+ throw ex;
+ throw new IOException("Failed to locate context props as URL or
resource:"+contextPropsURL);
+ }
+ contextProps.load(is);
}
- return subctx;
+ Context newContext() throws Exception
+ {
+ if( initialContext == null )
+ { // First check the NonSerializableFactory cache
+ initialContext = (Context) NonSerializableFactory.lookup(jndiName);
+ // Create the context from the contextClass and contextProps
+ if( initialContext == null )
+ initialContext = newContext(contextClass, contextProps);
+ }
+ return initialContext;
+ }
+
+ static Context newContext(Class contextClass, Properties contextProps)
+ throws Exception
+ {
+ Context ctx = null;
+ try
+ {
+ ctx = newDefaultContext(contextClass, contextProps);
+ }
+ catch(NoSuchMethodException e)
+ {
+ ctx = newLdapContext(contextClass, contextProps);
+ }
+ return ctx;
+ }
+ private static Context newDefaultContext(Class contextClass, Properties
contextProps)
+ throws Exception
+ {
+ Context ctx = null;
+ Class[] types = {Hashtable.class};
+ Constructor ctor = contextClass.getConstructor(types);
+ Object[] args = {contextProps};
+ ctx = (Context) ctor.newInstance(args);
+ return ctx;
+ }
+ private static Context newLdapContext(Class contextClass, Properties
contextProps)
+ throws Exception
+ {
+ Context ctx = null;
+ Class[] types = {Hashtable.class, Control[].class};
+ Constructor ctor = contextClass.getConstructor(types);
+ Object[] args = {contextProps, null};
+ ctx = (Context) ctor.newInstance(args);
+ return ctx;
+ }
+
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment) throws Exception
+ {
+ Reference ref = (Reference) obj;
+ SerializableInitialContext sic = (SerializableInitialContext)
ref.get(0);
+ return sic.newContext();
+ }
+
+ public Reference getReference() throws NamingException
+ {
+ Reference ref = new Reference(Context.class.getName(), this,
this.getClass().getName(), null);
+ return ref;
+ }
+
+ public Object getContent()
+ {
+ return null;
+ }
}
+
}
1.3 +14 -10 jboss/src/main/org/jboss/naming/ExternalContextMBean.java
Index: ExternalContextMBean.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/naming/ExternalContextMBean.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ExternalContextMBean.java 2001/01/17 03:29:17 1.2
+++ ExternalContextMBean.java 2001/03/14 06:40:54 1.3
@@ -9,25 +9,29 @@
import java.io.IOException;
import javax.naming.NamingException;
-/**
- *
- *
+/** The ExternalContext mbean interface.
+
@author [EMAIL PROTECTED]
-@version $Revision: 1.2 $
+@version $Revision: 1.3 $
*/
public interface ExternalContextMBean extends org.jboss.util.ServiceMBean
{
- // Constants -----------------------------------------------------
- public static final String OBJECT_NAME = ":service=ExternalContext";
-
- // Public --------------------------------------------------------
-
/** Get the jndi name under which the external context is bound.
*/
public String getJndiName();
/** Set the jndi name under which the external context is bound.
+ */
+ public void setJndiName(String jndiName) throws NamingException;
+ /** Get the remote access flag. If true, the external context is bound using
+ Serializable object that allows the InitialContext to be recreated
+ remotely.
+ */
+ public boolean getRemoteAccess();
+ /** Set the remote access flag. If true, the external context is bound using
+ Serializable object that allows the InitialContext to be recreated
+ remotely.
*/
- public void setJndiName(String jndiName);
+ public void setRemoteAccess(boolean remoteAccess);
/** Get the class name of the InitialContext implementation to
use. Should be one of:
1.4 +19 -10 jboss/src/main/org/jboss/naming/NonSerializableFactory.java
Index: NonSerializableFactory.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/naming/NonSerializableFactory.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- NonSerializableFactory.java 2001/02/08 02:29:48 1.3
+++ NonSerializableFactory.java 2001/03/14 06:40:54 1.4
@@ -66,11 +66,11 @@
@see #rebind(Context, String, Object)
@author [EMAIL PROTECTED]
-@version $Revision: 1.3 $
+@version $Revision: 1.4 $
*/
public class NonSerializableFactory implements ObjectFactory
{
- private static Map wrapperMap = Collections.synchronizedMap(new HashMap());
+ private static Map wrapperMap = Collections.synchronizedMap(new HashMap());
/** Place an object into the NonSerializableFactory namespace for subsequent
access by getObject. There cannot be an already existing binding for key.
@@ -82,12 +82,12 @@
@throws NameAlreadyBoundException, thrown if key already exists in the
NonSerializableFactory map
*/
- public static synchronized void bind(String key, Object target) throws
NameAlreadyBoundException
- {
+ public static synchronized void bind(String key, Object target) throws
NameAlreadyBoundException
+ {
if( wrapperMap.containsKey(key) == true )
throw new NameAlreadyBoundException(key+" already exists in the
NonSerializableFactory map");
- wrapperMap.put(key, target);
- }
+ wrapperMap.put(key, target);
+ }
/** Place or replace an object in the NonSerializableFactory namespce
for subsequent access by getObject. Any existing binding for key will be
replaced by target.
@@ -97,10 +97,10 @@
not have to be.
@param target, the non-Serializable object to bind.
*/
- public static void rebind(String key, Object target)
- {
- wrapperMap.put(key, target);
- }
+ public static void rebind(String key, Object target)
+ {
+ wrapperMap.put(key, target);
+ }
/** Remove a binding from the NonSerializableFactory map.
@@ -113,6 +113,15 @@
{
if( wrapperMap.remove(key) == null )
throw new NameNotFoundException(key+" was not found in the
NonSerializableFactory map");
+ }
+
+ /** Lookup a value from the NonSerializableFactory map.
+ @return the object bound to key is one exists, null otherwise.
+ */
+ public static Object lookup(String key)
+ {
+ Object value = wrapperMap.get(key);
+ return value;
}
/** A convience method that simplifies the process of rebinding a