Source Code Cross Referenced for ContextFinder.java in  » 6.0-JDK-Modules » jaxb-api » javax » xml » bind » 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 » 6.0 JDK Modules » jaxb api » javax.xml.bind 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
003:         * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
004:         */
005:
006:        package javax.xml.bind;
007:
008:        import java.io.BufferedReader;
009:        import java.io.IOException;
010:        import java.io.InputStream;
011:        import java.io.InputStreamReader;
012:        import java.io.UnsupportedEncodingException;
013:        import java.lang.reflect.InvocationTargetException;
014:        import java.lang.reflect.Method;
015:        import java.net.URL;
016:        import java.util.Map;
017:        import java.util.Properties;
018:        import java.util.StringTokenizer;
019:        import java.util.logging.ConsoleHandler;
020:        import java.util.logging.Level;
021:        import java.util.logging.Logger;
022:        import java.security.AccessController;
023:        import java.security.PrivilegedAction;
024:
025:        import static javax.xml.bind.JAXBContext.JAXB_CONTEXT_FACTORY;
026:
027:        //import java.lang.reflect.InvocationTargetException;
028:
029:        /**
030:         * This class is package private and therefore is not exposed as part of the 
031:         * JAXB API.
032:         *
033:         * This code is designed to implement the JAXB 1.0 spec pluggability feature
034:         *
035:         * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul>
036:         * @version $Revision: 1.25 $
037:         * @see JAXBContext
038:         */
039:        class ContextFinder {
040:            private static final Logger logger;
041:            static {
042:                logger = Logger.getLogger("javax.xml.bind");
043:                try {
044:                    if (AccessController.doPrivileged(new GetPropertyAction(
045:                            "jaxb.debug")) != null) {
046:                        // disconnect the logger from a bigger framework (if any)
047:                        // and take the matters into our own hands
048:                        logger.setUseParentHandlers(false);
049:                        logger.setLevel(Level.ALL);
050:                        ConsoleHandler handler = new ConsoleHandler();
051:                        handler.setLevel(Level.ALL);
052:                        logger.addHandler(handler);
053:                    } else {
054:                        // don't change the setting of this logger
055:                        // to honor what other frameworks
056:                        // have done on configurations.
057:                    }
058:                } catch (Throwable t) {
059:                    // just to be extra safe. in particular System.getProperty may throw
060:                    // SecurityException.
061:                }
062:            }
063:
064:            /**
065:             * If the {@link InvocationTargetException} wraps an exception that shouldn't be wrapped,
066:             * throw the wrapped exception.
067:             */
068:            private static void handleInvocationTargetException(
069:                    InvocationTargetException x) throws JAXBException {
070:                Throwable t = x.getTargetException();
071:                if (t != null) {
072:                    if (t instanceof  JAXBException)
073:                        // one of our exceptions, just re-throw
074:                        throw (JAXBException) t;
075:                    if (t instanceof  RuntimeException)
076:                        // avoid wrapping exceptions unnecessarily
077:                        throw (RuntimeException) t;
078:                    if (t instanceof  Error)
079:                        throw (Error) t;
080:                }
081:            }
082:
083:            /**
084:             * Determine if two types (JAXBContext in this case) will generate a ClassCastException.
085:             *
086:             * For example, (targetType)originalType
087:             *
088:             * @param originalType
089:             *          The Class object of the type being cast
090:             * @param targetType
091:             *          The Class object of the type that is being cast to
092:             * @return JAXBException to be thrown.
093:             */
094:            private static JAXBException handleClassCastException(
095:                    Class originalType, Class targetType) {
096:                final URL targetTypeURL = which(targetType);
097:
098:                return new JAXBException(Messages.format(
099:                        Messages.ILLEGAL_CAST,
100:                        // we don't care where the impl class is, we want to know where JAXBContext lives in the impl
101:                        // class' ClassLoader
102:                        originalType.getClassLoader().getResource(
103:                                "javax/xml/bind/JAXBContext.class"),
104:                        targetTypeURL));
105:            }
106:
107:            /**
108:             * Create an instance of a class using the specified ClassLoader
109:             */
110:            static JAXBContext newInstance(String contextPath,
111:                    String className, ClassLoader classLoader, Map properties)
112:                    throws JAXBException {
113:                try {
114:                    Class spiClass;
115:                    if (classLoader == null) {
116:                        spiClass = Class.forName(className);
117:                    } else {
118:                        spiClass = classLoader.loadClass(className);
119:                    }
120:
121:                    /*
122:                     * javax.xml.bind.context.factory points to a class which has a
123:                     * static method called 'createContext' that
124:                     * returns a javax.xml.JAXBContext.
125:                     */
126:
127:                    Object context = null;
128:
129:                    // first check the method that takes Map as the third parameter.
130:                    // this is added in 2.0.
131:                    try {
132:                        Method m = spiClass.getMethod("createContext",
133:                                String.class, ClassLoader.class, Map.class);
134:                        // any failure in invoking this method would be considered fatal
135:                        context = m.invoke(null, contextPath, classLoader,
136:                                properties);
137:                    } catch (NoSuchMethodException e) {
138:                        // it's not an error for the provider not to have this method.
139:                    }
140:
141:                    if (context == null) {
142:                        // try the old method that doesn't take properties. compatible with 1.0.
143:                        // it is an error for an implementation not to have both forms of the createContext method.
144:                        Method m = spiClass.getMethod("createContext",
145:                                String.class, ClassLoader.class);
146:                        // any failure in invoking this method would be considered fatal
147:                        context = m.invoke(null, contextPath, classLoader);
148:                    }
149:
150:                    if (!(context instanceof  JAXBContext)) {
151:                        // the cast would fail, so generate an exception with a nice message
152:                        handleClassCastException(context.getClass(),
153:                                JAXBContext.class);
154:                    }
155:                    return (JAXBContext) context;
156:                } catch (ClassNotFoundException x) {
157:                    throw new JAXBException(Messages.format(
158:                            Messages.PROVIDER_NOT_FOUND, className), x);
159:                } catch (InvocationTargetException x) {
160:                    handleInvocationTargetException(x);
161:                    // for other exceptions, wrap the internal target exception
162:                    // with a JAXBException
163:                    Throwable e = x;
164:                    if (x.getTargetException() != null)
165:                        e = x.getTargetException();
166:
167:                    throw new JAXBException(Messages.format(
168:                            Messages.COULD_NOT_INSTANTIATE, className, e), e);
169:                } catch (RuntimeException x) {
170:                    // avoid wrapping RuntimeException to JAXBException,
171:                    // because it indicates a bug in this code.
172:                    throw x;
173:                } catch (Exception x) {
174:                    // can't catch JAXBException because the method is hidden behind
175:                    // reflection.  Root element collisions detected in the call to
176:                    // createContext() are reported as JAXBExceptions - just re-throw it
177:                    // some other type of exception - just wrap it
178:                    throw new JAXBException(Messages.format(
179:                            Messages.COULD_NOT_INSTANTIATE, className, x), x);
180:                }
181:            }
182:
183:            /**
184:             * Create an instance of a class using the specified ClassLoader
185:             */
186:            static JAXBContext newInstance(Class[] classes, Map properties,
187:                    String className) throws JAXBException {
188:                ClassLoader cl = Thread.currentThread().getContextClassLoader();
189:                Class spi;
190:                try {
191:                    logger.fine("Trying to load " + className);
192:                    if (cl != null)
193:                        spi = cl.loadClass(className);
194:                    else
195:                        spi = Class.forName(className);
196:                } catch (ClassNotFoundException e) {
197:                    throw new JAXBException(e);
198:                }
199:
200:                if (logger.isLoggable(Level.FINE)) {
201:                    // extra check to avoid costly which operation if not logged
202:                    logger.fine("loaded " + className + " from " + which(spi));
203:                }
204:
205:                Method m;
206:                try {
207:                    m = spi
208:                            .getMethod("createContext", Class[].class,
209:                                    Map.class);
210:                } catch (NoSuchMethodException e) {
211:                    throw new JAXBException(e);
212:                }
213:                try {
214:                    Object context = m.invoke(null, classes, properties);
215:                    if (!(context instanceof  JAXBContext)) {
216:                        // the cast would fail, so generate an exception with a nice message
217:                        throw handleClassCastException(context.getClass(),
218:                                JAXBContext.class);
219:                    }
220:                    return (JAXBContext) context;
221:                } catch (IllegalAccessException e) {
222:                    throw new JAXBException(e);
223:                } catch (InvocationTargetException e) {
224:                    handleInvocationTargetException(e);
225:
226:                    Throwable x = e;
227:                    if (e.getTargetException() != null)
228:                        x = e.getTargetException();
229:
230:                    throw new JAXBException(x);
231:                }
232:            }
233:
234:            static JAXBContext find(String factoryId, String contextPath,
235:                    ClassLoader classLoader, Map properties)
236:                    throws JAXBException {
237:
238:                // TODO: do we want/need another layer of searching in $java.home/lib/jaxb.properties like JAXP?
239:
240:                final String jaxbContextFQCN = JAXBContext.class.getName();
241:
242:                // search context path for jaxb.properties first
243:                StringBuilder propFileName;
244:                StringTokenizer packages = new StringTokenizer(contextPath, ":");
245:                String factoryClassName;
246:
247:                if (!packages.hasMoreTokens())
248:                    // no context is specified
249:                    throw new JAXBException(Messages
250:                            .format(Messages.NO_PACKAGE_IN_CONTEXTPATH));
251:
252:                logger.fine("Searching jaxb.properties");
253:
254:                while (packages.hasMoreTokens()) {
255:                    String packageName = packages.nextToken(":").replace('.',
256:                            '/');
257:                    // com.acme.foo - > com/acme/foo/jaxb.properties
258:                    propFileName = new StringBuilder().append(packageName)
259:                            .append("/jaxb.properties");
260:
261:                    Properties props = loadJAXBProperties(classLoader,
262:                            propFileName.toString());
263:                    if (props != null) {
264:                        if (props.containsKey(factoryId)) {
265:                            factoryClassName = props.getProperty(factoryId);
266:                            return newInstance(contextPath, factoryClassName,
267:                                    classLoader, properties);
268:                        } else {
269:                            throw new JAXBException(Messages.format(
270:                                    Messages.MISSING_PROPERTY, packageName,
271:                                    factoryId));
272:                        }
273:                    }
274:                }
275:
276:                logger.fine("Searching the system property");
277:
278:                // search for a system property second (javax.xml.bind.JAXBContext)
279:                factoryClassName = AccessController
280:                        .doPrivileged(new GetPropertyAction(jaxbContextFQCN));
281:                if (factoryClassName != null) {
282:                    return newInstance(contextPath, factoryClassName,
283:                            classLoader, properties);
284:                }
285:
286:                logger.fine("Searching META-INF/services");
287:
288:                // search META-INF services next
289:                BufferedReader r;
290:                try {
291:                    final StringBuilder resource = new StringBuilder().append(
292:                            "META-INF/services/").append(jaxbContextFQCN);
293:                    final InputStream resourceStream = classLoader
294:                            .getResourceAsStream(resource.toString());
295:
296:                    if (resourceStream != null) {
297:                        r = new BufferedReader(new InputStreamReader(
298:                                resourceStream, "UTF-8"));
299:                        factoryClassName = r.readLine().trim();
300:                        r.close();
301:                        return newInstance(contextPath, factoryClassName,
302:                                classLoader, properties);
303:                    } else {
304:                        logger.fine("Unable to load:" + resource.toString());
305:                    }
306:                } catch (UnsupportedEncodingException e) {
307:                    // should never happen
308:                    throw new JAXBException(e);
309:                } catch (IOException e) {
310:                    throw new JAXBException(e);
311:                }
312:
313:                // else no provider found
314:                logger.fine("Trying to create the platform default provider");
315:                return newInstance(contextPath, PLATFORM_DEFAULT_FACTORY_CLASS,
316:                        classLoader, properties);
317:            }
318:
319:            // TODO: log each step in the look up process
320:            static JAXBContext find(Class[] classes, Map properties)
321:                    throws JAXBException {
322:
323:                // TODO: do we want/need another layer of searching in $java.home/lib/jaxb.properties like JAXP?
324:
325:                final String jaxbContextFQCN = JAXBContext.class.getName();
326:                String factoryClassName;
327:
328:                // search for jaxb.properties in the class loader of each class first
329:                for (final Class c : classes) {
330:                    // this classloader is used only to load jaxb.properties, so doing this should be safe.
331:                    ClassLoader classLoader = AccessController
332:                            .doPrivileged(new PrivilegedAction<ClassLoader>() {
333:                                public ClassLoader run() {
334:                                    return c.getClassLoader();
335:                                }
336:                            });
337:                    Package pkg = c.getPackage();
338:                    if (pkg == null)
339:                        continue; // this is possible for primitives, arrays, and classes that are loaded by poorly implemented ClassLoaders
340:                    String packageName = pkg.getName().replace('.', '/');
341:
342:                    // TODO: do we want to optimize away searching the same package?  org.Foo, org.Bar, com.Baz
343:                    //       classes from the same package might come from different class loades, so it might be a bad idea
344:
345:                    // TODO: it's easier to look things up from the class
346:                    // c.getResourceAsStream("jaxb.properties");
347:
348:                    // build the resource name and use the property loader code
349:                    String resourceName = packageName + "/jaxb.properties";
350:                    logger.fine("Trying to locate " + resourceName);
351:                    Properties props = loadJAXBProperties(classLoader,
352:                            resourceName);
353:                    if (props == null) {
354:                        logger.fine("  not found");
355:                    } else {
356:                        logger.fine("  found");
357:                        if (props.containsKey(JAXB_CONTEXT_FACTORY)) {
358:                            // trim() seems redundant, but adding to satisfy customer complaint
359:                            factoryClassName = props.getProperty(
360:                                    JAXB_CONTEXT_FACTORY).trim();
361:                            return newInstance(classes, properties,
362:                                    factoryClassName);
363:                        } else {
364:                            throw new JAXBException(Messages.format(
365:                                    Messages.MISSING_PROPERTY, packageName,
366:                                    JAXB_CONTEXT_FACTORY));
367:                        }
368:                    }
369:                }
370:
371:                // search for a system property second (javax.xml.bind.JAXBContext)
372:                logger.fine("Checking system property " + jaxbContextFQCN);
373:                factoryClassName = AccessController
374:                        .doPrivileged(new GetPropertyAction(jaxbContextFQCN));
375:                if (factoryClassName != null) {
376:                    logger.fine("  found " + factoryClassName);
377:                    return newInstance(classes, properties, factoryClassName);
378:                }
379:                logger.fine("  not found");
380:
381:                // search META-INF services next
382:                logger.fine("Checking META-INF/services");
383:                BufferedReader r;
384:                try {
385:                    final String resource = new StringBuilder(
386:                            "META-INF/services/").append(jaxbContextFQCN)
387:                            .toString();
388:                    ClassLoader classLoader = Thread.currentThread()
389:                            .getContextClassLoader();
390:                    URL resourceURL;
391:                    if (classLoader == null)
392:                        resourceURL = ClassLoader.getSystemResource(resource);
393:                    else
394:                        resourceURL = classLoader.getResource(resource);
395:
396:                    if (resourceURL != null) {
397:                        logger.fine("Reading " + resourceURL);
398:                        r = new BufferedReader(new InputStreamReader(
399:                                resourceURL.openStream(), "UTF-8"));
400:                        factoryClassName = r.readLine().trim();
401:                        return newInstance(classes, properties,
402:                                factoryClassName);
403:                    } else {
404:                        logger.fine("Unable to find: " + resource);
405:                    }
406:                } catch (UnsupportedEncodingException e) {
407:                    // should never happen
408:                    throw new JAXBException(e);
409:                } catch (IOException e) {
410:                    throw new JAXBException(e);
411:                }
412:
413:                // else no provider found
414:                logger.fine("Trying to create the platform default provider");
415:                return newInstance(classes, properties,
416:                        PLATFORM_DEFAULT_FACTORY_CLASS);
417:            }
418:
419:            private static Properties loadJAXBProperties(
420:                    ClassLoader classLoader, String propFileName)
421:                    throws JAXBException {
422:
423:                Properties props = null;
424:
425:                try {
426:                    URL url;
427:                    if (classLoader == null)
428:                        url = ClassLoader.getSystemResource(propFileName);
429:                    else
430:                        url = classLoader.getResource(propFileName);
431:
432:                    if (url != null) {
433:                        logger.fine("loading props from " + url);
434:                        props = new Properties();
435:                        InputStream is = url.openStream();
436:                        props.load(is);
437:                        is.close();
438:                    }
439:                } catch (IOException ioe) {
440:                    logger.log(Level.FINE, "Unable to load " + propFileName,
441:                            ioe);
442:                    throw new JAXBException(ioe.toString(), ioe);
443:                }
444:
445:                return props;
446:            }
447:
448:            /**
449:             * Search the given ClassLoader for an instance of the specified class and
450:             * return a string representation of the URL that points to the resource.
451:             *
452:             * @param clazz
453:             *          The class to search for
454:             * @param loader
455:             *          The ClassLoader to search.  If this parameter is null, then the
456:             *          system class loader will be searched
457:             * @return
458:             *          the URL for the class or null if it wasn't found
459:             */
460:            static URL which(Class clazz, ClassLoader loader) {
461:
462:                String classnameAsResource = clazz.getName().replace('.', '/')
463:                        + ".class";
464:
465:                if (loader == null) {
466:                    loader = ClassLoader.getSystemClassLoader();
467:                }
468:
469:                return loader.getResource(classnameAsResource);
470:            }
471:
472:            /**
473:             * Get the URL for the Class from it's ClassLoader.
474:             *
475:             * Convenience method for {@link #which(Class, ClassLoader)}.
476:             *
477:             * Equivalent to calling: which(clazz, clazz.getClassLoader())
478:             *
479:             * @param clazz
480:             *          The class to search for
481:             * @return
482:             *          the URL for the class or null if it wasn't found
483:             */
484:            static URL which(Class clazz) {
485:                return which(clazz, clazz.getClassLoader());
486:            }
487:
488:            /**
489:             * When JAXB is in J2SE, rt.jar has to have a JAXB implementation.
490:             * However, rt.jar cannot have META-INF/services/javax.xml.bind.JAXBContext
491:             * because if it has, it will take precedence over any file that applications have
492:             * in their jar files.
493:             *
494:             * <p>
495:             * When the user bundles his own JAXB implementation, we'd like to use it, and we
496:             * want the platform default to be used only when there's no other JAXB provider.
497:             *
498:             * <p>
499:             * For this reason, we have to hard-code the class name into the API.
500:             */
501:            private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.bind.v2.ContextFactory";
502:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.