Home » geronimo-2.2-source-release » org.apache.geronimo.naming.java » [javadoc | source]

    1   /**
    2    *
    3    * Copyright 2003-2004 The Apache Software Foundation
    4    *
    5    *  Licensed under the Apache License, Version 2.0 (the "License");
    6    *  you may not use this file except in compliance with the License.
    7    *  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   
   18   package org.apache.geronimo.naming.java;
   19   
   20   import java.util.Collections;
   21   import java.util.HashMap;
   22   import java.util.Hashtable;
   23   import java.util.Iterator;
   24   import java.util.Map;
   25   import java.io.Serializable;
   26   
   27   import javax.naming.Binding;
   28   import javax.naming.CompositeName;
   29   import javax.naming.Context;
   30   import javax.naming.LinkRef;
   31   import javax.naming.Name;
   32   import javax.naming.NameClassPair;
   33   import javax.naming.NameNotFoundException;
   34   import javax.naming.NameParser;
   35   import javax.naming.NamingEnumeration;
   36   import javax.naming.NamingException;
   37   import javax.naming.NotContextException;
   38   import javax.naming.OperationNotSupportedException;
   39   import javax.naming.Reference;
   40   import javax.naming.InitialContext;
   41   import javax.naming.spi.NamingManager;
   42   
   43   import org.apache.geronimo.naming.reference.SimpleReference;
   44   import org.apache.geronimo.naming.reference.KernelAwareReference;
   45   import org.apache.geronimo.naming.reference.ClassLoaderAwareReference;
   46   import org.apache.geronimo.kernel.Kernel;
   47   
   48   /**
   49    * A read-only Context in the java: namespace.
   50    * <p>
   51    * This version assumes it and all its subcontext are read-only and any attempt
   52    * to modify (e.g. through bind) will result in an OperationNotSupportedException.
   53    * Each Context in the tree builds a cache of the entries in all sub-contexts
   54    * to optimise the performance of lookup.
   55    * </p>
   56    * <p>This implementation is intended to optimise the performance of lookup(String)
   57    * to about the level of a HashMap get. It has been observed that the scheme
   58    * resolution phase performed by the JVM takes considerably longer, so for
   59    * optimum performance lookups should be coded like:</p>
   60    * <code>
   61    *   Context componentContext = (Context)new InitialContext().lookup("java:comp");
   62    *   String envEntry = (String) componentContext.lookup("env/myEntry");
   63    *   String envEntry2 = (String) componentContext.lookup("env/myEntry2");
   64    * </code>
   65    *
   66    * @version $Rev: 126558 $ $Date: 2005-01-26 15:13:09 -0800 (Wed, 26 Jan 2005) $
   67    */
   68   public class ReadOnlyContext implements Context, Serializable {
   69       protected final Hashtable env;        // environment for this context
   70       protected final Map bindings;         // bindings at my level
   71       protected final Map treeBindings;     // all bindings under me
   72   
   73       private boolean frozen = false;
   74   
   75       public ReadOnlyContext() {
   76           env = new Hashtable();
   77           bindings = new HashMap();
   78           treeBindings = new HashMap();
   79       }
   80   
   81       ReadOnlyContext(Hashtable env) {
   82           if (env == null) {
   83               this.env = new Hashtable();
   84           } else {
   85               this.env = new Hashtable(env);
   86           }
   87           this.bindings = Collections.EMPTY_MAP;
   88           this.treeBindings = Collections.EMPTY_MAP;
   89       }
   90   
   91       protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env) {
   92           this.bindings = clone.bindings;
   93           this.treeBindings = clone.treeBindings;
   94           this.env = new Hashtable(env);
   95       }
   96   
   97       public void freeze() {
   98           frozen = true;
   99       }
  100   
  101       boolean isFrozen() {
  102           return frozen;
  103       }
  104   
  105       /**
  106        * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses.
  107        * It binds every possible lookup into a map in each context.  To do this, each context
  108        * strips off one name segment and if necessary creates a new context for it. Then it asks that context
  109        * to bind the remaining name.  It returns a map containing all the bindings from the next context, plus
  110        * the context it just created (if it in fact created it). (the names are suitably extended by the segment
  111        * originally lopped off).
  112        * @param name
  113        * @param value
  114        * @return
  115        * @throws javax.naming.NamingException
  116        */
  117       protected Map internalBind(String name, Object value) throws NamingException {
  118           assert name != null && name.length() > 0;
  119           assert !frozen;
  120   
  121           Map newBindings = new HashMap();
  122           int pos = name.indexOf('/');
  123           if (pos == -1) {
  124               if (treeBindings.put(name, value) != null) {
  125                   throw new NamingException("Something already bound at " + name);
  126               }
  127               bindings.put(name, value);
  128               newBindings.put(name, value);
  129           } else {
  130               String segment = name.substring(0, pos);
  131               assert segment != null;
  132               assert !segment.equals("");
  133               Object o = treeBindings.get(segment);
  134               if (o == null) {
  135                   o = newContext();
  136                   treeBindings.put(segment, o);
  137                   bindings.put(segment, o);
  138                   newBindings.put(segment, o);
  139               } else if (!(o instanceof ReadOnlyContext)) {
  140                   throw new NamingException("Something already bound where a subcontext should go");
  141               }
  142               ReadOnlyContext readOnlyContext = (ReadOnlyContext)o;
  143               String remainder = name.substring(pos + 1);
  144               Map subBindings = readOnlyContext.internalBind(remainder, value);
  145               for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) {
  146                   Map.Entry entry = (Map.Entry) iterator.next();
  147                   String subName = segment + "/" + entry.getKey();
  148                   Object bound = entry.getValue();
  149                   treeBindings.put(subName, bound);
  150                   newBindings.put(subName, bound);
  151               }
  152           }
  153           return newBindings;
  154       }
  155   
  156       protected ReadOnlyContext newContext() {
  157           return new ReadOnlyContext();
  158       }
  159   
  160       public void setKernel(Kernel kernel) {
  161           for (Iterator iterator = treeBindings.values().iterator(); iterator.hasNext();) {
  162               Object o = iterator.next();
  163               if (o instanceof KernelAwareReference) {
  164                   ((KernelAwareReference) o).setKernel(kernel);
  165               }
  166           }
  167       }
  168   
  169       public void setClassLoader(ClassLoader classLoader) {
  170           for (Iterator iterator = treeBindings.values().iterator(); iterator.hasNext();) {
  171               Object o = iterator.next();
  172               if (o instanceof ClassLoaderAwareReference) {
  173                   ((ClassLoaderAwareReference) o).setClassLoader(classLoader);
  174               }
  175           }
  176       }
  177   
  178       public Object addToEnvironment(String propName, Object propVal) throws NamingException {
  179           return env.put(propName, propVal);
  180       }
  181   
  182       public Hashtable getEnvironment() throws NamingException {
  183           return (Hashtable) env.clone();
  184       }
  185   
  186       public Object removeFromEnvironment(String propName) throws NamingException {
  187           return env.remove(propName);
  188       }
  189   
  190       public Object lookup(String name) throws NamingException {
  191           if (name.length() == 0) {
  192               return this;
  193           }
  194           Object result = treeBindings.get(name);
  195           if (result == null) {
  196               if (name.indexOf(':') > 0) {
  197                   Context ctx = new InitialContext();
  198                   return ctx.lookup(name);
  199               } else {
  200                   // Split out the first name of the path
  201                   // and look for it in the bindings map.
  202                   CompositeName path = new CompositeName(name);
  203   
  204                   if (path.size() == 0) {
  205                       return this;
  206                   } else {
  207                       Object obj = bindings.get(path.get(0));
  208                       if (obj == null){
  209                           throw new NameNotFoundException(name);
  210                       } else if (obj instanceof Context && path.size() > 1){
  211                           Context subContext = (Context) obj;
  212                           obj = subContext.lookup(path.getSuffix(1));
  213                       }
  214                       return obj;
  215                   }
  216               }
  217           }
  218           if (result instanceof SimpleReference) {
  219               try {
  220                   result = ((SimpleReference) result).getContent();
  221               } catch (Exception e) {
  222                   throw (NamingException)new NamingException("could not look up : " + name).initCause(e);
  223               }
  224           }
  225           if (result instanceof LinkRef) {
  226               LinkRef ref = (LinkRef) result;
  227               result = lookup(ref.getLinkName());
  228           }
  229           if (result instanceof Reference) {
  230               try {
  231                   result = NamingManager.getObjectInstance(result, null, null, this.env);
  232               } catch (NamingException e) {
  233                   throw e;
  234               } catch (Exception e) {
  235                   throw (NamingException)new NamingException("could not look up : " + name).initCause(e);
  236               }
  237           }
  238           return result;
  239       }
  240   
  241       public Object lookup(Name name) throws NamingException {
  242           return lookup(name.toString());
  243       }
  244   
  245       public Object lookupLink(String name) throws NamingException {
  246           return lookup(name);
  247       }
  248   
  249       public Name composeName(Name name, Name prefix) throws NamingException {
  250           Name result = (Name) prefix.clone();
  251           result.addAll(name);
  252           return result;
  253       }
  254   
  255       public String composeName(String name, String prefix) throws NamingException {
  256           CompositeName result = new CompositeName(prefix);
  257           result.addAll(new CompositeName(name));
  258           return result.toString();
  259       }
  260   
  261       public NamingEnumeration list(String name) throws NamingException {
  262           Object o = lookup(name);
  263           if (o == this) {
  264               return new ListEnumeration();
  265           } else if (o instanceof Context) {
  266               return ((Context) o).list("");
  267           } else {
  268               throw new NotContextException();
  269           }
  270       }
  271   
  272       public NamingEnumeration listBindings(String name) throws NamingException {
  273           Object o = lookup(name);
  274           if (o == this) {
  275               return new ListBindingEnumeration();
  276           } else if (o instanceof Context) {
  277               return ((Context) o).listBindings("");
  278           } else {
  279               throw new NotContextException();
  280           }
  281       }
  282   
  283       public Object lookupLink(Name name) throws NamingException {
  284           return lookupLink(name.toString());
  285       }
  286   
  287       public NamingEnumeration list(Name name) throws NamingException {
  288           return list(name.toString());
  289       }
  290   
  291       public NamingEnumeration listBindings(Name name) throws NamingException {
  292           return listBindings(name.toString());
  293       }
  294   
  295       public void bind(Name name, Object obj) throws NamingException {
  296           throw new OperationNotSupportedException();
  297       }
  298   
  299       public void bind(String name, Object obj) throws NamingException {
  300           throw new OperationNotSupportedException();
  301       }
  302   
  303       public void close() throws NamingException {
  304           throw new OperationNotSupportedException();
  305       }
  306   
  307       public Context createSubcontext(Name name) throws NamingException {
  308           throw new OperationNotSupportedException();
  309       }
  310   
  311       public Context createSubcontext(String name) throws NamingException {
  312           throw new OperationNotSupportedException();
  313       }
  314   
  315       public void destroySubcontext(Name name) throws NamingException {
  316           throw new OperationNotSupportedException();
  317       }
  318   
  319       public void destroySubcontext(String name) throws NamingException {
  320           throw new OperationNotSupportedException();
  321       }
  322   
  323       public String getNameInNamespace() throws NamingException {
  324           throw new OperationNotSupportedException();
  325       }
  326   
  327       public NameParser getNameParser(Name name) throws NamingException {
  328           throw new OperationNotSupportedException();
  329       }
  330   
  331       public NameParser getNameParser(String name) throws NamingException {
  332           throw new OperationNotSupportedException();
  333       }
  334   
  335       public void rebind(Name name, Object obj) throws NamingException {
  336           throw new OperationNotSupportedException();
  337       }
  338   
  339       public void rebind(String name, Object obj) throws NamingException {
  340           throw new OperationNotSupportedException();
  341       }
  342   
  343       public void rename(Name oldName, Name newName) throws NamingException {
  344           throw new OperationNotSupportedException();
  345       }
  346   
  347       public void rename(String oldName, String newName) throws NamingException {
  348           throw new OperationNotSupportedException();
  349       }
  350   
  351       public void unbind(Name name) throws NamingException {
  352           throw new OperationNotSupportedException();
  353       }
  354   
  355       public void unbind(String name) throws NamingException {
  356           throw new OperationNotSupportedException();
  357       }
  358   
  359       private abstract class LocalNamingEnumeration implements NamingEnumeration {
  360           private Iterator i = bindings.entrySet().iterator();
  361   
  362           public boolean hasMore() throws NamingException {
  363               return i.hasNext();
  364           }
  365   
  366           public boolean hasMoreElements() {
  367               return i.hasNext();
  368           }
  369   
  370           protected Map.Entry getNext() {
  371               return (Map.Entry) i.next();
  372           }
  373   
  374           public void close() throws NamingException {
  375           }
  376       }
  377   
  378       private class ListEnumeration extends LocalNamingEnumeration {
  379           public Object next() throws NamingException {
  380               return nextElement();
  381           }
  382   
  383           public Object nextElement() {
  384               Map.Entry entry = getNext();
  385               return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName());
  386           }
  387       }
  388   
  389       private class ListBindingEnumeration extends LocalNamingEnumeration {
  390           public Object next() throws NamingException {
  391               return nextElement();
  392           }
  393   
  394           public Object nextElement() {
  395               Map.Entry entry = getNext();
  396               return new Binding((String) entry.getKey(), entry.getValue());
  397           }
  398       }
  399   }

Home » geronimo-2.2-source-release » org.apache.geronimo.naming.java » [javadoc | source]