KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > internal > xjc > runtime > JAXBContextFactory


1 package com.sun.tools.internal.xjc.runtime;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.List JavaDoc;
5 import java.util.Map JavaDoc;
6 import java.util.StringTokenizer JavaDoc;
7
8 import javax.xml.bind.JAXBContext;
9 import javax.xml.bind.JAXBException;
10
11 /**
12  * This class implements the actual logic of {@link JAXBContext#newInstance}.
13  *
14  * <p>
15  * This class works as a facade and all the actual work is delegated to
16  * a JAXB provider that happens to be in the runtime (not necessarily the JAXB RI.)
17  * This allows the generated code to be run with any JAXB provider.
18  *
19  * <p>
20  * This code is only used when XJC generates interfaces/implementations.
21  *
22  * <p>
23  * The trick to make this work is two ObjectFactory classes that we generate
24  * in the interface/implementation mode.
25  *
26  * <p>
27  * The public ObjectFactory follows the spec, and this is the one that's exposed
28  * to users. The public ObjectFactory refers to interfaces, so they aren't
29  * directly usable by a JAXB 2.0 implementation.
30  *
31  * <p>
32  * The private one lives in the impl package, and this one is indistinguishable
33  * from the ObjectFactory that we generate for the value class generation mode.
34  * This private ObjectFactory refers to implementation classes, which are
35  * also indistinguishable from value classes that JAXB generates.
36  *
37  * <p>
38  * All in all, the private ObjectFactory plus implementation classes give
39  * a JAXB provider an illusion that they are dealing with value classes
40  * that happens to implement some interfaces.
41  *
42  * <p>
43  * In this way, the JAXB RI can provide the portability even for the
44  * interface/implementation generation mode.
45  *
46  * @since 2.0
47  * @author Kohsuke Kawaguchi
48  */

49 public class JAXBContextFactory {
50     private static final String JavaDoc DOT_OBJECT_FACTORY = ".ObjectFactory";
51     private static final String JavaDoc IMPL_DOT_OBJECT_FACTORY = ".impl.ObjectFactory";
52
53     /**
54      * The JAXB API will invoke this method via reflection
55      */

56     public static JAXBContext createContext( Class JavaDoc[] classes, Map JavaDoc properties ) throws JAXBException {
57         Class JavaDoc[] r = new Class JavaDoc[classes.length];
58         boolean modified = false;
59
60         // find any reference to our 'public' ObjectFactory and
61
// replace that to our 'private' ObjectFactory.
62
for( int i=0; i<r.length; i++ ) {
63             Class JavaDoc c = classes[i];
64             String JavaDoc name = c.getName();
65             if(name.endsWith(DOT_OBJECT_FACTORY)
66             && !name.endsWith(IMPL_DOT_OBJECT_FACTORY)) {
67                 // we never generate into the root package, so no need to worry about FQCN "ObjectFactory"
68

69                 // if we find one, tell the real JAXB provider to
70
// load foo.bar.impl.ObjectFactory
71
name = name.substring(0,name.length()-DOT_OBJECT_FACTORY.length())+IMPL_DOT_OBJECT_FACTORY;
72
73                 try {
74                     c = c.getClassLoader().loadClass(name);
75                 } catch (ClassNotFoundException JavaDoc e) {
76                     throw new JAXBException(e);
77                 }
78
79                 modified = true;
80             }
81
82             r[i] = c;
83         }
84
85         if(!modified) {
86             // if the class list doesn't contain any of our classes,
87
// this ContextFactory shouldn't have been called in the first place
88
// if we simply continue, we'll just end up with the infinite recursion.
89

90             // the only case that I can think of where this could happen is
91
// when the user puts additional classes into the JAXB-generated
92
// package and pass them to JAXBContext.newInstance().
93
// Under normal use, this shouldn't happen.
94

95             // anyway, bail out now.
96
// if you hit this problem and wondering how to get around the problem,
97
// subscribe and send a note to users@jaxb.dev.java.net (http://jaxb.dev.java.net/)
98
throw new JAXBException("Unable to find a JAXB implementation to delegate");
99         }
100
101         // delegate to the JAXB provider in the system
102
return JAXBContext.newInstance(r,properties);
103     }
104
105
106     /**
107      * The JAXB API will invoke this method via reflection
108      */

109     public static JAXBContext createContext( String JavaDoc contextPath,
110                                              ClassLoader JavaDoc classLoader, Map JavaDoc properties ) throws JAXBException {
111
112         List JavaDoc<Class JavaDoc> classes = new ArrayList JavaDoc<Class JavaDoc>();
113         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(contextPath,":");
114
115         // each package should be pointing to a JAXB RI generated
116
// content interface package.
117
//
118
// translate them into a list of private ObjectFactories.
119
try {
120             while(tokens.hasMoreTokens()) {
121                 String JavaDoc pkg = tokens.nextToken();
122                 classes.add(classLoader.loadClass(pkg+IMPL_DOT_OBJECT_FACTORY));
123             }
124         } catch (ClassNotFoundException JavaDoc e) {
125             throw new JAXBException(e);
126         }
127
128         // delegate to the JAXB provider in the system
129
return JAXBContext.newInstance(classes.toArray(new Class JavaDoc[classes.size()]),properties);
130     }
131 }
132
Popular Tags