src/share/jaxws_classes/com/sun/tools/internal/xjc/runtime/JAXBContextFactory.java

changeset 0
373ffda63c9a
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.internal.xjc.runtime;
27
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.StringTokenizer;
32
33 import javax.xml.bind.JAXBContext;
34 import javax.xml.bind.JAXBException;
35
36 /**
37 * This class implements the actual logic of {@link JAXBContext#newInstance}.
38 *
39 * <p>
40 * This class works as a facade and all the actual work is delegated to
41 * a JAXB provider that happens to be in the runtime (not necessarily the JAXB RI.)
42 * This allows the generated code to be run with any JAXB provider.
43 *
44 * <p>
45 * This code is only used when XJC generates interfaces/implementations.
46 *
47 * <p>
48 * The trick to make this work is two ObjectFactory classes that we generate
49 * in the interface/implementation mode.
50 *
51 * <p>
52 * The public ObjectFactory follows the spec, and this is the one that's exposed
53 * to users. The public ObjectFactory refers to interfaces, so they aren't
54 * directly usable by a JAXB 2.0 implementation.
55 *
56 * <p>
57 * The private one lives in the impl package, and this one is indistinguishable
58 * from the ObjectFactory that we generate for the value class generation mode.
59 * This private ObjectFactory refers to implementation classes, which are
60 * also indistinguishable from value classes that JAXB generates.
61 *
62 * <p>
63 * All in all, the private ObjectFactory plus implementation classes give
64 * a JAXB provider an illusion that they are dealing with value classes
65 * that happens to implement some interfaces.
66 *
67 * <p>
68 * In this way, the JAXB RI can provide the portability even for the
69 * interface/implementation generation mode.
70 *
71 * @since 2.0
72 * @author Kohsuke Kawaguchi
73 */
74 public class JAXBContextFactory {
75 private static final String DOT_OBJECT_FACTORY = ".ObjectFactory";
76 private static final String IMPL_DOT_OBJECT_FACTORY = ".impl.ObjectFactory";
77
78 /**
79 * The JAXB API will invoke this method via reflection
80 */
81 public static JAXBContext createContext( Class[] classes, Map properties ) throws JAXBException {
82 Class[] r = new Class[classes.length];
83 boolean modified = false;
84
85 // find any reference to our 'public' ObjectFactory and
86 // replace that to our 'private' ObjectFactory.
87 for( int i=0; i<r.length; i++ ) {
88 Class c = classes[i];
89 String name = c.getName();
90 if(name.endsWith(DOT_OBJECT_FACTORY)
91 && !name.endsWith(IMPL_DOT_OBJECT_FACTORY)) {
92 // we never generate into the root package, so no need to worry about FQCN "ObjectFactory"
93
94 // if we find one, tell the real JAXB provider to
95 // load foo.bar.impl.ObjectFactory
96 name = name.substring(0,name.length()-DOT_OBJECT_FACTORY.length())+IMPL_DOT_OBJECT_FACTORY;
97
98 try {
99 c = getClassClassLoader(c).loadClass(name);
100 } catch (ClassNotFoundException e) {
101 throw new JAXBException(e);
102 }
103
104 modified = true;
105 }
106
107 r[i] = c;
108 }
109
110 if(!modified) {
111 // if the class list doesn't contain any of our classes,
112 // this ContextFactory shouldn't have been called in the first place
113 // if we simply continue, we'll just end up with the infinite recursion.
114
115 // the only case that I can think of where this could happen is
116 // when the user puts additional classes into the JAXB-generated
117 // package and pass them to JAXBContext.newInstance().
118 // Under normal use, this shouldn't happen.
119
120 // anyway, bail out now.
121 // if you hit this problem and wondering how to get around the problem,
122 // subscribe and send a note to users@jaxb.dev.java.net (http://jaxb.dev.java.net/)
123 throw new JAXBException("Unable to find a JAXB implementation to delegate");
124 }
125
126 // delegate to the JAXB provider in the system
127 return JAXBContext.newInstance(r,properties);
128 }
129
130
131 /**
132 * The JAXB API will invoke this method via reflection
133 */
134 public static JAXBContext createContext( String contextPath,
135 ClassLoader classLoader, Map properties ) throws JAXBException {
136
137 List<Class> classes = new ArrayList<Class>();
138 StringTokenizer tokens = new StringTokenizer(contextPath,":");
139
140 // each package should be pointing to a JAXB RI generated
141 // content interface package.
142 //
143 // translate them into a list of private ObjectFactories.
144 try {
145 while(tokens.hasMoreTokens()) {
146 String pkg = tokens.nextToken();
147 classes.add(classLoader.loadClass(pkg+IMPL_DOT_OBJECT_FACTORY));
148 }
149 } catch (ClassNotFoundException e) {
150 throw new JAXBException(e);
151 }
152
153 // delegate to the JAXB provider in the system
154 return JAXBContext.newInstance(classes.toArray(new Class[classes.size()]),properties);
155 }
156
157 private static ClassLoader getClassClassLoader(final Class c) {
158 if (System.getSecurityManager() == null) {
159 return c.getClassLoader();
160 } else {
161 return (ClassLoader) java.security.AccessController.doPrivileged(
162 new java.security.PrivilegedAction() {
163 public java.lang.Object run() {
164 return c.getClassLoader();
165 }
166 });
167 }
168 }
169
170 }

mercurial