Source for javax.naming.spi.NamingManager

   1: /* NamingManager.java --
   2:    Copyright (C) 2000, 2001, 2002, 2003, 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.naming.spi;
  40: 
  41: import java.util.Enumeration;
  42: import java.util.Hashtable;
  43: import java.util.StringTokenizer;
  44: 
  45: import javax.naming.CannotProceedException;
  46: import javax.naming.Context;
  47: import javax.naming.Name;
  48: import javax.naming.NamingException;
  49: import javax.naming.NoInitialContextException;
  50: import javax.naming.RefAddr;
  51: import javax.naming.Reference;
  52: import javax.naming.Referenceable;
  53: import javax.naming.StringRefAddr;
  54: 
  55: public class NamingManager
  56: {
  57:   public static final String CPE = "java.naming.spi.CannotProceedException";
  58: 
  59:   private static InitialContextFactoryBuilder icfb;
  60: 
  61:   // Package private so DirectoryManager can access it.
  62:   static ObjectFactoryBuilder ofb;
  63: 
  64:   // This class cannot be instantiated.
  65:   NamingManager ()
  66:   {
  67:   }
  68: 
  69:   public static boolean hasInitialContextFactoryBuilder ()
  70:   {
  71:     return icfb != null;
  72:   }
  73:   
  74:   public static Context getInitialContext (Hashtable environment)
  75:     throws NamingException
  76:   {
  77:     InitialContextFactory icf = null;
  78:     
  79:     if (icfb != null)
  80:       icf = icfb.createInitialContextFactory(environment);
  81:     else
  82:       {     
  83:     String java_naming_factory_initial = null;
  84:     if (environment != null)
  85:       java_naming_factory_initial
  86:         = (String) environment.get (Context.INITIAL_CONTEXT_FACTORY);
  87:     if (java_naming_factory_initial == null)
  88:       java_naming_factory_initial =
  89:         System.getProperty (Context.INITIAL_CONTEXT_FACTORY);
  90:     if (java_naming_factory_initial == null)
  91:       throw new
  92:         NoInitialContextException ("Can't find property: "
  93:                        + Context.INITIAL_CONTEXT_FACTORY);
  94: 
  95:     try
  96:       {
  97:         icf = (InitialContextFactory)Class.forName
  98:         (java_naming_factory_initial, true,
  99:          Thread.currentThread().getContextClassLoader())
 100:         .newInstance ();
 101:       }
 102:     catch (Exception exception)
 103:       {
 104:         NoInitialContextException e
 105:           = new NoInitialContextException
 106:           ("Can't load InitialContextFactory class: "
 107:            + java_naming_factory_initial);
 108:         e.setRootCause(exception);
 109:         throw e;
 110:       }
 111:       }
 112: 
 113:     return icf.getInitialContext (environment);
 114:   }
 115: 
 116:   static Context getURLContext (Object refInfo,
 117:                 Name name,
 118:                 Context nameCtx,
 119:                 String scheme,
 120:                 Hashtable environment) 
 121:     throws NamingException
 122:   {
 123:     String prefixes = null;
 124:     if (environment != null)
 125:       prefixes = (String) environment.get (Context.URL_PKG_PREFIXES);
 126:     if (prefixes == null)
 127:       prefixes = System.getProperty (Context.URL_PKG_PREFIXES);
 128:     if (prefixes == null)
 129:       {
 130:     // Specified as the default in the docs.  Unclear if this is
 131:     // right for us.
 132:     prefixes = "com.sun.jndi.url";
 133:       }
 134: 
 135:     scheme = scheme + "." + scheme + "URLContextFactory";
 136: 
 137:     StringTokenizer tokens = new StringTokenizer (prefixes, ":");
 138:     while (tokens.hasMoreTokens ())
 139:       {
 140:     String aTry = tokens.nextToken ();
 141:     try
 142:       {
 143:         Class factoryClass = Class.forName (aTry + "." + scheme,
 144:                         true,
 145:                         Thread.currentThread().getContextClassLoader());
 146:         ObjectFactory factory =
 147:           (ObjectFactory) factoryClass.newInstance ();
 148:         Object obj = factory.getObjectInstance (refInfo, name,
 149:                             nameCtx, environment);
 150:         Context ctx = (Context) obj;
 151:         if (ctx != null)
 152:           return ctx;
 153:       }
 154:     catch (ClassNotFoundException _1)
 155:       {
 156:         // Ignore it.
 157:       }
 158:     catch (ClassCastException _2)
 159:       {
 160:         // This means that the class we found was not an
 161:         // ObjectFactory or that the factory returned something
 162:         // which was not a Context.
 163:       }
 164:     catch (InstantiationException _3)
 165:       {
 166:         // If we couldn't instantiate the factory we might get
 167:         // this.
 168:       }
 169:     catch (IllegalAccessException _4)
 170:       {
 171:         // Another possibility when instantiating.
 172:       }
 173:     catch (NamingException _5)
 174:       {
 175:         throw _5;
 176:       }
 177:     catch (Exception _6)
 178:       {
 179:         // Anything from getObjectInstance.
 180:       }
 181:       }
 182: 
 183:     return null;
 184:   }
 185: 
 186:   public static Context getURLContext (String scheme,
 187:                        Hashtable environment) 
 188:        throws NamingException
 189:   {
 190:     return getURLContext (null, null, null, scheme, environment);
 191:   }
 192: 
 193:   public static void setObjectFactoryBuilder (ObjectFactoryBuilder builder)
 194:     throws NamingException
 195:   {
 196:     SecurityManager sm = System.getSecurityManager ();
 197:     if (sm != null)
 198:       sm.checkSetFactory ();
 199:     // Once the builder is installed it cannot be replaced.
 200:     if (ofb != null)
 201:       throw new IllegalStateException ("builder already installed");
 202:     if (builder != null)
 203:       ofb = builder;
 204:   }
 205: 
 206:   static StringTokenizer getPlusPath (String property, Hashtable env,
 207:                       Context nameCtx)
 208:     throws NamingException
 209:   {
 210:     String path = (String) env.get (property);
 211:     if (nameCtx == null)
 212:       nameCtx = getInitialContext (env);
 213:     String path2 = (String) nameCtx.getEnvironment ().get (property);
 214:     if (path == null)
 215:       path = path2;
 216:     else if (path2 != null)
 217:       path += ":" + path2;
 218:     return new StringTokenizer (path != null ? path : "", ":");
 219:   }
 220: 
 221:   public static Object getObjectInstance (Object refInfo,
 222:                       Name name,
 223:                       Context nameCtx,
 224:                       Hashtable environment)
 225:     throws Exception
 226:   {
 227:     ObjectFactory factory = null;
 228: 
 229:     if (ofb != null)
 230:       factory = ofb.createObjectFactory (refInfo, environment);
 231:     else
 232:       {
 233:     // First see if we have a Reference or a Referenceable.  If so
 234:     // we do some special processing.
 235:     Object ref2 = refInfo;
 236:     if (refInfo instanceof Referenceable)
 237:       ref2 = ((Referenceable) refInfo).getReference ();
 238:     if (ref2 instanceof Reference)
 239:       {
 240:         Reference ref = (Reference) ref2;
 241: 
 242:         // If we have a factory class name then we use that.
 243:         String fClass = ref.getFactoryClassName ();
 244:         if (fClass != null)
 245:           {
 246:         // Exceptions here are passed to the caller.
 247:         Class k = Class.forName (fClass,
 248:                      true,
 249:                      Thread.currentThread().getContextClassLoader());
 250:         factory = (ObjectFactory) k.newInstance ();
 251:           }
 252:         else
 253:           {
 254:         // There's no factory class name.  If the address is a
 255:         // StringRefAddr with address type `URL', then we try
 256:         // the URL's context factory.
 257:         Enumeration e = ref.getAll ();
 258:         while (e.hasMoreElements ())
 259:           {
 260:             RefAddr ra = (RefAddr) e.nextElement ();
 261:             if (ra instanceof StringRefAddr
 262:             && "URL".equals (ra.getType ()))
 263:               {
 264:             factory
 265:               = (ObjectFactory) getURLContext (refInfo,
 266:                                name,
 267:                                nameCtx,
 268:                                (String) ra.getContent (),
 269:                                environment);
 270:             Object obj = factory.getObjectInstance (refInfo,
 271:                                 name,
 272:                                 nameCtx,
 273:                                 environment);
 274:             if (obj != null)
 275:               return obj;
 276:               }
 277:           }
 278: 
 279:         // Have to try the next step.
 280:         factory = null;
 281:           }
 282:       }
 283: 
 284:     // Now look at OBJECT_FACTORIES to find the factory.
 285:     if (factory == null)
 286:       {
 287:         StringTokenizer tokens = getPlusPath (Context.OBJECT_FACTORIES,
 288:                           environment, nameCtx);
 289: 
 290:         while (tokens.hasMoreTokens ())
 291:           {
 292:         String klassName = tokens.nextToken ();
 293:         Class k = Class.forName (klassName,
 294:                      true,
 295:                      Thread.currentThread().getContextClassLoader());
 296:         factory = (ObjectFactory) k.newInstance ();
 297:         Object obj = factory.getObjectInstance (refInfo, name,
 298:                             nameCtx, environment);
 299:         if (obj != null)
 300:           return obj;
 301:           }
 302: 
 303:         // Failure.
 304:         return refInfo;
 305:       }
 306:       }
 307: 
 308:     if (factory == null)
 309:       return refInfo;
 310:     Object obj = factory.getObjectInstance (refInfo, name,
 311:                         nameCtx, environment);
 312:     return obj == null ? refInfo : obj;
 313:   }
 314: 
 315:   public static void setInitialContextFactoryBuilder (InitialContextFactoryBuilder builder)
 316:     throws NamingException
 317:   {
 318:     SecurityManager sm = System.getSecurityManager ();
 319:     if (sm != null)
 320:       sm.checkSetFactory ();
 321:     // Once the builder is installed it cannot be replaced.
 322:     if (icfb != null)
 323:       throw new IllegalStateException ("builder already installed");
 324:     if (builder != null)
 325:       icfb = builder;
 326:   }
 327: 
 328:   public static Context getContinuationContext (CannotProceedException cpe)
 329:     throws NamingException
 330:   {
 331:     Hashtable env = cpe.getEnvironment ();
 332:     if (env != null)
 333:       env.put (CPE, cpe);
 334: 
 335:     // It is really unclear to me if this is right.
 336:     try
 337:       {
 338:     Object obj = getObjectInstance (cpe.getResolvedObj(),
 339:                     cpe.getAltName (),
 340:                     cpe.getAltNameCtx (), 
 341:                     env);
 342:     if (obj != null)
 343:       return (Context) obj;
 344:       }
 345:     catch (Exception _)
 346:       {
 347:       }
 348: 
 349:     // fix stack trace for re-thrown exception (message confusing otherwise)
 350:     cpe.fillInStackTrace();
 351: 
 352:     throw cpe;
 353:   }
 354: 
 355:   public static Object getStateToBind (Object obj, Name name,
 356:                        Context nameCtx, Hashtable environment)
 357:     throws NamingException
 358:   {
 359:     StringTokenizer tokens = getPlusPath (Context.STATE_FACTORIES,
 360:                       environment, nameCtx);
 361:     while (tokens.hasMoreTokens ())
 362:       {
 363:     String klassName = tokens.nextToken ();
 364:     try
 365:       {
 366:         Class k = Class.forName (klassName,
 367:                      true,
 368:                      Thread.currentThread().getContextClassLoader());
 369:         StateFactory factory = (StateFactory) k.newInstance ();
 370:         Object o = factory.getStateToBind (obj, name, nameCtx,
 371:                            environment);
 372:         if (o != null)
 373:           return o;
 374:       }
 375:     catch (ClassNotFoundException _1)
 376:       {
 377:         // Ignore it.
 378:       }
 379:     catch (ClassCastException _2)
 380:       {
 381:         // This means that the class we found was not an
 382:         // ObjectFactory or that the factory returned something
 383:         // which was not a Context.
 384:       }
 385:     catch (InstantiationException _3)
 386:       {
 387:         // If we couldn't instantiate the factory we might get
 388:         // this.
 389:       }
 390:     catch (IllegalAccessException _4)
 391:       {
 392:         // Another possibility when instantiating.
 393:       }
 394:       }
 395: 
 396:     return obj;
 397:   }
 398: }