Source Code Cross Referenced for NamingManager.java in  » Apache-Harmony-Java-SE » javax-package » javax » naming » spi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » javax package » javax.naming.spi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* 
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package javax.naming.spi;
019:
020:        import java.net.URL;
021:        import java.net.URLClassLoader;
022:        import java.security.AccessController;
023:        import java.security.PrivilegedAction;
024:        import java.util.Enumeration;
025:        import java.util.Hashtable;
026:        import java.util.StringTokenizer;
027:
028:        import javax.naming.CannotProceedException;
029:        import javax.naming.Context;
030:        import org.apache.harmony.jndi.internal.EnvironmentReader;
031:        import org.apache.harmony.jndi.internal.UrlParser;
032:        import org.apache.harmony.jndi.internal.nls.Messages;
033:
034:        import javax.naming.Name;
035:        import javax.naming.NamingException;
036:        import javax.naming.NoInitialContextException;
037:        import javax.naming.RefAddr;
038:        import javax.naming.Reference;
039:        import javax.naming.Referenceable;
040:        import javax.naming.StringRefAddr;
041:
042:        /**
043:         * The <code>NamingManager</code> class should not be instantiated although it
044:         * can be extended by classes within the <code>javax.naming.spi</code> package -
045:         * see {@link DirectoryManager}. All its methods are static.
046:         * <p>
047:         * The methods are used by service providers for accessing object and state
048:         * factories and for determining continuation contexts. Many of the methods
049:         * create objects. These may be <code>Context</code> objects or objects
050:         * referred to by the naming service.
051:         * </p>
052:         * <p>
053:         * The <code>Name</code> and <code>Hashtable</code> arguments passed to the
054:         * <code>NamingManager</code> methods remain owned purely by the calling
055:         * method. They must not be changed or referenced.
056:         * </p>
057:         * <p>
058:         * It should be noted that it is possible for an application to access a
059:         * namespace other than that supplied by the default <code>InitialContext</code>
060:         * (as specified by <code>Context.INITIAL_CONTEXT_FACTORY</code>). It is
061:         * possible to call the following <code>InitialContext</code> methods passing
062:         * a URL string either as the <code>String</code> or <code>Name</code>
063:         * parameter: <code>lookup, bin, rebind, unbind, rename, list, listBindings, 
064:         * destroySubcontext, createSubcontext, lookupLink, getNameParser</code>.
065:         * This allows you to have one <code>InitialContext</code> object where these
066:         * methods usually use the default initial context but access a URL
067:         * <code>Context</code> instead when invoked with a URL string.
068:         * </p>
069:         * <p>
070:         * A URL string is of the format abc:\nnnnnn where abc is the scheme of the URL.
071:         * (See <code>InitialContext</code> where it refers to RFC1738.) When a URL
072:         * string is supplied to those <code>InitialContext</code> methods, a URL
073:         * context is used instead of the default initial context when performing that
074:         * method. URL context factories are used to create URL contexts. A URL context
075:         * factory is really just a service provider's implementation of an
076:         * <code>ObjectFactory</code>. It is not essential that a service provider
077:         * supplies one if they do not wish to support URL <code>Contexts.</code>
078:         * </p>
079:         * <p>
080:         * See the <code>getURLContext</code> method for a description of how a URL
081:         * context factory is located.
082:         * </p>
083:         * <p>
084:         * Please note that multithreaded access to this class must be safe. For
085:         * example, for thread safety, it should not be possible for one thread to read
086:         * the installed <code>InitialContextFactoryBuilder</code> or
087:         * <code>ObjectFactoryBuilder</code> while another thread is in the process of
088:         * setting it.
089:         * </p>
090:         * <p>
091:         * Also note that privileges should be granted to get the context classloader
092:         * and to read the resource files.
093:         * </p>
094:         * 
095:         * @see DirectoryManager
096:         */
097:        public class NamingManager {
098:
099:            /**
100:             * The property name of <code>CannotProceedException</code> in a context's
101:             * environment.
102:             */
103:            public static final String CPE = "java.naming.spi.CannotProceedException"; //$NON-NLS-1$
104:
105:            static InitialContextFactoryBuilder icfb;
106:
107:            static ObjectFactoryBuilder ofb;
108:
109:            NamingManager() {
110:                super ();
111:                // package private to prevent it being instanced but make it can be
112:                // subclassed by DirectoryManager
113:            }
114:
115:            /**
116:             * Install an <code>InitialContextFactoryBuilder</code>. Once this has
117:             * been set it cannot be reset. Attempts to do so cause an
118:             * <code>IllegalStateException</code>. The builder can only be installed
119:             * if the security policy allows the setting of the factory.
120:             * 
121:             * @param icfb
122:             *            the builder to be installed - can be null, but then no builder
123:             *            is installed.
124:             * @throws IllegalStateException
125:             *             if an builder has already been installed.
126:             * @throws SecurityException
127:             *             is a security error prevents the installation.
128:             * @throws NamingException
129:             *             for other errors encountered.
130:             */
131:            public static void setInitialContextFactoryBuilder(
132:                    InitialContextFactoryBuilder icfb)
133:                    throws IllegalStateException, SecurityException,
134:                    NamingException {
135:                // check security access
136:                SecurityManager sm = System.getSecurityManager();
137:                if (null != sm) {
138:                    sm.checkSetFactory();
139:                }
140:                synchronized (NamingManager.class) {
141:                    if (null != NamingManager.icfb) {
142:                        // jndi.1E=InitialContextFactoryBuilder cannot be reset
143:                        throw new IllegalStateException(Messages
144:                                .getString("jndi.1E")); //$NON-NLS-1$
145:                    }
146:                    NamingManager.icfb = icfb;
147:                }
148:            }
149:
150:            /**
151:             * Returns true when an <code>InitialContextFactoryBuilder</code> has been
152:             * installed.
153:             * 
154:             * @return true when an <code>InitialContextFactoryBuilder</code> has been
155:             *         installed.
156:             */
157:            public static boolean hasInitialContextFactoryBuilder() {
158:                return null != icfb;
159:            }
160:
161:            /**
162:             * Install an <code>ObjectFactoryBuilder</code>. Once this has been set
163:             * it cannot be reset. Attempts to do so cause an
164:             * <code>IllegalStateException</code>. The builder can only be installed
165:             * if the security policy allows the setting of the factory.
166:             * 
167:             * @param ofb
168:             *            the <code>ObjectFactoryBuilder</code> to be installed - can
169:             *            be null, but then no builder is installed.
170:             * @throws IllegalStateException
171:             *             if an <code>ObjectFactoryBuilder</code> has already been
172:             *             installed.
173:             * @throws SecurityException
174:             *             is a security error prevents the installation.
175:             * @throws NamingException
176:             *             for other errors encountered.
177:             */
178:            public static synchronized void setObjectFactoryBuilder(
179:                    ObjectFactoryBuilder ofb) throws IllegalStateException,
180:                    SecurityException, NamingException {
181:
182:                if (null != NamingManager.ofb) {
183:                    // jndi.1F=ObjectFactoryBuilder cannot be reset
184:                    throw new IllegalStateException(Messages
185:                            .getString("jndi.1F")); //$NON-NLS-1$
186:                }
187:
188:                // check security access
189:                SecurityManager sm = System.getSecurityManager();
190:                if (null != sm) {
191:                    sm.checkSetFactory();
192:                }
193:
194:                NamingManager.ofb = ofb;
195:            }
196:
197:            /**
198:             * Create an <code>InitialContext</code> from either a previously
199:             * installed <code>InitialContextFactoryBuilder</code> or from the
200:             * <code>Context.INITIAL_CONTEXT_FACTORY</code> property in the supplied
201:             * <code> Hashtable h</code> if no builder is installed. An installed
202:             * <code>InitialContextFactoryBuilder</code> can generate a factory which
203:             * can be used to create the <code>InitialContext</code>. The
204:             * <code>Context.INITIAL_CONTEXT_FACTORY</code> property contains the
205:             * class of a factory which can be used to create the
206:             * <code>InitialContext</code>.
207:             * 
208:             * @param h
209:             *            a hashtable containing properties and values - may be null
210:             * @return an <code>InitialContext</code>
211:             * @throws NoInitialContextException
212:             *             if the <code>InitialContext</code> cannot be created.
213:             * @throws NamingException
214:             */
215:            public static Context getInitialContext(Hashtable<?, ?> h)
216:                    throws NoInitialContextException, NamingException {
217:
218:                // if InitialContextFactoryBuilder is set
219:                if (null != icfb) {
220:                    // create InitialContext using builder
221:                    return icfb.createInitialContextFactory(h)
222:                            .getInitialContext(h);
223:                }
224:
225:                // create InitialContext using factory specified in hashtable
226:                try {
227:                    // get factory class name
228:                    String factoryClassName = (String) h
229:                            .get(Context.INITIAL_CONTEXT_FACTORY);
230:                    // new factory instance
231:                    Class<?> factoryClass = classForName(factoryClassName);
232:                    InitialContextFactory factory = (InitialContextFactory) factoryClass
233:                            .newInstance();
234:                    // create initial context instance using the factory
235:                    return factory.getInitialContext(h);
236:                } catch (NamingException e) {
237:                    // throw NamingException
238:                    throw e;
239:                } catch (Exception e) {
240:                    // failed, throw NoInitialContextException
241:                    // jndi.20=Failed to create InitialContext using factory specified
242:                    // in hashtable {0}
243:                    NamingException nex = new NoInitialContextException(
244:                            Messages.getString("jndi.20", h)); //$NON-NLS-1$
245:                    nex.setRootCause(e);
246:                    throw nex;
247:                }
248:            }
249:
250:            /**
251:             * Create an object from either a previously installed
252:             * <code>ObjectFactoryBuilder</code> or from a supplied reference or from
253:             * the <code>Context.OBJECT_FACTORIES</code> property in the supplied
254:             * <code>Hashtable h</code>.
255:             * <p>
256:             * An installed <code>ObjectFactoryBuilder</code> can generate a factory
257:             * which can be used to create the object instance to return to caller. Any
258:             * encountered exceptions are thrown.
259:             * </p>
260:             * <p>
261:             * If an <code>ObjectFactoryBuilder</code> has not been installed then the
262:             * supplied <code>Object o</code> may provide a <code>Reference</code>
263:             * or <code>Referenceable</code> object. If so, then that
264:             * <code>Object o</code> may have an associated class in a factory which
265:             * could be loaded and used to create the object instance. If the factory
266:             * class cannot be loaded then the <code>URLClassLoader</code> may be able
267:             * to load a class from the list of URLs specified in the reference's
268:             * factory class location. Any exceptions encountered are passed up.
269:             * </p>
270:             * <p>
271:             * If a reference is supplied but no factory class can be loaded from it
272:             * then this method returns the supplied object <code>o</code>.
273:             * </p>
274:             * <p>
275:             * If a factory class loads successfully and can then be used to create an
276:             * object instance then that instance is returned to the caller.
277:             * </p>
278:             * <p>
279:             * If no factory name was associated with the <code>Reference</code>
280:             * object <code>o</code> then see whether the <code>Reference</code> or
281:             * <code>Referenceable</code> object has any <code>StringRefAddrs</code>
282:             * of address type URL or url in its address list. For each entry in the
283:             * list, in the order they appear in the list, it may be possible to use the
284:             * URL factory to create the object. A URL in a <code>StringRefAddr</code>
285:             * should have a scheme which can be used to locate the associated URL
286:             * context factory in the same way as in the <code>getURLContext</code>
287:             * method. (The scheme is the part which comes before :\. For example the
288:             * URL http://www.apache.org has the scheme http.) A URL with no scheme
289:             * would be ignored for these purposes.
290:             * </p>
291:             * <p>
292:             * If no <code>ObjectFactoryBuilder</code> was installed, no factory class
293:             * name is supplied with a <code>Reference</code> and no URL contexts
294:             * succeeded in creating an <code>Object</code> then try the factories in
295:             * <code>Context.OBJECT_FACTORIES</code> for this environment. Also try
296:             * the provider resource file belonging to the context <code>c</code>.
297:             * (See <code>Context</code> description for details of Provider resource
298:             * files.) If any factory throws an exception then pass that back to the
299:             * caller - no further factories are tried.
300:             * </p>
301:             * <p>
302:             * If all factories fail to load or create the <code>Object</code> then
303:             * return the argument object <code>o</code> as the returned object.
304:             * </p>
305:             * 
306:             * @param o
307:             *            an object which may provide reference or location information.
308:             *            May be null.
309:             * @param n
310:             *            The name of the <code>Object</code> relative to the default
311:             *            initial context(or relative to the Context c if it is
312:             *            supplied)
313:             * @param c
314:             *            the <code>Context</code> to which the <code>Name</code> is
315:             *            relative
316:             * @param h
317:             *            a <code>Hashtable</code> containing environment properties
318:             *            and values - may be null
319:             * @return a new <code>Object</code> or the supplied <code>Object o</code>
320:             *         if one cannot be created.
321:             * @throws NamingException
322:             *             if one is encountered
323:             * @throws Exception
324:             *             if any other exception is encountered
325:             */
326:            public static Object getObjectInstance(Object o, Name n, Context c,
327:                    Hashtable<?, ?> h) throws NamingException, Exception {
328:
329:                // 1. try ObjectFactoryBuilder, if it is set
330:                if (null != ofb) {
331:                    // use the builder to create an object factory
332:                    ObjectFactory factory = ofb.createObjectFactory(o, h);
333:                    // get object instance using the factory and return
334:                    return factory.getObjectInstance(o, n, c, h);
335:                }
336:
337:                // 2. see whether o is a Referenceable or a Reference
338:                Reference ref = null;
339:                if (o instanceof  Referenceable) {
340:                    ref = ((Referenceable) o).getReference();
341:                }
342:                if (o instanceof  Reference) {
343:                    ref = (Reference) o;
344:                }
345:                // if o is a Referenceable or a Reference
346:                if (null != ref) {
347:                    // if a factory class name is supplied by the reference, use it to
348:                    // create
349:                    if (null != ref.getFactoryClassName()) {
350:                        return getObjectInstanceByFactoryInReference(ref, o, n,
351:                                c, h);
352:                    }
353:                    // see if ref has any StringRefAddrs of address type URL,
354:                    Object result = getObjectInstanceByUrlRefAddr(n, c, h, ref);
355:                    // if success, return it
356:                    if (null != result) {
357:                        return result;
358:                    }
359:                }
360:
361:                // 3. try Context.OBJECT_FACTORIES
362:                Object result = getObjectInstanceByObjectFactory(o, n, c, h);
363:                if (null != result) {
364:                    return result;
365:                }
366:
367:                // all failed, just return o
368:                return o;
369:            }
370:
371:            private static Object getObjectInstanceByObjectFactory(Object o,
372:                    Name n, Context c, Hashtable<?, ?> h)
373:                    throws NamingException, Exception {
374:                // obtain object factories from hashtable and service provider resource
375:                // file
376:                String fnames[] = EnvironmentReader
377:                        .getFactoryNamesFromEnvironmentAndProviderResource(h,
378:                                c, Context.OBJECT_FACTORIES);
379:                for (String element : fnames) {
380:                    // new factory instance by its class name
381:                    ObjectFactory factory = null;
382:                    try {
383:                        factory = (ObjectFactory) classForName(element)
384:                                .newInstance();
385:                    } catch (Exception e) {
386:                        continue;
387:                    }
388:                    // create object using factory
389:                    Object obj = factory.getObjectInstance(o, n, c, h);
390:                    if (null != obj) {
391:                        return obj;
392:                    }
393:                }
394:                // no object factory succeeded, return null
395:                return null;
396:            }
397:
398:            private static Object getObjectInstanceByUrlRefAddr(Name n,
399:                    Context c, Hashtable<?, ?> h, Reference ref)
400:                    throws NamingException {
401:                // obtain pkg prefixes from hashtable and service provider resource file
402:                String pkgPrefixes[] = EnvironmentReader
403:                        .getFactoryNamesFromEnvironmentAndProviderResource(h,
404:                                c, Context.URL_PKG_PREFIXES);
405:                // for each RefAddr
406:                Enumeration<RefAddr> enumeration = ref.getAll();
407:                while (enumeration.hasMoreElements()) {
408:                    RefAddr addr = enumeration.nextElement();
409:                    // if it is StringRefAddr and type is URL
410:                    if (addr instanceof  StringRefAddr
411:                            && addr.getType().equalsIgnoreCase("URL")) { //$NON-NLS-1$
412:                        // get the url address
413:                        String url = (String) ((StringRefAddr) addr)
414:                                .getContent();
415:                        // try create using url context factory
416:                        Object obj = getObjectInstanceByUrlContextFactory(url,
417:                                n, c, h, pkgPrefixes, UrlParser.getScheme(url));
418:                        // if success, return the created obj
419:                        if (null != obj) {
420:                            return obj;
421:                        }
422:                    }
423:                }
424:                // failed to create using any StringRefAddr of address type URL, return
425:                // null
426:                return null;
427:            }
428:
429:            private static Object getObjectInstanceByUrlContextFactory(
430:                    String url, Name n, Context c, Hashtable<?, ?> h,
431:                    String pkgPrefixes[], String schema) throws NamingException {
432:                // if schema is empty or null, fail, return null
433:                if (null == schema || 0 == schema.length()) {
434:                    return null;
435:                }
436:
437:                for (String element : pkgPrefixes) {
438:                    ObjectFactory factory = null;
439:                    try {
440:                        // create url context factory instance
441:                        String clsName = element + "." //$NON-NLS-1$
442:                                + schema + "." //$NON-NLS-1$
443:                                + schema + "URLContextFactory"; //$NON-NLS-1$
444:                        factory = (ObjectFactory) classForName(clsName)
445:                                .newInstance();
446:                    } catch (Exception e) {
447:                        // failed to create factory, continue trying
448:                        continue;
449:                    }
450:                    try {
451:                        // create obj using url context factory
452:                        Object obj = factory.getObjectInstance(url, n, c, h);
453:                        // if create success, return it
454:                        if (null != obj) {
455:                            return obj;
456:                        }
457:                    } catch (Exception e) {
458:                        // throw NamingException, if factory fails
459:                        if (e instanceof  NamingException) {
460:                            throw (NamingException) e;
461:                        }
462:                        // jndi.21=Failed to create object instance
463:                        NamingException nex = new NamingException(Messages
464:                                .getString("jndi.21")); //$NON-NLS-1$
465:                        nex.setRootCause(e);
466:                        throw nex;
467:                    }
468:                }
469:                // fail to create using url context factory, return null
470:                return null;
471:            }
472:
473:            private static Object getObjectInstanceByFactoryInReference(
474:                    Reference ref, Object o, Name n, Context c,
475:                    Hashtable<?, ?> h) throws Exception {
476:                ObjectFactory factory = null;
477:
478:                // try load the factory by its class name
479:                try {
480:                    factory = (ObjectFactory) classForName(
481:                            ref.getFactoryClassName()).newInstance();
482:                } catch (ClassNotFoundException e) {
483:                    // Ignore.
484:                }
485:
486:                // try load the factory from its class location
487:                if (null == factory && null != ref.getFactoryClassLocation()) {
488:                    factory = (ObjectFactory) loadFactoryFromLocation(ref
489:                            .getFactoryClassName(), ref
490:                            .getFactoryClassLocation());
491:                }
492:                // if factory cannot be loaded
493:                if (null == factory) {
494:                    // return o
495:                    return o;
496:                }
497:
498:                // get object instance using the factory and return it
499:                return factory.getObjectInstance(ref, n, c, h);
500:            }
501:
502:            /*
503:             * If cannot load class, return null. Throws any exceptions except
504:             * ClassNotFoundException
505:             */
506:            private static Object loadFactoryFromLocation(String clsName,
507:                    String location) throws Exception {
508:
509:                // convert location into an array of URL, separated by ' '
510:                StringTokenizer st = new StringTokenizer(location, " "); //$NON-NLS-1$
511:                URL urls[] = new URL[st.countTokens()];
512:                for (int i = 0; i < urls.length; i++) {
513:                    urls[i] = new URL(st.nextToken());
514:                }
515:
516:                // new a URLClassLoader from the URLs
517:                URLClassLoader l = new URLClassLoader(urls);
518:
519:                // try load factory by URLClassLoader
520:                try {
521:                    // return the new instance
522:                    return l.loadClass(clsName).newInstance();
523:                } catch (ClassNotFoundException e) {
524:                    // return null if class loading failed
525:                    return null;
526:                }
527:            }
528:
529:            /**
530:             * Get the state of an Object.
531:             * <p>
532:             * The <code>Context.STATE_FACTORIES</code> property from the
533:             * <code>Hashtable h</code> together with the
534:             * <code>Context.STATE_FACTORIES</code> property from the provider
535:             * resource file of the <code>Context c</code> provides the list of
536:             * factories tried to get an object's state.
537:             * </p>
538:             * <p>
539:             * Each factory in the list is attempted to be loaded using the context
540:             * class loader. Once a class is loaded then it can be used to create a new
541:             * instance of it to obtain the factory which can then use its
542:             * <code>getStateToBind</code> to find the return object. Once an object
543:             * is found then it is not necessary to examine further factories and the
544:             * object is returned it as the return parameter.
545:             * </p>
546:             * <p>
547:             * If no factory is loaded or all loaded factories fail to return an object
548:             * then return the supplied <code>Object o</code> as the return param.
549:             * </p>
550:             * <p>
551:             * Note for service provider implementors: Classes which implement the
552:             * <code>StateFactory</code> interface must be public with a public
553:             * constructor that has no parameters.
554:             * </p>
555:             * 
556:             * @param o
557:             *            an object which may provide reference or location information.
558:             *            May be null.
559:             * @param n
560:             *            the name of the <code>Object</code> relative to the default
561:             *            initial context (or relative to the Context c if it is
562:             *            supplied)
563:             * @param c
564:             *            the <code>Context</code> to which the <code>Name</code> is
565:             *            relative
566:             * @param h
567:             *            a <code>Hashtable</code> containing environment properties
568:             *            and values - may be null
569:             * @return the state of the specified object
570:             * @throws NamingException
571:             *             if one is encountered
572:             */
573:            public static Object getStateToBind(Object o, Name n, Context c,
574:                    Hashtable<?, ?> h) throws NamingException {
575:
576:                // obtain state factories from hashtable and service provider resource
577:                // file
578:                String fnames[] = EnvironmentReader
579:                        .getFactoryNamesFromEnvironmentAndProviderResource(h,
580:                                c, Context.STATE_FACTORIES);
581:
582:                for (String element : fnames) {
583:                    // new factory instance by its class name
584:                    StateFactory factory = null;
585:                    try {
586:                        factory = (StateFactory) classForName(element)
587:                                .newInstance();
588:                    } catch (Exception e) {
589:                        continue;
590:                    }
591:                    // try obtain state using the factory
592:                    Object state = factory.getStateToBind(o, n, c, h);
593:                    // if a state obtained successfully, return it
594:                    if (null != state) {
595:                        return state;
596:                    }
597:                }
598:
599:                // all factories failed, return the input argument o
600:                return o;
601:            }
602:
603:            /**
604:             * Creates a URL <code>Context</code> which can subsequently be used to
605:             * resolve any URLs with the URL scheme s. A <code>URLContextFactory</code>
606:             * is a type of <code>ObjectFactory</code> used to create a
607:             * <code>URLContext</code> when <code>getObjectInstance</code> is
608:             * invoked with the <code>Object o</code> set to null (see the description
609:             * of <code>ObjectFactory</code>).
610:             * <p>
611:             * This <code>getURLContext</code> method tries to locate the
612:             * <code>URLContextFactory</code> based on the
613:             * <code>Context.URL_PKG_PREFIXES</code> property which contains the
614:             * prefixes to be tried as the start of the package name. (See
615:             * <code>Context</code>).
616:             * </p>
617:             * <p>
618:             * Each package prefix entry (and finally the default value) are tried to
619:             * find the class which can be used to create the Context.
620:             * </p>
621:             * <p>
622:             * A full class name is derived as
623:             * <code>packageprefix.s.sURLContextFactory</code> where <code>s</code>
624:             * is the scheme.
625:             * </p>
626:             * <p>
627:             * For example if a scheme is abc and the package prefix to try is com.ibm
628:             * then the factory class to try is
629:             * <code>com.ibm.abc.abcURLContextFactory</code>. Once a factory is
630:             * created then a <code>Context</code> is created using the special use of
631:             * <code>ObjectFactory.getObjectInstance</code>.
632:             * </p>
633:             * <p>
634:             * Once a first factory is created, it is used to create the context, and NO
635:             * further attempts will be made on other pkg prefixes.
636:             * </p>
637:             * 
638:             * @param schema
639:             *            the URL scheme to which the Context will relate
640:             * @param envmt
641:             *            a <code>Hashtable</code> containing environment properties
642:             *            and values - may be null
643:             * @return the URL <code>Context</code> or null if no
644:             *         <code>URLContextFactory</code> instance can be created and
645:             *         therefore a Context cannot be created.
646:             * @throws NamingException
647:             *             if one is encountered.
648:             */
649:            public static Context getURLContext(String schema,
650:                    Hashtable<?, ?> envmt) throws NamingException {
651:
652:                if (null == schema || 0 == schema.length() || null == envmt) {
653:                    return null;
654:                }
655:
656:                // obtain pkg prefixes from hashtable
657:                String pkgPrefixes[] = EnvironmentReader
658:                        .getFactoryNamesFromEnvironmentAndProviderResource(
659:                                envmt, null, Context.URL_PKG_PREFIXES);
660:
661:                for (String element : pkgPrefixes) {
662:                    // create factory instance
663:                    ObjectFactory factory;
664:                    try {
665:                        String clsName = element + "." //$NON-NLS-1$
666:                                + schema + "." //$NON-NLS-1$
667:                                + schema + "URLContextFactory"; //$NON-NLS-1$
668:                        factory = (ObjectFactory) classForName(clsName)
669:                                .newInstance();
670:                    } catch (Exception ex) {
671:                        // fail to create factory, continue to try another
672:                        continue;
673:                    }
674:                    try {
675:                        // create url context using the factory, and return it
676:                        return (Context) factory.getObjectInstance(null, null,
677:                                null, envmt);
678:                    } catch (NamingException e) {
679:                        // find NamingException, throw it
680:                        throw e;
681:                    } catch (Exception e) {
682:                        // other exception, throw as NamingException
683:                        // jndi.22=other exception happens: {0}
684:                        NamingException nex = new NamingException(Messages
685:                                .getString("jndi.22", e.toString())); //$NON-NLS-1$
686:                        nex.setRootCause(e);
687:                        throw nex;
688:                    }
689:                }
690:
691:                // cannot create context instance from any pkg prefixes, return null
692:                return null;
693:            }
694:
695:            /**
696:             * Create the next context when using federation. All the information
697:             * required to do this is contained in the
698:             * <code>CannotProceedException</code> <code>e</code>. If the resolved
699:             * object is null then throw the supplied
700:             * <code>CannotProceedException</code> <code>e</code> using the stack
701:             * details from this thread. The resolved object in <code>e</code> may
702:             * already be a <code>Context</code>. This is the case where the service
703:             * provider gives an explicit pointer to the next naming system. A Context
704:             * object is returned as the continuation context, but need not be the same
705:             * object instance as the resolved object.
706:             * <p>
707:             * If the resolved object is not already a <code>Context</code> then it is
708:             * necessary to use the resolved object together with the
709:             * <code>altName</code> name, the <code>altNameCtx</code> context and
710:             * the environment hashtable to get an instance of the object. This should
711:             * then be a context which is returned as the continuation context. If an
712:             * instance cannot be obtained then throw the supplied
713:             * <code>CannotProceedException</code> using the stack details from this
714:             * thread.
715:             * </p>
716:             * <p>
717:             * This method is responsible for setting the property denoted by the
718:             * <code>CPE</code> string to be the supplied
719:             * <code>CannotProceedException</code> for the exception <code>e</code>
720:             * environment. The continuation context should then inherit this property.
721:             * </p>
722:             * 
723:             * @param cpe
724:             *            the <code>CannotProceedException</code> generated by the
725:             *            context of the previous naming system when it can proceed no
726:             *            further.
727:             * @return the next Context when using federation
728:             * @throws NamingException
729:             *             if the resolved object is null or if a context cannot be
730:             *             obtained from it either directly or indirectly.
731:             */
732:            @SuppressWarnings("unchecked")
733:            public static Context getContinuationContext(
734:                    CannotProceedException cpe) throws NamingException {
735:
736:                Context ctx = null;
737:
738:                // set CPE property of the env
739:                if (cpe.getEnvironment() == null) {
740:                    cpe
741:                            .setEnvironment(new Hashtable<String, CannotProceedException>());
742:                }
743:                ((Hashtable<String, CannotProceedException>) cpe
744:                        .getEnvironment()).put(CPE, cpe);
745:
746:                // if resolved object is null
747:                if (null == cpe.getResolvedObj()) {
748:                    // re-throw cpe
749:                    cpe.fillInStackTrace();
750:                    throw cpe;
751:                }
752:
753:                // if cpe's resolved obj is Context
754:                if (cpe.getResolvedObj() instanceof  Context) {
755:                    // accept it as the continuation context
756:                    ctx = (Context) cpe.getResolvedObj();
757:                } else {
758:                    // otherwise, call getObjectInstance() to get a context instance
759:                    try {
760:                        ctx = (Context) getObjectInstance(cpe.getResolvedObj(),
761:                                cpe.getAltName(), cpe.getAltNameCtx(), cpe
762:                                        .getEnvironment());
763:                    } catch (Exception ex) {
764:                        // throw back CPE in case of any exception
765:                        throw cpe;
766:                    }
767:                    // if ctx cannot be obtained
768:                    if (null == ctx) {
769:                        // re-throw CPE
770:                        cpe.fillInStackTrace();
771:                        throw cpe;
772:                    }
773:                }
774:
775:                // return the continuation context
776:                return ctx;
777:            }
778:
779:            private static Class<?> classForName(final String className)
780:                    throws ClassNotFoundException {
781:
782:                Class<?> cls = AccessController
783:                        .doPrivileged(new PrivilegedAction<Class<?>>() {
784:                            public Class<?> run() {
785:                                // try thread context class loader first
786:                                try {
787:                                    return Class.forName(className, true,
788:                                            Thread.currentThread()
789:                                                    .getContextClassLoader());
790:                                } catch (ClassNotFoundException e) {
791:                                    // Ignored.
792:                                }
793:                                // try system class loader second
794:                                try {
795:                                    return Class.forName(className, true,
796:                                            ClassLoader.getSystemClassLoader());
797:                                } catch (ClassNotFoundException e1) {
798:                                    // Ignored.
799:                                }
800:                                // return null, if fail to load class
801:                                return null;
802:                            }
803:                        });
804:
805:                if (cls == null) {
806:                    // jndi.1C=class {0} not found
807:                    throw new ClassNotFoundException(Messages.getString(
808:                            "jndi.1C", className)); //$NON-NLS-1$
809:                }
810:
811:                return cls;
812:            }
813:
814:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.