CompNamingContext.java

00001 
00026 package org.objectweb.jonas.naming;
00027 
00028 import java.util.Enumeration;
00029 import java.util.Hashtable;
00030 import java.util.NoSuchElementException;
00031 
00032 import javax.naming.Binding;
00033 import javax.naming.CompositeName;
00034 import javax.naming.Context;
00035 import javax.naming.InitialContext;
00036 import javax.naming.InvalidNameException;
00037 import javax.naming.LinkRef;
00038 import javax.naming.Name;
00039 import javax.naming.NameAlreadyBoundException;
00040 import javax.naming.NameClassPair;
00041 import javax.naming.NameNotFoundException;
00042 import javax.naming.NameParser;
00043 import javax.naming.NamingEnumeration;
00044 import javax.naming.NamingException;
00045 import javax.naming.NotContextException;
00046 import javax.naming.OperationNotSupportedException;
00047 import javax.naming.RefAddr;
00048 import javax.naming.Reference;
00049 
00050 import org.objectweb.jonas.common.Log;
00051 import org.objectweb.util.monolog.api.BasicLevel;
00052 import org.objectweb.util.monolog.api.Logger;
00053 
00062 public class CompNamingContext implements Context {
00063 
00067     private static Logger logger = null;
00068 
00072     private Hashtable myEnv = null;
00073 
00077     private Hashtable bindings = new Hashtable();
00078 
00082     private static NameParser myParser = new EJBNameParser();
00083 
00087     private String compId;
00088 
00094     public CompNamingContext(String id, Hashtable env) {
00095         if (env != null) {
00096             // clone env to be able to change it.
00097             myEnv = (Hashtable) (env.clone());
00098         }
00099         compId = id;
00100         logger = Log.getLogger(Log.JONAS_NAMING_PREFIX);
00101     }
00102 
00107     public CompNamingContext(String id) {
00108         myEnv = new Hashtable();
00109         compId = id;
00110         logger = Log.getLogger(Log.JONAS_NAMING_PREFIX);
00111     }
00112 
00113     // ------------------------------------------------------------------
00114     // Context implementation
00115     // ------------------------------------------------------------------
00116 
00125     public Object lookup(Name name) throws NamingException {
00126         // Just use the string version for now.
00127         return lookup(name.toString());
00128     }
00129 
00137     public Object lookup(String name) throws NamingException {
00138         logger.log(BasicLevel.DEBUG, name);
00139 
00140         Name n = new CompositeName(name);
00141         if (n.size() < 1) {
00142             // Empty name means this context
00143             logger.log(BasicLevel.DEBUG, "empty name");
00144             return this;
00145         }
00146 
00147         if (n.size() == 1) {
00148             // leaf in the env tree
00149             Object ret = bindings.get(name);
00150             if (ret == null) {
00151                 logger.log(BasicLevel.DEBUG, " " + name + " not found.");
00152                 throw new NameNotFoundException(name);
00153             }
00154             if (ret instanceof LinkRef) {
00155                 // Handle special case of the LinkRef since I think
00156                 // it's not handled by std NamingManager.getObjectInstance().
00157                 // The name hidden in linkref is in the initial context.
00158 
00159                 InitialContext ictx = NamingManager.getInstance().getInitialContext();
00160                 RefAddr ra = ((Reference) ret).get(0);
00161                 try {
00162                     ret = ictx.lookup((String) ra.getContent());
00163                 } catch (Exception e) {
00164                     NamingException ne = new NamingException(e.getMessage());
00165                     ne.setRootCause(e);
00166                     logger.log(BasicLevel.WARN, "unexpected exception " + e.getMessage());
00167                     throw ne;
00168                 }
00169             } else if (ret instanceof Reference) {
00170                 //Use NamingManager to build an object
00171                 try {
00172                     Object o = javax.naming.spi.NamingManager.getObjectInstance(ret, n, this, myEnv);
00173                     ret = o;
00174                 } catch (NamingException e) {
00175                     throw e;
00176                 } catch (Exception e) {
00177                     NamingException ne = new NamingException(e.getMessage());
00178                     ne.setRootCause(e);
00179                     throw ne;
00180                 }
00181                 if (ret == null) {
00182                     logger.log(BasicLevel.WARN, "Can not build an object with the reference " + name);
00183                     throw new NamingException("Can not build an object with the reference '" + name  + "'");
00184                 }
00185             }
00186             return ret;
00187         } else {
00188             // sub context in the env tree
00189             String suffix = n.getSuffix(1).toString();
00190             // should throw exception if sub context not found!
00191             Context subctx = lookupCtx(n.get(0));
00192             return subctx.lookup(suffix);
00193         }
00194     }
00195 
00206     public void bind(Name name, Object obj) throws NamingException {
00207         // Just use the string version for now.
00208         bind(name.toString(), obj);
00209     }
00210 
00220     public void bind(String name, Object obj) throws NamingException {
00221 
00222         logger.log(BasicLevel.DEBUG, name);
00223 
00224         Name n = new CompositeName(name);
00225         if (n.size() < 1) {
00226             logger.log(BasicLevel.ERROR, "CompNamingContext bind empty name ?");
00227             throw new InvalidNameException("CompNamingContext cannot bind empty name");
00228         }
00229 
00230         if (n.size() == 1) {
00231             // leaf in the env tree
00232             if (bindings.get(name) != null) {
00233                 logger.log(BasicLevel.ERROR, "CompNamingContext: trying to overbind");
00234                 throw new NameAlreadyBoundException("CompNamingContext: Use rebind to bind over a name");
00235             }
00236             bindings.put(name, obj);
00237         } else {
00238             // sub context in the env tree
00239             String suffix = n.getSuffix(1).toString();
00240             // must create the subcontext first if it does not exist yet.
00241             Context subctx;
00242             try {
00243                 subctx = lookupCtx(n.get(0));
00244             } catch (NameNotFoundException e) {
00245                 subctx = createSubcontext(n.get(0));
00246             }
00247             subctx.bind(suffix, obj);
00248         }
00249     }
00250 
00261     public void rebind(Name name, Object obj) throws NamingException {
00262         // Just use the string version for now.
00263         rebind(name.toString(), obj);
00264     }
00265 
00277     public void rebind(String name, Object obj) throws NamingException {
00278 
00279         logger.log(BasicLevel.DEBUG, name);
00280 
00281         Name n = new CompositeName(name);
00282         if (n.size() < 1) {
00283             logger.log(BasicLevel.ERROR, "CompNamingContext rebind empty name ?");
00284             throw new InvalidNameException("CompNamingContext cannot rebind empty name");
00285         }
00286 
00287         if (n.size() == 1) {
00288             // leaf in the env tree
00289             bindings.put(name, obj);
00290         } else {
00291             // sub context in the env tree
00292             String suffix = n.getSuffix(1).toString();
00293             // must create the subcontext first if it does not exist yet.
00294             Context subctx;
00295             try {
00296                 subctx = lookupCtx(n.get(0));
00297             } catch (NameNotFoundException e) {
00298                 subctx = createSubcontext(n.get(0));
00299             }
00300             subctx.rebind(suffix, obj);
00301         }
00302     }
00303 
00311     public void unbind(Name name) throws NamingException {
00312         // Just use the string version for now.
00313         unbind(name.toString());
00314     }
00315 
00324     public void unbind(String name) throws NamingException {
00325 
00326         logger.log(BasicLevel.DEBUG, name);
00327 
00328         Name n = new CompositeName(name);
00329         if (n.size() < 1) {
00330             logger.log(BasicLevel.ERROR, "CompNamingContext unbind empty name ?");
00331             throw new InvalidNameException("CompNamingContext cannot unbind empty name");
00332         }
00333 
00334         if (n.size() == 1) {
00335             // leaf in the env tree
00336             if (bindings.get(name) == null) {
00337                 logger.log(BasicLevel.ERROR, "CompNamingContext nothing to unbind");
00338                 throw new NameNotFoundException(name);
00339             }
00340             bindings.remove(name);
00341         } else {
00342             // sub context in the env tree
00343             String suffix = n.getSuffix(1).toString();
00344             // should throw exception if sub context not found!
00345             Context subctx = lookupCtx(n.get(0));
00346             subctx.unbind(suffix);
00347         }
00348     }
00349 
00360     public void rename(Name oldName, Name newName) throws NamingException {
00361         // Just use the string version for now.
00362         rename(oldName.toString(), newName.toString());
00363     }
00364 
00373     public void rename(String oldName, String newName) throws NamingException {
00374 
00375         logger.log(BasicLevel.ERROR, "CompNamingContext rename " + oldName + " in " + newName);
00376 
00377         Object obj = lookup(oldName);
00378         rebind(newName, obj);
00379         unbind(oldName);
00380     }
00381 
00393     public NamingEnumeration list(Name name) throws NamingException {
00394         // Just use the string version for now.
00395         return list(name.toString());
00396     }
00397 
00408     public NamingEnumeration list(String name) throws NamingException {
00409 
00410         logger.log(BasicLevel.DEBUG, name);
00411 
00412         if (name.length() == 0) {
00413             // List this context
00414             return new ListOfNames(bindings);
00415         }
00416         Object obj = lookup(name);
00417         if (obj instanceof Context) {
00418             return ((Context) obj).list("");
00419         } else {
00420             logger.log(BasicLevel.ERROR, "CompNamingContext: can only list a Context");
00421             throw new NotContextException(name);
00422         }
00423     }
00424 
00441     public NamingEnumeration listBindings(Name name) throws NamingException {
00442         // Just use the string version for now.
00443         return listBindings(name.toString());
00444     }
00445 
00456     public NamingEnumeration listBindings(String name) throws NamingException {
00457 
00458         logger.log(BasicLevel.DEBUG, name);
00459 
00460         if (name.length() == 0) {
00461             // List this context
00462             return new ListOfBindings(bindings);
00463         }
00464         Object obj = lookup(name);
00465         if (obj instanceof Context) {
00466             return ((Context) obj).listBindings("");
00467         } else {
00468             logger.log(BasicLevel.ERROR, "CompNamingContext: can only list a Context");
00469             throw new NotContextException(name);
00470         }
00471     }
00472 
00479     public void destroySubcontext(Name name) throws NamingException {
00480         // Just use the string version for now.
00481         destroySubcontext(name.toString());
00482     }
00483 
00490     public void destroySubcontext(String name) throws NamingException {
00491 
00492         logger.log(BasicLevel.ERROR, "CompNamingContext try to destroySubcontext " + name);
00493 
00494         throw new OperationNotSupportedException("CompNamingContext: destroySubcontext");
00495     }
00496 
00509     public Context createSubcontext(Name name) throws NamingException {
00510         // Just use the string version for now.
00511         return createSubcontext(name.toString());
00512     }
00513 
00524     public Context createSubcontext(String name) throws NamingException {
00525 
00526         logger.log(BasicLevel.DEBUG, name);
00527 
00528         Name n = new CompositeName(name);
00529         if (n.size() < 1) {
00530             logger.log(BasicLevel.ERROR, "CompNamingContext createSubcontext with empty name ?");
00531             throw new InvalidNameException("CompNamingContext cannot create empty Subcontext");
00532         }
00533 
00534         Context ctx = null; // returned ctx
00535         if (n.size() == 1) {
00536             // leaf in the env tree: create ctx and bind it in parent.
00537             ctx = new CompNamingContext(compId, myEnv);
00538             bindings.put(name, ctx);
00539         } else {
00540             // as for bind, we must create first all the subcontexts
00541             // if they don't exist yet.
00542             String suffix = n.getSuffix(1).toString();
00543             Context subctx;
00544             name = n.get(0);
00545             try {
00546                 subctx = lookupCtx(name);
00547             } catch (NameNotFoundException e) {
00548                 subctx = createSubcontext(name);
00549             }
00550             ctx = subctx.createSubcontext(suffix);
00551         }
00552         return ctx;
00553     }
00554 
00566     public Object lookupLink(Name name) throws NamingException {
00567         // Just use the string version for now.
00568         return lookupLink(name.toString());
00569     }
00570 
00583     public Object lookupLink(String name) throws NamingException {
00584 
00585         logger.log(BasicLevel.DEBUG, name);
00586 
00587         // To be done. For now: just return the object
00588         logger.log(BasicLevel.ERROR, "CompNamingContext lookupLink not implemented yet!");
00589         return lookup(name);
00590     }
00591 
00601     public NameParser getNameParser(Name name) throws NamingException {
00602         return myParser;
00603     }
00604 
00614     public NameParser getNameParser(String name) throws NamingException {
00615         return myParser;
00616     }
00617 
00627     public Name composeName(Name name, Name prefix) throws NamingException {
00628 
00629         logger.log(BasicLevel.ERROR, "CompNamingContext composeName not implemented!");
00630         throw new OperationNotSupportedException("CompNamingContext composeName");
00631     }
00632 
00642     public String composeName(String name, String prefix) throws NamingException {
00643 
00644         logger.log(BasicLevel.ERROR, "CompNamingContext composeName " + name + " " + prefix);
00645 
00646         throw new OperationNotSupportedException("CompNamingContext composeName");
00647     }
00648 
00661     public Object addToEnvironment(String propName, Object propVal) throws NamingException {
00662 
00663         logger.log(BasicLevel.DEBUG, propName);
00664 
00665         if (myEnv == null) {
00666             myEnv = new Hashtable();
00667         }
00668         return myEnv.put(propName, propVal);
00669     }
00670 
00680     public Object removeFromEnvironment(String propName) throws NamingException {
00681 
00682         logger.log(BasicLevel.DEBUG, propName);
00683 
00684         if (myEnv == null) {
00685             return null;
00686         }
00687         return myEnv.remove(propName);
00688     }
00689 
00696     public Hashtable getEnvironment() throws NamingException {
00697 
00698         logger.log(BasicLevel.DEBUG, "");
00699 
00700         if (myEnv == null) {
00701             myEnv = new Hashtable();
00702         }
00703         return myEnv;
00704     }
00705 
00711     public void close() throws NamingException {
00712         myEnv = null;
00713     }
00714 
00720     public String getNameInNamespace() {
00721         // this is used today for debug only.
00722         return compId;
00723     }
00724 
00725     // ------------------------------------------------------------------
00726     // Private Methods
00727     // ------------------------------------------------------------------
00728 
00737     private Context lookupCtx(String name) throws NamingException {
00738         Object obj = bindings.get(name);
00739         if (obj == null) {
00740             throw new NameNotFoundException();
00741         }
00742         if (obj instanceof CompNamingContext) {
00743             return (Context) obj;
00744         } else {
00745             throw new NameAlreadyBoundException(name);
00746         }
00747     }
00748 
00749     // ------------------------------------------------------------------
00750     // Inner classes for enumerating lists of bindings
00751     // ------------------------------------------------------------------
00752 
00757     class ListOfNames implements NamingEnumeration {
00758         protected Enumeration names;
00759         protected Hashtable bindings;
00760 
00761         // Constructor. Called by list()
00762         // copy bindings locally in this object and build an
00763         // enumeration of the keys.
00764 
00765         ListOfNames (Hashtable bindings) {
00766             this.bindings = bindings;
00767             this.names = bindings.keys();
00768         }
00769 
00770         // Methods implementing NamingEnumeration interface:
00771         // - hasMore
00772         // - next
00773         // - close
00774         public boolean hasMore() throws NamingException {
00775             return names.hasMoreElements();
00776         }
00777 
00778         public Object next() throws NamingException {
00779             String name = (String) names.nextElement();
00780             String className = bindings.get(name).getClass().getName();
00781             return new NameClassPair(name, className);
00782         }
00783 
00784         public void close() {
00785         }
00786 
00787         // Methods inherited from Enumeration:
00788         // - nextElement
00789         // - hasMoreElements
00790 
00791         public Object nextElement() {
00792             try {
00793                 return next();
00794             } catch (NamingException e) {
00795                 throw new NoSuchElementException(e.toString());
00796             }
00797         }
00798 
00799         public boolean hasMoreElements() {
00800             try {
00801                 return hasMore();
00802             } catch (NamingException e) {
00803                 return false;
00804             }
00805         }
00806 
00807     }
00808 
00812     class ListOfBindings extends ListOfNames {
00813 
00814         ListOfBindings (Hashtable bindings) {
00815             super(bindings);
00816         }
00817 
00818         // next() is the only different method.
00819         // It returns a Binding instead of a NameClassPair
00820         public Object next() throws NamingException {
00821             String name = (String) names.nextElement();
00822             return new Binding(name, this.bindings.get(name));
00823         }
00824     }
00825 }

Generated on Tue Feb 15 15:05:19 2005 for JOnAS by  doxygen 1.3.9.1