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
  
  
  

Reply via email to