Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » naming » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  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   
   19   package org.apache.naming;
   20   
   21   import java.util.HashMap;
   22   import java.util.Hashtable;
   23   import java.util.Enumeration;
   24   import javax.naming.Context;
   25   import javax.naming.Name;
   26   import javax.naming.LinkRef;
   27   import javax.naming.CompositeName;
   28   import javax.naming.NameParser;
   29   import javax.naming.Referenceable;
   30   import javax.naming.Reference;
   31   import javax.naming.NamingEnumeration;
   32   import javax.naming.NamingException;
   33   import javax.naming.NameAlreadyBoundException;
   34   import javax.naming.NameNotFoundException;
   35   import javax.naming.NotContextException;
   36   import javax.naming.InitialContext;
   37   import javax.naming.OperationNotSupportedException;
   38   import javax.naming.spi.NamingManager;
   39   
   40   /**
   41    * Catalina JNDI Context implementation.
   42    *
   43    * @author Remy Maucherat
   44    * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
   45    */
   46   public class NamingContext implements Context {
   47   
   48   
   49       // -------------------------------------------------------------- Constants
   50   
   51   
   52       /**
   53        * Name parser for this context.
   54        */
   55       protected static final NameParser nameParser = new NameParserImpl();
   56   
   57   
   58       private static org.apache.juli.logging.Log log =
   59           org.apache.juli.logging.LogFactory.getLog(NamingContext.class);
   60   
   61   
   62       // ----------------------------------------------------------- Constructors
   63   
   64   
   65       /**
   66        * Builds a naming context using the given environment.
   67        */
   68       public NamingContext(Hashtable env, String name) 
   69           throws NamingException {
   70           this.bindings = new HashMap();
   71           this.env = new Hashtable();
   72           // FIXME ? Could be put in the environment ?
   73           this.name = name;
   74           // Populating the environment hashtable
   75           if (env != null ) {
   76               Enumeration envEntries = env.keys();
   77               while (envEntries.hasMoreElements()) {
   78                   String entryName = (String) envEntries.nextElement();
   79                   addToEnvironment(entryName, env.get(entryName));
   80               }
   81           }
   82       }
   83   
   84   
   85       /**
   86        * Builds a naming context using the given environment.
   87        */
   88       public NamingContext(Hashtable env, String name, HashMap bindings) 
   89           throws NamingException {
   90           this(env, name);
   91           this.bindings = bindings;
   92       }
   93   
   94   
   95       // ----------------------------------------------------- Instance Variables
   96   
   97   
   98       /**
   99        * Environment.
  100        */
  101       protected Hashtable env;
  102   
  103   
  104       /**
  105        * The string manager for this package.
  106        */
  107       protected StringManager sm = StringManager.getManager(Constants.Package);
  108   
  109   
  110       /**
  111        * Bindings in this Context.
  112        */
  113       protected HashMap bindings;
  114   
  115   
  116       /**
  117        * Name of the associated Catalina Context.
  118        */
  119       protected String name;
  120   
  121   
  122       // --------------------------------------------------------- Public Methods
  123   
  124   
  125       // -------------------------------------------------------- Context Methods
  126   
  127   
  128       /**
  129        * Retrieves the named object. If name is empty, returns a new instance 
  130        * of this context (which represents the same naming context as this 
  131        * context, but its environment may be modified independently and it may 
  132        * be accessed concurrently).
  133        * 
  134        * @param name the name of the object to look up
  135        * @return the object bound to name
  136        * @exception NamingException if a naming exception is encountered
  137        */
  138       public Object lookup(Name name)
  139           throws NamingException {
  140           return lookup(name, true);
  141       }
  142   
  143   
  144       /**
  145        * Retrieves the named object.
  146        * 
  147        * @param name the name of the object to look up
  148        * @return the object bound to name
  149        * @exception NamingException if a naming exception is encountered
  150        */
  151       public Object lookup(String name)
  152           throws NamingException {
  153           return lookup(new CompositeName(name), true);
  154       }
  155   
  156   
  157       /**
  158        * Binds a name to an object. All intermediate contexts and the target 
  159        * context (that named by all but terminal atomic component of the name) 
  160        * must already exist.
  161        * 
  162        * @param name the name to bind; may not be empty
  163        * @param obj the object to bind; possibly null
  164        * @exception NameAlreadyBoundException if name is already bound
  165        * @exception InvalidAttributesException if object did not supply all 
  166        * mandatory attributes
  167        * @exception NamingException if a naming exception is encountered
  168        */
  169       public void bind(Name name, Object obj)
  170           throws NamingException {
  171           bind(name, obj, false);
  172       }
  173   
  174   
  175       /**
  176        * Binds a name to an object.
  177        * 
  178        * @param name the name to bind; may not be empty
  179        * @param obj the object to bind; possibly null
  180        * @exception NameAlreadyBoundException if name is already bound
  181        * @exception InvalidAttributesException if object did not supply all 
  182        * mandatory attributes
  183        * @exception NamingException if a naming exception is encountered
  184        */
  185       public void bind(String name, Object obj)
  186           throws NamingException {
  187           bind(new CompositeName(name), obj);
  188       }
  189   
  190   
  191       /**
  192        * Binds a name to an object, overwriting any existing binding. All 
  193        * intermediate contexts and the target context (that named by all but 
  194        * terminal atomic component of the name) must already exist.
  195        * <p>
  196        * If the object is a DirContext, any existing attributes associated with 
  197        * the name are replaced with those of the object. Otherwise, any 
  198        * existing attributes associated with the name remain unchanged.
  199        * 
  200        * @param name the name to bind; may not be empty
  201        * @param obj the object to bind; possibly null
  202        * @exception InvalidAttributesException if object did not supply all 
  203        * mandatory attributes
  204        * @exception NamingException if a naming exception is encountered
  205        */
  206       public void rebind(Name name, Object obj)
  207           throws NamingException {
  208           bind(name, obj, true);
  209       }
  210   
  211   
  212       /**
  213        * Binds a name to an object, overwriting any existing binding.
  214        * 
  215        * @param name the name to bind; may not be empty
  216        * @param obj the object to bind; possibly null
  217        * @exception InvalidAttributesException if object did not supply all 
  218        * mandatory attributes
  219        * @exception NamingException if a naming exception is encountered
  220        */
  221       public void rebind(String name, Object obj)
  222           throws NamingException {
  223           rebind(new CompositeName(name), obj);
  224       }
  225   
  226   
  227       /**
  228        * Unbinds the named object. Removes the terminal atomic name in name 
  229        * from the target context--that named by all but the terminal atomic 
  230        * part of name.
  231        * <p>
  232        * This method is idempotent. It succeeds even if the terminal atomic 
  233        * name is not bound in the target context, but throws 
  234        * NameNotFoundException if any of the intermediate contexts do not exist. 
  235        * 
  236        * @param name the name to bind; may not be empty
  237        * @exception NameNotFoundException if an intermediate context does not 
  238        * exist
  239        * @exception NamingException if a naming exception is encountered
  240        */
  241       public void unbind(Name name)
  242           throws NamingException {
  243           checkWritable();
  244           
  245           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  246               name = name.getSuffix(1);
  247           if (name.isEmpty())
  248               throw new NamingException
  249                   (sm.getString("namingContext.invalidName"));
  250           
  251           NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
  252           
  253           if (entry == null) {
  254               throw new NameNotFoundException
  255                   (sm.getString("namingContext.nameNotBound", name.get(0)));
  256           }
  257           
  258           if (name.size() > 1) {
  259               if (entry.type == NamingEntry.CONTEXT) {
  260                   ((Context) entry.value).unbind(name.getSuffix(1));
  261               } else {
  262                   throw new NamingException
  263                       (sm.getString("namingContext.contextExpected"));
  264               }
  265           } else {
  266               bindings.remove(name.get(0));
  267           }
  268           
  269       }
  270   
  271   
  272       /**
  273        * Unbinds the named object.
  274        * 
  275        * @param name the name to bind; may not be empty
  276        * @exception NameNotFoundException if an intermediate context does not 
  277        * exist
  278        * @exception NamingException if a naming exception is encountered
  279        */
  280       public void unbind(String name)
  281           throws NamingException {
  282           unbind(new CompositeName(name));
  283       }
  284   
  285   
  286       /**
  287        * Binds a new name to the object bound to an old name, and unbinds the 
  288        * old name. Both names are relative to this context. Any attributes 
  289        * associated with the old name become associated with the new name. 
  290        * Intermediate contexts of the old name are not changed.
  291        * 
  292        * @param oldName the name of the existing binding; may not be empty
  293        * @param newName the name of the new binding; may not be empty
  294        * @exception NameAlreadyBoundException if newName is already bound
  295        * @exception NamingException if a naming exception is encountered
  296        */
  297       public void rename(Name oldName, Name newName)
  298           throws NamingException {
  299           Object value = lookup(oldName);
  300           bind(newName, value);
  301           unbind(oldName);
  302       }
  303   
  304   
  305       /**
  306        * Binds a new name to the object bound to an old name, and unbinds the 
  307        * old name.
  308        * 
  309        * @param oldName the name of the existing binding; may not be empty
  310        * @param newName the name of the new binding; may not be empty
  311        * @exception NameAlreadyBoundException if newName is already bound
  312        * @exception NamingException if a naming exception is encountered
  313        */
  314       public void rename(String oldName, String newName)
  315           throws NamingException {
  316           rename(new CompositeName(oldName), new CompositeName(newName));
  317       }
  318   
  319   
  320       /**
  321        * Enumerates the names bound in the named context, along with the class 
  322        * names of objects bound to them. The contents of any subcontexts are 
  323        * not included.
  324        * <p>
  325        * If a binding is added to or removed from this context, its effect on 
  326        * an enumeration previously returned is undefined.
  327        * 
  328        * @param name the name of the context to list
  329        * @return an enumeration of the names and class names of the bindings in 
  330        * this context. Each element of the enumeration is of type NameClassPair.
  331        * @exception NamingException if a naming exception is encountered
  332        */
  333       public NamingEnumeration list(Name name)
  334           throws NamingException {
  335           // Removing empty parts
  336           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  337               name = name.getSuffix(1);
  338           if (name.isEmpty()) {
  339               return new NamingContextEnumeration(bindings.values().iterator());
  340           }
  341           
  342           NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
  343           
  344           if (entry == null) {
  345               throw new NameNotFoundException
  346                   (sm.getString("namingContext.nameNotBound", name.get(0)));
  347           }
  348           
  349           if (entry.type != NamingEntry.CONTEXT) {
  350               throw new NamingException
  351                   (sm.getString("namingContext.contextExpected"));
  352           }
  353           return ((Context) entry.value).list(name.getSuffix(1));
  354       }
  355   
  356   
  357       /**
  358        * Enumerates the names bound in the named context, along with the class 
  359        * names of objects bound to them.
  360        * 
  361        * @param name the name of the context to list
  362        * @return an enumeration of the names and class names of the bindings in 
  363        * this context. Each element of the enumeration is of type NameClassPair.
  364        * @exception NamingException if a naming exception is encountered
  365        */
  366       public NamingEnumeration list(String name)
  367           throws NamingException {
  368           return list(new CompositeName(name));
  369       }
  370   
  371   
  372       /**
  373        * Enumerates the names bound in the named context, along with the 
  374        * objects bound to them. The contents of any subcontexts are not 
  375        * included.
  376        * <p>
  377        * If a binding is added to or removed from this context, its effect on 
  378        * an enumeration previously returned is undefined.
  379        * 
  380        * @param name the name of the context to list
  381        * @return an enumeration of the bindings in this context. 
  382        * Each element of the enumeration is of type Binding.
  383        * @exception NamingException if a naming exception is encountered
  384        */
  385       public NamingEnumeration listBindings(Name name)
  386           throws NamingException {
  387           // Removing empty parts
  388           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  389               name = name.getSuffix(1);
  390           if (name.isEmpty()) {
  391               return new NamingContextBindingsEnumeration(bindings.values().iterator(), this);
  392           }
  393           
  394           NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
  395           
  396           if (entry == null) {
  397               throw new NameNotFoundException
  398                   (sm.getString("namingContext.nameNotBound", name.get(0)));
  399           }
  400           
  401           if (entry.type != NamingEntry.CONTEXT) {
  402               throw new NamingException
  403                   (sm.getString("namingContext.contextExpected"));
  404           }
  405           return ((Context) entry.value).listBindings(name.getSuffix(1));
  406       }
  407   
  408   
  409       /**
  410        * Enumerates the names bound in the named context, along with the 
  411        * objects bound to them.
  412        * 
  413        * @param name the name of the context to list
  414        * @return an enumeration of the bindings in this context. 
  415        * Each element of the enumeration is of type Binding.
  416        * @exception NamingException if a naming exception is encountered
  417        */
  418       public NamingEnumeration listBindings(String name)
  419           throws NamingException {
  420           return listBindings(new CompositeName(name));
  421       }
  422   
  423   
  424       /**
  425        * Destroys the named context and removes it from the namespace. Any 
  426        * attributes associated with the name are also removed. Intermediate 
  427        * contexts are not destroyed.
  428        * <p>
  429        * This method is idempotent. It succeeds even if the terminal atomic 
  430        * name is not bound in the target context, but throws 
  431        * NameNotFoundException if any of the intermediate contexts do not exist. 
  432        * 
  433        * In a federated naming system, a context from one naming system may be 
  434        * bound to a name in another. One can subsequently look up and perform 
  435        * operations on the foreign context using a composite name. However, an 
  436        * attempt destroy the context using this composite name will fail with 
  437        * NotContextException, because the foreign context is not a "subcontext" 
  438        * of the context in which it is bound. Instead, use unbind() to remove 
  439        * the binding of the foreign context. Destroying the foreign context 
  440        * requires that the destroySubcontext() be performed on a context from 
  441        * the foreign context's "native" naming system.
  442        * 
  443        * @param name the name of the context to be destroyed; may not be empty
  444        * @exception NameNotFoundException if an intermediate context does not 
  445        * exist
  446        * @exception NotContextException if the name is bound but does not name 
  447        * a context, or does not name a context of the appropriate type
  448        */
  449       public void destroySubcontext(Name name)
  450           throws NamingException {
  451           
  452           checkWritable();
  453           
  454           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  455               name = name.getSuffix(1);
  456           if (name.isEmpty())
  457               throw new NamingException
  458                   (sm.getString("namingContext.invalidName"));
  459           
  460           NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
  461           
  462           if (entry == null) {
  463               throw new NameNotFoundException
  464                   (sm.getString("namingContext.nameNotBound", name.get(0)));
  465           }
  466           
  467           if (name.size() > 1) {
  468               if (entry.type == NamingEntry.CONTEXT) {
  469                   ((Context) entry.value).unbind(name.getSuffix(1));
  470               } else {
  471                   throw new NamingException
  472                       (sm.getString("namingContext.contextExpected"));
  473               }
  474           } else {
  475               if (entry.type == NamingEntry.CONTEXT) {
  476                   ((Context) entry.value).close();
  477                   bindings.remove(name.get(0));
  478               } else {
  479                   throw new NotContextException
  480                       (sm.getString("namingContext.contextExpected"));
  481               }
  482           }
  483           
  484       }
  485   
  486   
  487       /**
  488        * Destroys the named context and removes it from the namespace.
  489        * 
  490        * @param name the name of the context to be destroyed; may not be empty
  491        * @exception NameNotFoundException if an intermediate context does not 
  492        * exist
  493        * @exception NotContextException if the name is bound but does not name 
  494        * a context, or does not name a context of the appropriate type
  495        */
  496       public void destroySubcontext(String name)
  497           throws NamingException {
  498           destroySubcontext(new CompositeName(name));
  499       }
  500   
  501   
  502       /**
  503        * Creates and binds a new context. Creates a new context with the given 
  504        * name and binds it in the target context (that named by all but 
  505        * terminal atomic component of the name). All intermediate contexts and 
  506        * the target context must already exist.
  507        * 
  508        * @param name the name of the context to create; may not be empty
  509        * @return the newly created context
  510        * @exception NameAlreadyBoundException if name is already bound
  511        * @exception InvalidAttributesException if creation of the subcontext 
  512        * requires specification of mandatory attributes
  513        * @exception NamingException if a naming exception is encountered
  514        */
  515       public Context createSubcontext(Name name)
  516           throws NamingException {
  517           checkWritable();
  518           
  519           Context newContext = new NamingContext(env, this.name);
  520           bind(name, newContext);
  521           
  522           return newContext;
  523       }
  524   
  525   
  526       /**
  527        * Creates and binds a new context.
  528        * 
  529        * @param name the name of the context to create; may not be empty
  530        * @return the newly created context
  531        * @exception NameAlreadyBoundException if name is already bound
  532        * @exception InvalidAttributesException if creation of the subcontext 
  533        * requires specification of mandatory attributes
  534        * @exception NamingException if a naming exception is encountered
  535        */
  536       public Context createSubcontext(String name)
  537           throws NamingException {
  538           return createSubcontext(new CompositeName(name));
  539       }
  540   
  541   
  542       /**
  543        * Retrieves the named object, following links except for the terminal 
  544        * atomic component of the name. If the object bound to name is not a 
  545        * link, returns the object itself.
  546        * 
  547        * @param name the name of the object to look up
  548        * @return the object bound to name, not following the terminal link 
  549        * (if any).
  550        * @exception NamingException if a naming exception is encountered
  551        */
  552       public Object lookupLink(Name name)
  553           throws NamingException {
  554           return lookup(name, false);
  555       }
  556   
  557   
  558       /**
  559        * Retrieves the named object, following links except for the terminal 
  560        * atomic component of the name.
  561        * 
  562        * @param name the name of the object to look up
  563        * @return the object bound to name, not following the terminal link 
  564        * (if any).
  565        * @exception NamingException if a naming exception is encountered
  566        */
  567       public Object lookupLink(String name)
  568           throws NamingException {
  569           return lookup(new CompositeName(name), false);
  570       }
  571   
  572   
  573       /**
  574        * Retrieves the parser associated with the named context. In a 
  575        * federation of namespaces, different naming systems will parse names 
  576        * differently. This method allows an application to get a parser for 
  577        * parsing names into their atomic components using the naming convention 
  578        * of a particular naming system. Within any single naming system, 
  579        * NameParser objects returned by this method must be equal (using the 
  580        * equals() test).
  581        * 
  582        * @param name the name of the context from which to get the parser
  583        * @return a name parser that can parse compound names into their atomic 
  584        * components
  585        * @exception NamingException if a naming exception is encountered
  586        */
  587       public NameParser getNameParser(Name name)
  588           throws NamingException {
  589   
  590           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  591               name = name.getSuffix(1);
  592           if (name.isEmpty())
  593               return nameParser;
  594   
  595           if (name.size() > 1) {
  596               Object obj = bindings.get(name.get(0));
  597               if (obj instanceof Context) {
  598                   return ((Context) obj).getNameParser(name.getSuffix(1));
  599               } else {
  600                   throw new NotContextException
  601                       (sm.getString("namingContext.contextExpected"));
  602               }
  603           }
  604   
  605           return nameParser;
  606   
  607       }
  608   
  609   
  610       /**
  611        * Retrieves the parser associated with the named context.
  612        * 
  613        * @param name the name of the context from which to get the parser
  614        * @return a name parser that can parse compound names into their atomic 
  615        * components
  616        * @exception NamingException if a naming exception is encountered
  617        */
  618       public NameParser getNameParser(String name)
  619           throws NamingException {
  620           return getNameParser(new CompositeName(name));
  621       }
  622   
  623   
  624       /**
  625        * Composes the name of this context with a name relative to this context.
  626        * <p>
  627        * Given a name (name) relative to this context, and the name (prefix) 
  628        * of this context relative to one of its ancestors, this method returns 
  629        * the composition of the two names using the syntax appropriate for the 
  630        * naming system(s) involved. That is, if name names an object relative 
  631        * to this context, the result is the name of the same object, but 
  632        * relative to the ancestor context. None of the names may be null.
  633        * 
  634        * @param name a name relative to this context
  635        * @param prefix the name of this context relative to one of its ancestors
  636        * @return the composition of prefix and name
  637        * @exception NamingException if a naming exception is encountered
  638        */
  639       public Name composeName(Name name, Name prefix)
  640           throws NamingException {
  641           prefix = (Name) prefix.clone();
  642           return prefix.addAll(name);
  643       }
  644   
  645   
  646       /**
  647        * Composes the name of this context with a name relative to this context.
  648        * 
  649        * @param name a name relative to this context
  650        * @param prefix the name of this context relative to one of its ancestors
  651        * @return the composition of prefix and name
  652        * @exception NamingException if a naming exception is encountered
  653        */
  654       public String composeName(String name, String prefix)
  655           throws NamingException {
  656           return prefix + "/" + name;
  657       }
  658   
  659   
  660       /**
  661        * Adds a new environment property to the environment of this context. If 
  662        * the property already exists, its value is overwritten.
  663        * 
  664        * @param propName the name of the environment property to add; may not 
  665        * be null
  666        * @param propVal the value of the property to add; may not be null
  667        * @exception NamingException if a naming exception is encountered
  668        */
  669       public Object addToEnvironment(String propName, Object propVal)
  670           throws NamingException {
  671           return env.put(propName, propVal);
  672       }
  673   
  674   
  675       /**
  676        * Removes an environment property from the environment of this context. 
  677        * 
  678        * @param propName the name of the environment property to remove; 
  679        * may not be null
  680        * @exception NamingException if a naming exception is encountered
  681        */
  682       public Object removeFromEnvironment(String propName)
  683           throws NamingException {
  684           return env.remove(propName);
  685       }
  686   
  687   
  688       /**
  689        * Retrieves the environment in effect for this context. See class 
  690        * description for more details on environment properties. 
  691        * The caller should not make any changes to the object returned: their 
  692        * effect on the context is undefined. The environment of this context 
  693        * may be changed using addToEnvironment() and removeFromEnvironment().
  694        * 
  695        * @return the environment of this context; never null
  696        * @exception NamingException if a naming exception is encountered
  697        */
  698       public Hashtable getEnvironment()
  699           throws NamingException {
  700           return env;
  701       }
  702   
  703   
  704       /**
  705        * Closes this context. This method releases this context's resources 
  706        * immediately, instead of waiting for them to be released automatically 
  707        * by the garbage collector.
  708        * This method is idempotent: invoking it on a context that has already 
  709        * been closed has no effect. Invoking any other method on a closed 
  710        * context is not allowed, and results in undefined behaviour.
  711        * 
  712        * @exception NamingException if a naming exception is encountered
  713        */
  714       public void close()
  715           throws NamingException {
  716           env.clear();
  717       }
  718   
  719   
  720       /**
  721        * Retrieves the full name of this context within its own namespace.
  722        * <p>
  723        * Many naming services have a notion of a "full name" for objects in 
  724        * their respective namespaces. For example, an LDAP entry has a 
  725        * distinguished name, and a DNS record has a fully qualified name. This 
  726        * method allows the client application to retrieve this name. The string 
  727        * returned by this method is not a JNDI composite name and should not be 
  728        * passed directly to context methods. In naming systems for which the 
  729        * notion of full name does not make sense, 
  730        * OperationNotSupportedException is thrown.
  731        * 
  732        * @return this context's name in its own namespace; never null
  733        * @exception OperationNotSupportedException if the naming system does 
  734        * not have the notion of a full name
  735        * @exception NamingException if a naming exception is encountered
  736        */
  737       public String getNameInNamespace()
  738           throws NamingException {
  739           throw  new OperationNotSupportedException
  740               (sm.getString("namingContext.noAbsoluteName"));
  741           //FIXME ?
  742       }
  743   
  744   
  745       // ------------------------------------------------------ Protected Methods
  746   
  747   
  748       /**
  749        * Retrieves the named object.
  750        * 
  751        * @param name the name of the object to look up
  752        * @param resolveLinks If true, the links will be resolved
  753        * @return the object bound to name
  754        * @exception NamingException if a naming exception is encountered
  755        */
  756       protected Object lookup(Name name, boolean resolveLinks)
  757           throws NamingException {
  758   
  759           // Removing empty parts
  760           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  761               name = name.getSuffix(1);
  762           if (name.isEmpty()) {
  763               // If name is empty, a newly allocated naming context is returned
  764               return new NamingContext(env, this.name, bindings);
  765           }
  766           
  767           NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
  768           
  769           if (entry == null) {
  770               throw new NameNotFoundException
  771                   (sm.getString("namingContext.nameNotBound", name.get(0)));
  772           }
  773           
  774           if (name.size() > 1) {
  775               // If the size of the name is greater that 1, then we go through a
  776               // number of subcontexts.
  777               if (entry.type != NamingEntry.CONTEXT) {
  778                   throw new NamingException
  779                       (sm.getString("namingContext.contextExpected"));
  780               }
  781               return ((Context) entry.value).lookup(name.getSuffix(1));
  782           } else {
  783               if ((resolveLinks) && (entry.type == NamingEntry.LINK_REF)) {
  784                   String link = ((LinkRef) entry.value).getLinkName();
  785                   if (link.startsWith(".")) {
  786                       // Link relative to this context
  787                       return lookup(link.substring(1));
  788                   } else {
  789                       return (new InitialContext(env)).lookup(link);
  790                   }
  791               } else if (entry.type == NamingEntry.REFERENCE) {
  792                   try {
  793                       Object obj = NamingManager.getObjectInstance
  794                           (entry.value, name, this, env);
  795                       if (obj != null) {
  796                           entry.value = obj;
  797                           entry.type = NamingEntry.ENTRY;
  798                       }
  799                       return obj;
  800                   } catch (NamingException e) {
  801                       throw e;
  802                   } catch (Exception e) {
  803                       log.warn(sm.getString
  804                                ("namingContext.failResolvingReference"), e);
  805                       throw new NamingException(e.getMessage());
  806                   }
  807               } else {
  808                   return entry.value;
  809               }
  810           }
  811           
  812       }
  813   
  814   
  815       /**
  816        * Binds a name to an object. All intermediate contexts and the target 
  817        * context (that named by all but terminal atomic component of the name) 
  818        * must already exist.
  819        * 
  820        * @param name the name to bind; may not be empty
  821        * @param obj the object to bind; possibly null
  822        * @param rebind if true, then perform a rebind (ie, overwrite)
  823        * @exception NameAlreadyBoundException if name is already bound
  824        * @exception InvalidAttributesException if object did not supply all 
  825        * mandatory attributes
  826        * @exception NamingException if a naming exception is encountered
  827        */
  828       protected void bind(Name name, Object obj, boolean rebind)
  829           throws NamingException {
  830           
  831           checkWritable();
  832           
  833           while ((!name.isEmpty()) && (name.get(0).length() == 0))
  834               name = name.getSuffix(1);
  835           if (name.isEmpty())
  836               throw new NamingException
  837                   (sm.getString("namingContext.invalidName"));
  838           
  839           NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
  840           
  841           if (name.size() > 1) {
  842               if (entry == null) {
  843                   throw new NameNotFoundException
  844                       (sm.getString("namingContext.nameNotBound", name.get(0)));
  845               }
  846               if (entry.type == NamingEntry.CONTEXT) {
  847                   if (rebind) {
  848                       ((Context) entry.value).rebind(name.getSuffix(1), obj);
  849                   } else {
  850                       ((Context) entry.value).bind(name.getSuffix(1), obj);
  851                   }
  852               } else {
  853                   throw new NamingException
  854                       (sm.getString("namingContext.contextExpected"));
  855               }
  856           } else {
  857               if ((!rebind) && (entry != null)) {
  858                   throw new NameAlreadyBoundException
  859                       (sm.getString("namingContext.alreadyBound", name.get(0)));
  860               } else {
  861                   // Getting the type of the object and wrapping it within a new
  862                   // NamingEntry
  863                   Object toBind = 
  864                       NamingManager.getStateToBind(obj, name, this, env);
  865                   if (toBind instanceof Context) {
  866                       entry = new NamingEntry(name.get(0), toBind, 
  867                                               NamingEntry.CONTEXT);
  868                   } else if (toBind instanceof LinkRef) {
  869                       entry = new NamingEntry(name.get(0), toBind, 
  870                                               NamingEntry.LINK_REF);
  871                   } else if (toBind instanceof Reference) {
  872                       entry = new NamingEntry(name.get(0), toBind, 
  873                                               NamingEntry.REFERENCE);
  874                   } else if (toBind instanceof Referenceable) {
  875                       toBind = ((Referenceable) toBind).getReference();
  876                       entry = new NamingEntry(name.get(0), toBind, 
  877                                               NamingEntry.REFERENCE);
  878                   } else {
  879                       entry = new NamingEntry(name.get(0), toBind, 
  880                                               NamingEntry.ENTRY);
  881                   }
  882                   bindings.put(name.get(0), entry);
  883               }
  884           }
  885           
  886       }
  887   
  888   
  889       /**
  890        * Returns true if writing is allowed on this context.
  891        */
  892       protected boolean isWritable() {
  893           return ContextAccessController.isWritable(name);
  894       }
  895   
  896   
  897       /**
  898        * Throws a naming exception is Context is not writable.
  899        */
  900       protected void checkWritable() 
  901           throws NamingException {
  902           if (!isWritable())
  903               throw new NamingException(sm.getString("namingContext.readOnly"));
  904       }
  905   
  906   
  907   }
  908   

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » naming » [javadoc | source]