1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package org.jomc.model.bootstrap;
34
35 import java.io.BufferedReader;
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.lang.reflect.Constructor;
42 import java.lang.reflect.InvocationTargetException;
43 import java.net.URL;
44 import java.util.Collection;
45 import java.util.Comparator;
46 import java.util.Enumeration;
47 import java.util.Map;
48 import java.util.TreeMap;
49 import javax.xml.bind.JAXBContext;
50 import javax.xml.bind.Marshaller;
51 import javax.xml.bind.Unmarshaller;
52
53
54
55
56
57
58
59
60 public abstract class BootstrapContext
61 {
62
63
64 private static volatile String bootstrapContextClassName;
65
66
67 private ClassLoader classLoader;
68
69
70
71
72
73
74 protected BootstrapContext( final ClassLoader classLoader )
75 {
76 super();
77 this.classLoader = classLoader;
78 }
79
80
81
82
83
84
85 protected ClassLoader getClassLoader()
86 {
87 if ( this.classLoader == null )
88 {
89 this.classLoader = new ClassLoader( null )
90 {
91
92 @Override
93 public String toString()
94 {
95 return BootstrapContext.class.getName() + ".BootstrapClassLoader@" +
96 System.identityHashCode( this );
97
98 }
99
100 };
101
102 }
103
104 return this.classLoader;
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 public static String getBootstrapContextClassName()
119 {
120 if ( bootstrapContextClassName == null )
121 {
122 bootstrapContextClassName = System.getProperty( "org.jomc.model.bootstrap.BootstrapContext.className",
123 DefaultBootstrapContext.class.getName() );
124
125 }
126
127 return bootstrapContextClassName;
128 }
129
130
131
132
133
134
135
136
137 public static void setBootstrapContextClassName( final String value )
138 {
139 bootstrapContextClassName = value;
140 }
141
142
143
144
145
146
147
148
149
150
151
152 public Class findClass( final String name ) throws BootstrapException
153 {
154 if ( name == null )
155 {
156 throw new NullPointerException( "name" );
157 }
158
159 try
160 {
161 return Class.forName( name, true, this.getClassLoader() );
162 }
163 catch ( final ClassNotFoundException e )
164 {
165 return null;
166 }
167 }
168
169
170
171
172
173
174
175
176
177
178
179 public URL findResource( final String name ) throws BootstrapException
180 {
181 if ( name == null )
182 {
183 throw new NullPointerException( "name" );
184 }
185
186 return this.getClassLoader().getResource( name );
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200 public Enumeration<URL> findResources( final String name ) throws BootstrapException
201 {
202 if ( name == null )
203 {
204 throw new NullPointerException( "name" );
205 }
206
207 try
208 {
209 return this.getClassLoader().getResources( name );
210 }
211 catch ( final IOException e )
212 {
213 throw new BootstrapException( e );
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229 public Schemas findSchemas() throws BootstrapException
230 {
231 try
232 {
233 final Schemas schemas = new Schemas();
234
235 final Collection<Class<SchemaProvider>> providers = this.loadProviders( SchemaProvider.class );
236 for ( Class<SchemaProvider> provider : providers )
237 {
238 final SchemaProvider schemaProvider = provider.newInstance();
239 final Schemas provided = schemaProvider.findSchemas( this );
240 if ( provided != null )
241 {
242 schemas.getSchema().addAll( provided.getSchema() );
243 }
244 }
245
246 return schemas;
247 }
248 catch ( final InstantiationException e )
249 {
250 throw new BootstrapException( e );
251 }
252 catch ( final IllegalAccessException e )
253 {
254 throw new BootstrapException( e );
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 public static BootstrapContext createBootstrapContext( final ClassLoader classLoader ) throws BootstrapException
272 {
273 if ( DefaultBootstrapContext.class.getName().equals( getBootstrapContextClassName() ) )
274 {
275 return new DefaultBootstrapContext( classLoader );
276 }
277
278 try
279 {
280 final Class clazz = Class.forName( getBootstrapContextClassName(), true, classLoader );
281 final Constructor ctor = clazz.getConstructor( ClassLoader.class );
282 return (BootstrapContext) ctor.newInstance( classLoader );
283 }
284 catch ( final ClassNotFoundException e )
285 {
286 throw new BootstrapException( e );
287 }
288 catch ( final NoSuchMethodException e )
289 {
290 throw new BootstrapException( e );
291 }
292 catch ( final InstantiationException e )
293 {
294 throw new BootstrapException( e );
295 }
296 catch ( final IllegalAccessException e )
297 {
298 throw new BootstrapException( e );
299 }
300 catch ( final InvocationTargetException e )
301 {
302 throw new BootstrapException( e );
303 }
304 catch ( final ClassCastException e )
305 {
306 throw new BootstrapException( e );
307 }
308 }
309
310
311
312
313
314
315
316
317
318 public abstract javax.xml.validation.Schema createSchema() throws BootstrapException;
319
320
321
322
323
324
325
326
327
328 public abstract JAXBContext createContext() throws BootstrapException;
329
330
331
332
333
334
335
336
337
338 public abstract Marshaller createMarshaller() throws BootstrapException;
339
340
341
342
343
344
345
346
347
348 public abstract Unmarshaller createUnmarshaller() throws BootstrapException;
349
350 private <T> Collection<Class<T>> loadProviders( final Class<T> providerClass ) throws BootstrapException
351 {
352 try
353 {
354 final String providerNamePrefix = providerClass.getName() + ".";
355 final Map<String, Class<T>> providers = new TreeMap<String, Class<T>>( new Comparator<String>()
356 {
357
358 public int compare( final String key1, final String key2 )
359 {
360 return key1.compareTo( key2 );
361 }
362
363 } );
364
365 final File platformProviders = new File( new StringBuilder().append( System.getProperty( "java.home" ) ).
366 append( File.separator ).append( "jre" ).append( File.separator ).append( "lib" ).
367 append( File.separator ).append( "jomc.properties" ).toString() );
368
369 if ( platformProviders.exists() )
370 {
371 InputStream in = null;
372 final java.util.Properties p = new java.util.Properties();
373
374 try
375 {
376 in = new FileInputStream( platformProviders );
377 p.load( in );
378 }
379 finally
380 {
381 if ( in != null )
382 {
383 in.close();
384 }
385 }
386
387 for ( Map.Entry e : p.entrySet() )
388 {
389 if ( e.getKey().toString().startsWith( providerNamePrefix ) )
390 {
391 final Class<T> provider = this.findClass( e.getValue().toString() );
392 if ( provider != null )
393 {
394 providers.put( e.getKey().toString(), provider );
395 }
396 }
397 }
398 }
399
400 final Enumeration<URL> serviceProviders =
401 this.findResources( "META-INF/services/" + providerClass.getName() );
402
403 while ( serviceProviders.hasMoreElements() )
404 {
405 final URL url = serviceProviders.nextElement();
406 final BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream(), "UTF-8" ) );
407
408 String line = null;
409 while ( ( line = reader.readLine() ) != null )
410 {
411 if ( line.contains( "#" ) )
412 {
413 continue;
414 }
415
416 final Class<T> provider = this.findClass( line );
417 if ( provider != null )
418 {
419 providers.put( providerNamePrefix + providers.size(), provider );
420 }
421 }
422
423 reader.close();
424 }
425
426 return providers.values();
427 }
428 catch ( final IOException e )
429 {
430 throw new BootstrapException( e );
431 }
432 }
433
434 }