1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package javax.xml.bind;
18
19 import java.lang.reflect.Method;
20 import java.util.Map;
21 import java.util.Properties;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.BufferedReader;
25 import java.io.InputStreamReader;
26
27 class ContextFinder {
28
29 private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.bind.v2.ContextFactory";
30 private static final String JAXB_CONTEXT_PROPERTY = JAXBContext.class.getName();
31 private static final String JAXB_CONTEXT_FACTORY = JAXBContext.JAXB_CONTEXT_FACTORY;
32
33 public static JAXBContext find(String contextPath, ClassLoader classLoader, Map properties) throws JAXBException {
34 contextPath = contextPath.trim();
35 if (contextPath.length() == 0 || contextPath.equals(":")) {
36 throw new JAXBException("Invalid contextPath");
37 }
38 String className = null;
39 String[] packages = contextPath.split("[:]");
40 for (String pkg : packages) {
41 String url = pkg.replace('.', '/') + "/jaxb.properties";
42 className = loadClassNameFromProperties(url, classLoader);
43 if (className != null) {
44 break;
45 }
46 }
47 if (className == null) {
48 className = System.getProperty(JAXB_CONTEXT_PROPERTY);
49 }
50 if (className == null) {
51 String url = "META-INF/services/" + JAXB_CONTEXT_PROPERTY;
52 className = loadClassName(url, classLoader);
53 }
54 if (className == null) {
55 className = PLATFORM_DEFAULT_FACTORY_CLASS;
56 }
57 Class spi = loadSpi(className, classLoader);
58 try {
59 Method m = spi.getMethod("createContext", new Class[] { String.class, ClassLoader.class, Map.class });
60 return (JAXBContext) m.invoke(null, new Object[] { contextPath, classLoader, properties });
61 } catch (NoSuchMethodException e) {
62
63 } catch (Throwable t) {
64 throw new JAXBException("Unable to create context", t);
65 }
66
67
68 try {
69 Method m = spi.getMethod("createContext", new Class[] { String.class, ClassLoader.class });
70 return (JAXBContext) m.invoke(null, new Object[] { contextPath, classLoader });
71 } catch (Throwable t) {
72 throw new JAXBException("Unable to create context", t);
73 }
74 }
75
76
77 public static JAXBContext find(Class[] classes, Map properties) throws JAXBException {
78 String className = null;
79 for (Class cl : classes) {
80 Package pkg = cl.getPackage();
81 if (pkg != null) {
82 String url = pkg.getName().replace('.', '/') + "/jaxb.properties";
83 className = loadClassNameFromProperties(url, cl.getClassLoader());
84 if (className != null) {
85 break;
86 }
87 }
88 }
89 if (className == null) {
90 className = System.getProperty(JAXB_CONTEXT_PROPERTY);
91 }
92 if (className == null) {
93 String url = "META-INF/services/" + JAXB_CONTEXT_PROPERTY;
94 className = loadClassName(url, Thread.currentThread().getContextClassLoader());
95 }
96 if (className == null) {
97 className = PLATFORM_DEFAULT_FACTORY_CLASS;
98 }
99 Class spi = loadSpi(className, Thread.currentThread().getContextClassLoader());
100 try {
101 Method m = spi.getMethod("createContext", new Class[] { Class[].class, Map.class });
102 return (JAXBContext) m.invoke(null, new Object[] { classes, properties });
103 } catch (Throwable t) {
104 throw new JAXBException("Unable to create context", t);
105 }
106 }
107
108 private static String loadClassNameFromProperties(String url, ClassLoader classLoader) throws JAXBException {
109 try {
110 InputStream is;
111 if (classLoader != null) {
112 is = classLoader.getResourceAsStream(url);
113 } else {
114 is = ClassLoader.getSystemResourceAsStream(url);
115 }
116 if (is != null) {
117 try {
118 Properties props = new Properties();
119 props.load(is);
120 String className = props.getProperty(JAXB_CONTEXT_FACTORY);
121 if (className == null) {
122 throw new JAXBException("jaxb.properties file " + url + " should contain a " + JAXB_CONTEXT_FACTORY + " property");
123 }
124 return className.trim();
125 } finally {
126 is.close();
127 }
128 } else {
129 return null;
130 }
131 } catch (IOException e) {
132 throw new JAXBException(e);
133 }
134 }
135
136 private static String loadClassName(String url, ClassLoader classLoader) throws JAXBException {
137 try {
138 InputStream is;
139 if (classLoader != null) {
140 is = classLoader.getResourceAsStream(url);
141 } else {
142 is = ClassLoader.getSystemResourceAsStream(url);
143 }
144 if (is != null) {
145 try {
146 BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
147 return r.readLine().trim();
148 } finally {
149 is.close();
150 }
151 }
152 return null;
153 } catch (IOException e) {
154 throw new JAXBException(e);
155 }
156 }
157
158 private static Class loadSpi(String className, ClassLoader classLoader) throws JAXBException {
159 Class spiClass;
160 try {
161 if (classLoader != null) {
162 spiClass = classLoader.loadClass(className);
163 } else {
164 spiClass = Class.forName(className);
165 }
166 } catch (ClassNotFoundException e) {
167 throw new JAXBException("Provider " + className + " not found", e);
168 }
169 return spiClass;
170 }
171
172
173 }