28 import org.w3c.dom.Node;
29
30 import java.util.Collections;
31 import java.util.Map;
32 import java.util.Properties;
33 import java.io.IOException;
34 import java.io.InputStream;
35
36 /**
37 * <p>
38 * The <tt>JAXBContext</tt> class provides the client's entry point to the
39 * JAXB API. It provides an abstraction for managing the XML/Java binding
40 * information necessary to implement the JAXB binding framework operations:
41 * unmarshal, marshal and validate.
42 *
43 * <p>A client application normally obtains new instances of this class using
44 * one of these two styles for newInstance methods, although there are other
45 * specialized forms of the method available:
46 *
47 * <ul>
48 * <li>{@link #newInstance(String,ClassLoader) JAXBContext.newInstance( "com.acme.foo:com.acme.bar" )} <br>
49 * The JAXBContext instance is initialized from a list of colon
50 * separated Java package names. Each java package contains
51 * JAXB mapped classes, schema-derived classes and/or user annotated
52 * classes. Additionally, the java package may contain JAXB package annotations
53 * that must be processed. (see JLS, Section 7.4.1 "Named Packages").
54 * </li>
55 * <li>{@link #newInstance(Class...) JAXBContext.newInstance( com.acme.foo.Foo.class )} <br>
56 * The JAXBContext instance is initialized with class(es)
57 * passed as parameter(s) and classes that are statically reachable from
58 * these class(es). See {@link #newInstance(Class...)} for details.
59 * </li>
60 * </ul>
61 *
62 * <p>
63 * <i><B>SPEC REQUIREMENT:</B> the provider must supply an implementation
64 * class containing the following method signatures:</i>
65 *
66 * <pre>{@code
67 * public static JAXBContext createContext( String contextPath, ClassLoader classLoader, Map<String,Object> properties ) throws JAXBException
68 * public static JAXBContext createContext( Class[] classes, Map<String,Object> properties ) throws JAXBException
69 * }</pre>
70 *
71 * <p><i>
72 * The following JAXB 1.0 requirement is only required for schema to
73 * java interface/implementation binding. It does not apply to JAXB annotated
74 * classes. JAXB Providers must generate a <tt>jaxb.properties</tt> file in
75 * each package containing schema derived classes. The property file must
76 * contain a property named <tt>javax.xml.bind.context.factory</tt> whose
77 * value is the name of the class that implements the <tt>createContext</tt>
78 * APIs.</i>
79 *
80 * <p><i>
81 * The class supplied by the provider does not have to be assignable to
82 * <tt>javax.xml.bind.JAXBContext</tt>, it simply has to provide a class that
83 * implements the <tt>createContext</tt> APIs.</i>
84 *
85 * <p><i>
86 * In addition, the provider must call the
87 * {@link DatatypeConverter#setDatatypeConverter(DatatypeConverterInterface)
88 * DatatypeConverter.setDatatypeConverter} api prior to any client
89 * invocations of the marshal and unmarshal methods. This is necessary to
90 * configure the datatype converter that will be used during these operations.</i>
129 * of that type. For example,
130 * assume that after compiling a schema, you have a package <tt>com.acme.foo</tt>
131 * that contains a schema derived interface named <tt>PurchaseOrder</tt>. In
132 * order to create objects of that type, the client application would use the
133 * factory method like this:
134 *
135 * <pre>
136 * com.acme.foo.PurchaseOrder po =
137 * com.acme.foo.ObjectFactory.createPurchaseOrder();
138 * </pre>
139 *
140 * <p>
141 * Once the client application has an instance of the the schema derived object,
142 * it can use the mutator methods to set content on it.
143 *
144 * <p>
145 * For more information on the generated <tt>ObjectFactory</tt> classes, see
146 * Section 4.2 <i>Java Package</i> of the specification.
147 *
148 * <p>
149 * <i><B>SPEC REQUIREMENT:</B> the provider must generate a class in each
150 * package that contains all of the necessary object factory methods for that
151 * package named ObjectFactory as well as the static
152 * <tt>newInstance( javaContentInterface )</tt> method</i>
153 *
154 * <h3>Marshalling</h3>
155 * <p>
156 * The {@link Marshaller} class provides the client application the ability
157 * to convert a Java content tree back into XML data. There is no difference
158 * between marshalling a content tree that is created manually using the factory
159 * methods and marshalling a content tree that is the result an <tt>unmarshal
160 * </tt> operation. Clients can marshal a java content tree back to XML data
161 * to a <tt>java.io.OutputStream</tt> or a <tt>java.io.Writer</tt>. The
162 * marshalling process can alternatively produce SAX2 event streams to a
163 * registered <tt>ContentHandler</tt> or produce a DOM Node object.
164 * Client applications have control over the output encoding as well as
165 * whether or not to marshal the XML data as a complete document or
166 * as a fragment.
167 *
168 * <p>
169 * Here is a simple example that unmarshals an XML document and then marshals
197 *
198 *
199 * <h3>JAXB Runtime Binding Framework Compatibility</h3>
200 * <p>
201 * The following JAXB 1.0 restriction only applies to binding schema to
202 * interfaces/implementation classes.
203 * Since this binding does not require a common runtime system, a JAXB
204 * client application must not attempt to mix runtime objects (<tt>JAXBContext,
205 * Marshaller</tt>, etc. ) from different providers. This does not
206 * mean that the client application isn't portable, it simply means that a
207 * client has to use a runtime system provided by the same provider that was
208 * used to compile the schema.
209 *
210 *
211 * <h3>Discovery of JAXB implementation</h3>
212 * <p>
213 * When one of the <tt>newInstance</tt> methods is called, a JAXB implementation is discovered
214 * by the following steps.
215 *
216 * <ol>
217 * <li>
218 * For each package/class explicitly passed in to the {@link #newInstance} method, in the order they are specified,
219 * <tt>jaxb.properties</tt> file is looked up in its package, by using the associated classloader —
220 * this is {@link Class#getClassLoader() the owner class loader} for a {@link Class} argument, and for a package
221 * the specified {@link ClassLoader}.
222 *
223 * <p>
224 * If such a file is discovered, it is {@link Properties#load(InputStream) loaded} as a property file, and
225 * the value of the {@link #JAXB_CONTEXT_FACTORY} key will be assumed to be the provider factory class.
226 * This class is then loaded by the associated classloader discussed above.
227 *
228 * <p>
229 * This phase of the look up allows some packages to force the use of a certain JAXB implementation.
230 * (For example, perhaps the schema compiler has generated some vendor extension in the code.)
231 *
232 * <li>
233 * If the system property {@link #JAXB_CONTEXT_FACTORY} exists, then its value is assumed to be the provider
234 * factory class. This phase of the look up enables per-JVM override of the JAXB implementation.
235 *
236 * <li>
237 * Look for <tt>/META-INF/services/javax.xml.bind.JAXBContext</tt> file in the associated classloader.
238 * This file follows the standard service descriptor convention, and if such a file exists, its content
239 * is assumed to be the provider factory class. This phase of the look up is for automatic discovery.
240 * It allows users to just put a JAXB implementation in a classpath and use it without any furhter configuration.
241 *
242 * <li>
243 * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
244 * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
245 * This phase of the look up is so that JavaSE can have its own JAXB implementation as the last resort.
246 * </ol>
247 *
248 * <p>
249 * Once the provider factory class is discovered, its
250 * <tt>public static JAXBContext createContext(String,ClassLoader,Map)</tt> method
251 * (see {@link #newInstance(String, ClassLoader, Map)} for the parameter semantics.)
252 * or <tt>public static JAXBContext createContet(Class[],Map)</tt> method
253 * (see {@link #newInstance(Class[], Map)} for the parameter semantics) are invoked
254 * to create a {@link JAXBContext}.
255 *
256 * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul>
257 * @see Marshaller
258 * @see Unmarshaller
259 * @see <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html#jls-7.4.1">S 7.4.1 "Named Packages" in Java Language Specification</a>
260 * @since 1.6, JAXB 1.0
261 */
262 public abstract class JAXBContext {
263
264 /**
265 * The name of the property that contains the name of the class capable
266 * of creating new <tt>JAXBContext</tt> objects.
267 */
268 public static final String JAXB_CONTEXT_FACTORY =
269 "javax.xml.bind.context.factory";
270
271
272 protected JAXBContext() {
273 }
274
275
276 /**
277 * <p>
278 * Obtain a new instance of a <tt>JAXBContext</tt> class.
279 *
280 * <p>
281 * This is a convenience method to invoke the
282 * {@link #newInstance(String,ClassLoader)} method with
283 * the context class loader of the current thread.
284 *
285 * @throws JAXBException if an error was encountered while creating the
286 * <tt>JAXBContext</tt> such as
287 * <ol>
288 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
289 * <li>an ambiguity among global elements contained in the contextPath</li>
290 * <li>failure to locate a value for the context factory provider property</li>
291 * <li>mixing schema derived packages from different providers on the same contextPath</li>
292 * </ol>
293 */
294 public static JAXBContext newInstance( String contextPath )
295 throws JAXBException {
296
297 //return newInstance( contextPath, JAXBContext.class.getClassLoader() );
298 return newInstance( contextPath, getContextClassLoader());
299 }
300
301 /**
302 * <p>
303 * Obtain a new instance of a <tt>JAXBContext</tt> class.
304 *
305 * <p>
306 * The client application must supply a context path which is a list of
307 * colon (':', \u005Cu003A) separated java package names that contain
308 * schema-derived classes and/or fully qualified JAXB-annotated classes.
309 * Schema-derived
310 * code is registered with the JAXBContext by the
311 * ObjectFactory.class generated per package.
312 * Alternatively than being listed in the context path, programmer
313 * annotated JAXB mapped classes can be listed in a
314 * <tt>jaxb.index</tt> resource file, format described below.
315 * Note that a java package can contain both schema-derived classes and
316 * user annotated JAXB classes. Additionally, the java package may
317 * contain JAXB package annotations that must be processed. (see JLS,
318 * Section 7.4.1 "Named Packages").
319 * </p>
320 *
321 * <p>
322 * Every package listed on the contextPath must meet <b>one or both</b> of the
323 * following conditions otherwise a <tt>JAXBException</tt> will be thrown:
379 * This class loader will be used to locate the implementation
380 * classes.
381 *
382 * @return a new instance of a <tt>JAXBContext</tt>
383 * @throws JAXBException if an error was encountered while creating the
384 * <tt>JAXBContext</tt> such as
385 * <ol>
386 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
387 * <li>an ambiguity among global elements contained in the contextPath</li>
388 * <li>failure to locate a value for the context factory provider property</li>
389 * <li>mixing schema derived packages from different providers on the same contextPath</li>
390 * </ol>
391 */
392 public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException {
393
394 return newInstance(contextPath,classLoader,Collections.<String,Object>emptyMap());
395 }
396
397 /**
398 * <p>
399 * Obtain a new instance of a <tt>JAXBContext</tt> class.
400 *
401 * <p>
402 * This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)},
403 * but this version allows you to pass in provider-specific properties to configure
404 * the instantiation of {@link JAXBContext}.
405 *
406 * <p>
407 * The interpretation of properties is up to implementations. Implementations should
408 * throw <tt>JAXBException</tt> if it finds properties that it doesn't understand.
409 *
410 * @param contextPath list of java package names that contain schema derived classes
411 * @param classLoader
412 * This class loader will be used to locate the implementation classes.
413 * @param properties
414 * provider-specific properties. Can be null, which means the same thing as passing
415 * in an empty map.
416 *
417 * @return a new instance of a <tt>JAXBContext</tt>
418 * @throws JAXBException if an error was encountered while creating the
419 * <tt>JAXBContext</tt> such as
420 * <ol>
421 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
422 * <li>an ambiguity among global elements contained in the contextPath</li>
423 * <li>failure to locate a value for the context factory provider property</li>
424 * <li>mixing schema derived packages from different providers on the same contextPath</li>
425 * </ol>
426 * @since 1.6, JAXB 2.0
427 */
428 public static JAXBContext newInstance( String contextPath, ClassLoader classLoader, Map<String,?> properties )
429 throws JAXBException {
430
431 return ContextFinder.find(
432 /* The default property name according to the JAXB spec */
433 JAXB_CONTEXT_FACTORY,
434
435 /* the context path supplied by the client app */
436 contextPath,
437
438 /* class loader to be used */
439 classLoader,
440 properties );
441 }
442
443 // TODO: resurrect this once we introduce external annotations
444 // /**
445 // * <p>
446 // * Obtain a new instance of a <tt>JAXBContext</tt> class.
447 // *
448 // * <p>
449 // * The client application must supply a list of classes that the new
450 // * context object needs to recognize.
451 // *
452 // * Not only the new context will recognize all the classes specified,
453 // * but it will also recognize any classes that are directly/indirectly
454 // * referenced statically from the specified classes.
455 // *
456 // * For example, in the following Java code, if you do
457 // * <tt>newInstance(Foo.class)</tt>, the newly created {@link JAXBContext}
458 // * will recognize both <tt>Foo</tt> and <tt>Bar</tt>, but not <tt>Zot</tt>:
459 // * <pre>
460 // * class Foo {
461 // * Bar b;
462 // * }
463 // * class Bar { int x; }
464 // * class Zot extends Bar { int y; }
465 // * </pre>
466 // *
467 // * Therefore, a typical client application only needs to specify the
468 // * top-level classes, but it needs to be careful.
469 // *
470 // * TODO: if we are to define other mechanisms, refer to them.
471 // *
472 // * @param externalBindings
473 // * list of external binding files. Can be null or empty if none is used.
474 // * when specified, those files determine how the classes are bound.
475 // *
476 // * @param classesToBeBound
477 // * list of java classes to be recognized by the new {@link JAXBContext}.
478 // * Can be empty, in which case a {@link JAXBContext} that only knows about
479 // * spec-defined classes will be returned.
480 // *
481 // * @return
482 // * A new instance of a <tt>JAXBContext</tt>. Always non-null valid object.
483 // *
484 // * @throws JAXBException
485 // * if an error was encountered while creating the
486 // * <tt>JAXBContext</tt>, such as (but not limited to):
487 // * <ol>
488 // * <li>No JAXB implementation was discovered
489 // * <li>Classes use JAXB annotations incorrectly
490 // * <li>Classes have colliding annotations (i.e., two classes with the same type name)
491 // * <li>Specified external bindings are incorrect
492 // * <li>The JAXB implementation was unable to locate
493 // * provider-specific out-of-band information (such as additional
494 // * files generated at the development time.)
495 // * </ol>
496 // *
497 // * @throws IllegalArgumentException
498 // * if the parameter contains {@code null} (i.e., {@code newInstance(null);})
499 // *
500 // * @since JAXB 2.0
501 // */
502 // public static JAXBContext newInstance( Source[] externalBindings, Class... classesToBeBound )
503 // throws JAXBException {
504 //
505 // // empty class list is not an error, because the context will still include
506 // // spec-specified classes like String and Integer.
507 // // if(classesToBeBound.length==0)
508 // // throw new IllegalArgumentException();
509 //
510 // // but it is an error to have nulls in it.
511 // for( int i=classesToBeBound.length-1; i>=0; i-- )
512 // if(classesToBeBound[i]==null)
513 // throw new IllegalArgumentException();
514 //
515 // return ContextFinder.find(externalBindings,classesToBeBound);
516 // }
517
518 /**
519 * <p>
520 * Obtain a new instance of a <tt>JAXBContext</tt> class.
521 *
522 * <p>
523 * The client application must supply a list of classes that the new
524 * context object needs to recognize.
525 *
526 * Not only the new context will recognize all the classes specified,
527 * but it will also recognize any classes that are directly/indirectly
528 * referenced statically from the specified classes. Subclasses of
529 * referenced classes nor <tt>@XmlTransient</tt> referenced classes
530 * are not registered with JAXBContext.
531 *
532 * For example, in the following Java code, if you do
533 * <tt>newInstance(Foo.class)</tt>, the newly created {@link JAXBContext}
534 * will recognize both <tt>Foo</tt> and <tt>Bar</tt>, but not <tt>Zot</tt> or <tt>FooBar</tt>:
535 * <pre>
536 * class Foo {
537 * @XmlTransient FooBar c;
538 * Bar b;
539 * }
540 * class Bar { int x; }
542 * class FooBar { }
543 * </pre>
544 *
545 * Therefore, a typical client application only needs to specify the
546 * top-level classes, but it needs to be careful.
547 *
548 * <p>
549 * Note that for each java package registered with JAXBContext,
550 * when the optional package annotations exist, they must be processed.
551 * (see JLS, Section 7.4.1 "Named Packages").
552 *
553 * <p>
554 * The steps involved in discovering the JAXB implementation is discussed in the class javadoc.
555 *
556 * @param classesToBeBound
557 * list of java classes to be recognized by the new {@link JAXBContext}.
558 * Can be empty, in which case a {@link JAXBContext} that only knows about
559 * spec-defined classes will be returned.
560 *
561 * @return
562 * A new instance of a <tt>JAXBContext</tt>. Always non-null valid object.
563 *
564 * @throws JAXBException
565 * if an error was encountered while creating the
566 * <tt>JAXBContext</tt>, such as (but not limited to):
567 * <ol>
568 * <li>No JAXB implementation was discovered
569 * <li>Classes use JAXB annotations incorrectly
570 * <li>Classes have colliding annotations (i.e., two classes with the same type name)
571 * <li>The JAXB implementation was unable to locate
572 * provider-specific out-of-band information (such as additional
573 * files generated at the development time.)
574 * </ol>
575 *
576 * @throws IllegalArgumentException
577 * if the parameter contains {@code null} (i.e., {@code newInstance(null);})
578 *
579 * @since 1.6, JAXB 2.0
580 */
581 public static JAXBContext newInstance( Class... classesToBeBound )
582 throws JAXBException {
583
584 return newInstance(classesToBeBound,Collections.<String,Object>emptyMap());
585 }
586
587 /**
588 * <p>
589 * Obtain a new instance of a <tt>JAXBContext</tt> class.
590 *
591 * <p>
592 * An overloading of {@link JAXBContext#newInstance(Class...)}
593 * to configure 'properties' for this instantiation of {@link JAXBContext}.
594 *
595 * <p>
596 * The interpretation of properties is up to implementations. Implementations should
597 * throw <tt>JAXBException</tt> if it finds properties that it doesn't understand.
598 *
599 * @param classesToBeBound
600 * list of java classes to be recognized by the new {@link JAXBContext}.
601 * Can be empty, in which case a {@link JAXBContext} that only knows about
602 * spec-defined classes will be returned.
603 * @param properties
604 * provider-specific properties. Can be null, which means the same thing as passing
605 * in an empty map.
606 *
607 * @return
608 * A new instance of a <tt>JAXBContext</tt>. Always non-null valid object.
609 *
610 * @throws JAXBException
611 * if an error was encountered while creating the
612 * <tt>JAXBContext</tt>, such as (but not limited to):
613 * <ol>
614 * <li>No JAXB implementation was discovered
615 * <li>Classes use JAXB annotations incorrectly
616 * <li>Classes have colliding annotations (i.e., two classes with the same type name)
617 * <li>The JAXB implementation was unable to locate
618 * provider-specific out-of-band information (such as additional
619 * files generated at the development time.)
620 * </ol>
621 *
622 * @throws IllegalArgumentException
623 * if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);})
624 *
625 * @since 1.6, JAXB 2.0
626 */
627 public static JAXBContext newInstance( Class[] classesToBeBound, Map<String,?> properties )
628 throws JAXBException {
629
630 if (classesToBeBound == null) {
631 throw new IllegalArgumentException();
632 }
633
634 // but it is an error to have nulls in it.
635 for (int i = classesToBeBound.length - 1; i >= 0; i--) {
636 if (classesToBeBound[i] == null) {
637 throw new IllegalArgumentException();
638 }
639 }
640
641 return ContextFinder.find(classesToBeBound,properties);
642 }
643
644 /**
645 * Create an <tt>Unmarshaller</tt> object that can be used to convert XML
646 * data into a java content tree.
647 *
739 *
740 * @throws IOException
741 * if {@link SchemaOutputResolver} throws an {@link IOException}.
742 *
743 * @throws UnsupportedOperationException
744 * Calling this method on JAXB 1.0 implementations will throw
745 * an UnsupportedOperationException.
746 *
747 * @since 1.6, JAXB 2.0
748 */
749 public void generateSchema(SchemaOutputResolver outputResolver) throws IOException {
750 // to make JAXB 1.0 implementations work, this method must not be
751 // abstract
752 throw new UnsupportedOperationException();
753 }
754
755 private static ClassLoader getContextClassLoader() {
756 if (System.getSecurityManager() == null) {
757 return Thread.currentThread().getContextClassLoader();
758 } else {
759 return (ClassLoader) java.security.AccessController.doPrivileged(
760 new java.security.PrivilegedAction() {
761 public java.lang.Object run() {
762 return Thread.currentThread().getContextClassLoader();
763 }
764 });
765 }
766 }
767
768 }
|
28 import org.w3c.dom.Node;
29
30 import java.util.Collections;
31 import java.util.Map;
32 import java.util.Properties;
33 import java.io.IOException;
34 import java.io.InputStream;
35
36 /**
37 * <p>
38 * The <tt>JAXBContext</tt> class provides the client's entry point to the
39 * JAXB API. It provides an abstraction for managing the XML/Java binding
40 * information necessary to implement the JAXB binding framework operations:
41 * unmarshal, marshal and validate.
42 *
43 * <p>A client application normally obtains new instances of this class using
44 * one of these two styles for newInstance methods, although there are other
45 * specialized forms of the method available:
46 *
47 * <ul>
48 * <li>{@link #newInstance(String, ClassLoader) JAXBContext.newInstance( "com.acme.foo:com.acme.bar" )} <br>
49 * The JAXBContext instance is initialized from a list of colon
50 * separated Java package names. Each java package contains
51 * JAXB mapped classes, schema-derived classes and/or user annotated
52 * classes. Additionally, the java package may contain JAXB package annotations
53 * that must be processed. (see JLS, Section 7.4.1 "Named Packages").
54 * </li>
55 * <li>{@link #newInstance(Class...) JAXBContext.newInstance( com.acme.foo.Foo.class )} <br>
56 * The JAXBContext instance is initialized with class(es)
57 * passed as parameter(s) and classes that are statically reachable from
58 * these class(es). See {@link #newInstance(Class...)} for details.
59 * </li>
60 * </ul>
61 *
62 * <p><i>
63 * The following JAXB 1.0 requirement is only required for schema to
64 * java interface/implementation binding. It does not apply to JAXB annotated
65 * classes. JAXB Providers must generate a <tt>jaxb.properties</tt> file in
66 * each package containing schema derived classes. The property file must
67 * contain a property named <tt>javax.xml.bind.context.factory</tt> whose
68 * value is the name of the class that implements the <tt>createContext</tt>
69 * APIs.</i>
70 *
71 * <p><i>
72 * The class supplied by the provider does not have to be assignable to
73 * <tt>javax.xml.bind.JAXBContext</tt>, it simply has to provide a class that
74 * implements the <tt>createContext</tt> APIs.</i>
75 *
76 * <p><i>
77 * In addition, the provider must call the
78 * {@link DatatypeConverter#setDatatypeConverter(DatatypeConverterInterface)
79 * DatatypeConverter.setDatatypeConverter} api prior to any client
80 * invocations of the marshal and unmarshal methods. This is necessary to
81 * configure the datatype converter that will be used during these operations.</i>
120 * of that type. For example,
121 * assume that after compiling a schema, you have a package <tt>com.acme.foo</tt>
122 * that contains a schema derived interface named <tt>PurchaseOrder</tt>. In
123 * order to create objects of that type, the client application would use the
124 * factory method like this:
125 *
126 * <pre>
127 * com.acme.foo.PurchaseOrder po =
128 * com.acme.foo.ObjectFactory.createPurchaseOrder();
129 * </pre>
130 *
131 * <p>
132 * Once the client application has an instance of the the schema derived object,
133 * it can use the mutator methods to set content on it.
134 *
135 * <p>
136 * For more information on the generated <tt>ObjectFactory</tt> classes, see
137 * Section 4.2 <i>Java Package</i> of the specification.
138 *
139 * <p>
140 * <i>The provider must generate a class in each
141 * package that contains all of the necessary object factory methods for that
142 * package named ObjectFactory as well as the static
143 * <tt>newInstance( javaContentInterface )</tt> method</i>
144 *
145 * <h3>Marshalling</h3>
146 * <p>
147 * The {@link Marshaller} class provides the client application the ability
148 * to convert a Java content tree back into XML data. There is no difference
149 * between marshalling a content tree that is created manually using the factory
150 * methods and marshalling a content tree that is the result an <tt>unmarshal
151 * </tt> operation. Clients can marshal a java content tree back to XML data
152 * to a <tt>java.io.OutputStream</tt> or a <tt>java.io.Writer</tt>. The
153 * marshalling process can alternatively produce SAX2 event streams to a
154 * registered <tt>ContentHandler</tt> or produce a DOM Node object.
155 * Client applications have control over the output encoding as well as
156 * whether or not to marshal the XML data as a complete document or
157 * as a fragment.
158 *
159 * <p>
160 * Here is a simple example that unmarshals an XML document and then marshals
188 *
189 *
190 * <h3>JAXB Runtime Binding Framework Compatibility</h3>
191 * <p>
192 * The following JAXB 1.0 restriction only applies to binding schema to
193 * interfaces/implementation classes.
194 * Since this binding does not require a common runtime system, a JAXB
195 * client application must not attempt to mix runtime objects (<tt>JAXBContext,
196 * Marshaller</tt>, etc. ) from different providers. This does not
197 * mean that the client application isn't portable, it simply means that a
198 * client has to use a runtime system provided by the same provider that was
199 * used to compile the schema.
200 *
201 *
202 * <h3>Discovery of JAXB implementation</h3>
203 * <p>
204 * When one of the <tt>newInstance</tt> methods is called, a JAXB implementation is discovered
205 * by the following steps.
206 *
207 * <ol>
208 *
209 * <li>
210 * For each package/class explicitly passed in to the {@link #newInstance} method, in the order they are specified,
211 * <tt>jaxb.properties</tt> file is looked up in its package, by using the associated classloader —
212 * this is {@link Class#getClassLoader() the owner class loader} for a {@link Class} argument, and for a package
213 * the specified {@link ClassLoader}.
214 *
215 * <p>
216 * If such a file is discovered, it is {@link Properties#load(InputStream) loaded} as a property file, and
217 * the value of the {@link #JAXB_CONTEXT_FACTORY} key will be assumed to be the provider factory class.
218 * This class is then loaded by the associated class loader discussed above.
219 *
220 * <p>
221 * This phase of the look up allows some packages to force the use of a certain JAXB implementation.
222 * (For example, perhaps the schema compiler has generated some vendor extension in the code.)
223 *
224 * <li>
225 * If the system property {@link #JAXB_CONTEXT_FACTORY} exists, then its value is assumed to be the provider
226 * factory class. This phase of the look up enables per-JVM override of the JAXB implementation.
227 *
228 * <li>
229 * Provider of {@link javax.xml.bind.JAXBContextFactory} is loaded using the service-provider loading
230 * facilities, defined by the {@link java.util.ServiceLoader} class, to attempt
231 * to locate and load an implementation of the service using the {@linkplain
232 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: the service-provider loading facility
233 * will use the {@linkplain java.lang.Thread#getContextClassLoader() current thread's context class loader}
234 * to attempt to load the context factory. If the context class loader is null, the
235 * {@linkplain ClassLoader#getSystemClassLoader() system class loader} will be used.
236 * <br>
237 * In case of {@link java.util.ServiceConfigurationError service
238 * configuration error} a {@link javax.xml.bind.JAXBException} will be thrown.
239 * </li>
240 *
241 * <li>
242 * Look for resource {@code /META-INF/services/javax.xml.bind.JAXBContext} using provided class loader.
243 * Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}.
244 * If such a resource exists, its content is assumed to be the provider factory class and must supply
245 * an implementation class containing the following method signatures:
246 *
247 * <pre>
248 *
249 * public static JAXBContext createContext(
250 * String contextPath,
251 * ClassLoader classLoader,
252 * Map<String,Object> properties throws JAXBException
253 *
254 * public static JAXBContext createContext(
255 * Class[] classes,
256 * Map<String,Object> properties ) throws JAXBException
257 * </pre>
258 * This configuration method is deprecated.
259 *
260 * <li>
261 * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
262 * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
263 * This phase of the look up is so that JavaSE can have its own JAXB implementation as the last resort.
264 * </ol>
265 *
266 * <p>
267 * Once the provider factory class {@link javax.xml.bind.JAXBContextFactory} is discovered, one of its methods
268 * {@link javax.xml.bind.JAXBContextFactory#createContext(String, ClassLoader, java.util.Map)} or
269 * {@link javax.xml.bind.JAXBContextFactory#createContext(Class[], java.util.Map)} is invoked
270 * to create a {@link JAXBContext}.
271 *
272 * <p/>
273 *
274 * @apiNote
275 * <p>Service discovery method using file /META-INF/services/javax.xml.bind.JAXBContext (described in step 4)
276 * and leveraging provider's static methods is supported only to allow backwards compatibility, but it is strongly
277 * recommended to migrate to standard ServiceLoader mechanism (described in step 3).
278 *
279 * @implNote
280 * Within the last step, if Glassfish AS environment detected, its specific service loader is used to find factory class.
281 *
282 * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li>
283 * <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li>
284 * <li>Joe Fialli, Sun Microsystems, Inc.</li></ul>
285 *
286 * @see Marshaller
287 * @see Unmarshaller
288 * @see <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html#jls-7.4.1">S 7.4.1 "Named Packages"
289 * in Java Language Specification</a>
290 *
291 * @since 1.6, JAXB 1.0
292 */
293 public abstract class JAXBContext {
294
295 /**
296 * The name of the property that contains the name of the class capable
297 * of creating new <tt>JAXBContext</tt> objects.
298 */
299 public static final String JAXB_CONTEXT_FACTORY = "javax.xml.bind.JAXBContextFactory";
300
301 protected JAXBContext() {
302 }
303
304
305 /**
306 * <p>
307 * Create a new instance of a <tt>JAXBContext</tt> class.
308 *
309 * <p>
310 * This is a convenience method to invoke the
311 * {@link #newInstance(String,ClassLoader)} method with
312 * the context class loader of the current thread.
313 *
314 * @throws JAXBException if an error was encountered while creating the
315 * <tt>JAXBContext</tt> such as
316 * <ol>
317 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
318 * <li>an ambiguity among global elements contained in the contextPath</li>
319 * <li>failure to locate a value for the context factory provider property</li>
320 * <li>mixing schema derived packages from different providers on the same contextPath</li>
321 * </ol>
322 */
323 public static JAXBContext newInstance( String contextPath )
324 throws JAXBException {
325
326 //return newInstance( contextPath, JAXBContext.class.getClassLoader() );
327 return newInstance( contextPath, getContextClassLoader());
328 }
329
330 /**
331 * <p>
332 * Create a new instance of a <tt>JAXBContext</tt> class.
333 *
334 * <p>
335 * The client application must supply a context path which is a list of
336 * colon (':', \u005Cu003A) separated java package names that contain
337 * schema-derived classes and/or fully qualified JAXB-annotated classes.
338 * Schema-derived
339 * code is registered with the JAXBContext by the
340 * ObjectFactory.class generated per package.
341 * Alternatively than being listed in the context path, programmer
342 * annotated JAXB mapped classes can be listed in a
343 * <tt>jaxb.index</tt> resource file, format described below.
344 * Note that a java package can contain both schema-derived classes and
345 * user annotated JAXB classes. Additionally, the java package may
346 * contain JAXB package annotations that must be processed. (see JLS,
347 * Section 7.4.1 "Named Packages").
348 * </p>
349 *
350 * <p>
351 * Every package listed on the contextPath must meet <b>one or both</b> of the
352 * following conditions otherwise a <tt>JAXBException</tt> will be thrown:
408 * This class loader will be used to locate the implementation
409 * classes.
410 *
411 * @return a new instance of a <tt>JAXBContext</tt>
412 * @throws JAXBException if an error was encountered while creating the
413 * <tt>JAXBContext</tt> such as
414 * <ol>
415 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
416 * <li>an ambiguity among global elements contained in the contextPath</li>
417 * <li>failure to locate a value for the context factory provider property</li>
418 * <li>mixing schema derived packages from different providers on the same contextPath</li>
419 * </ol>
420 */
421 public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException {
422
423 return newInstance(contextPath,classLoader,Collections.<String,Object>emptyMap());
424 }
425
426 /**
427 * <p>
428 * Create a new instance of a <tt>JAXBContext</tt> class.
429 *
430 * <p>
431 * This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)},
432 * but this version allows you to pass in provider-specific properties to configure
433 * the instantiation of {@link JAXBContext}.
434 *
435 * <p>
436 * The interpretation of properties is up to implementations. Implementations should
437 * throw <tt>JAXBException</tt> if it finds properties that it doesn't understand.
438 *
439 * @param contextPath list of java package names that contain schema derived classes
440 * @param classLoader
441 * This class loader will be used to locate the implementation classes.
442 * @param properties
443 * provider-specific properties. Can be null, which means the same thing as passing
444 * in an empty map.
445 *
446 * @return a new instance of a <tt>JAXBContext</tt>
447 * @throws JAXBException if an error was encountered while creating the
448 * <tt>JAXBContext</tt> such as
449 * <ol>
450 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
451 * <li>an ambiguity among global elements contained in the contextPath</li>
452 * <li>failure to locate a value for the context factory provider property</li>
453 * <li>mixing schema derived packages from different providers on the same contextPath</li>
454 * </ol>
455 * @since 1.6, JAXB 2.0
456 */
457 public static JAXBContext newInstance( String contextPath,
458 ClassLoader classLoader,
459 Map<String,?> properties ) throws JAXBException {
460
461 return ContextFinder.find(
462 /* The default property name according to the JAXB spec */
463 JAXB_CONTEXT_FACTORY,
464
465 /* the context path supplied by the client app */
466 contextPath,
467
468 /* class loader to be used */
469 classLoader,
470 properties );
471 }
472
473 // TODO: resurrect this once we introduce external annotations
474 // /**
475 // * <p>
476 // * Create a new instance of a <tt>JAXBContext</tt> class.
477 // *
478 // * <p>
479 // * The client application must supply a list of classes that the new
480 // * context object needs to recognize.
481 // *
482 // * Not only the new context will recognize all the classes specified,
483 // * but it will also recognize any classes that are directly/indirectly
484 // * referenced statically from the specified classes.
485 // *
486 // * For example, in the following Java code, if you do
487 // * <tt>newInstance(Foo.class)</tt>, the newly created {@link JAXBContext}
488 // * will recognize both <tt>Foo</tt> and <tt>Bar</tt>, but not <tt>Zot</tt>:
489 // * <pre>
490 // * class Foo {
491 // * Bar b;
492 // * }
493 // * class Bar { int x; }
494 // * class Zot extends Bar { int y; }
495 // * </pre>
496 // *
497 // * Therefore, a typical client application only needs to specify the
498 // * top-level classes, but it needs to be careful.
499 // *
500 // * TODO: if we are to define other mechanisms, refer to them.
501 // *
502 // * @param externalBindings
503 // * list of external binding files. Can be null or empty if none is used.
504 // * when specified, those files determine how the classes are bound.
505 // *
506 // * @param classesToBeBound
507 // * list of java classes to be recognized by the new {@link JAXBContext}.
508 // * Can be empty, in which case a {@link JAXBContext} that only knows about
509 // * spec-defined classes will be returned.
510 // *
511 // * @return
512 // * A new instance of a <tt>JAXBContext</tt>.
513 // *
514 // * @throws JAXBException
515 // * if an error was encountered while creating the
516 // * <tt>JAXBContext</tt>, such as (but not limited to):
517 // * <ol>
518 // * <li>No JAXB implementation was discovered
519 // * <li>Classes use JAXB annotations incorrectly
520 // * <li>Classes have colliding annotations (i.e., two classes with the same type name)
521 // * <li>Specified external bindings are incorrect
522 // * <li>The JAXB implementation was unable to locate
523 // * provider-specific out-of-band information (such as additional
524 // * files generated at the development time.)
525 // * </ol>
526 // *
527 // * @throws IllegalArgumentException
528 // * if the parameter contains {@code null} (i.e., {@code newInstance(null);})
529 // *
530 // * @since JAXB 2.0
531 // */
532 // public static JAXBContext newInstance( Source[] externalBindings, Class... classesToBeBound )
533 // throws JAXBException {
534 //
535 // // empty class list is not an error, because the context will still include
536 // // spec-specified classes like String and Integer.
537 // // if(classesToBeBound.length==0)
538 // // throw new IllegalArgumentException();
539 //
540 // // but it is an error to have nulls in it.
541 // for( int i=classesToBeBound.length-1; i>=0; i-- )
542 // if(classesToBeBound[i]==null)
543 // throw new IllegalArgumentException();
544 //
545 // return ContextFinder.find(externalBindings,classesToBeBound);
546 // }
547
548 /**
549 * <p>
550 * Create a new instance of a <tt>JAXBContext</tt> class.
551 *
552 * <p>
553 * The client application must supply a list of classes that the new
554 * context object needs to recognize.
555 *
556 * Not only the new context will recognize all the classes specified,
557 * but it will also recognize any classes that are directly/indirectly
558 * referenced statically from the specified classes. Subclasses of
559 * referenced classes nor <tt>@XmlTransient</tt> referenced classes
560 * are not registered with JAXBContext.
561 *
562 * For example, in the following Java code, if you do
563 * <tt>newInstance(Foo.class)</tt>, the newly created {@link JAXBContext}
564 * will recognize both <tt>Foo</tt> and <tt>Bar</tt>, but not <tt>Zot</tt> or <tt>FooBar</tt>:
565 * <pre>
566 * class Foo {
567 * @XmlTransient FooBar c;
568 * Bar b;
569 * }
570 * class Bar { int x; }
572 * class FooBar { }
573 * </pre>
574 *
575 * Therefore, a typical client application only needs to specify the
576 * top-level classes, but it needs to be careful.
577 *
578 * <p>
579 * Note that for each java package registered with JAXBContext,
580 * when the optional package annotations exist, they must be processed.
581 * (see JLS, Section 7.4.1 "Named Packages").
582 *
583 * <p>
584 * The steps involved in discovering the JAXB implementation is discussed in the class javadoc.
585 *
586 * @param classesToBeBound
587 * list of java classes to be recognized by the new {@link JAXBContext}.
588 * Can be empty, in which case a {@link JAXBContext} that only knows about
589 * spec-defined classes will be returned.
590 *
591 * @return
592 * A new instance of a <tt>JAXBContext</tt>.
593 *
594 * @throws JAXBException
595 * if an error was encountered while creating the
596 * <tt>JAXBContext</tt>, such as (but not limited to):
597 * <ol>
598 * <li>No JAXB implementation was discovered
599 * <li>Classes use JAXB annotations incorrectly
600 * <li>Classes have colliding annotations (i.e., two classes with the same type name)
601 * <li>The JAXB implementation was unable to locate
602 * provider-specific out-of-band information (such as additional
603 * files generated at the development time.)
604 * </ol>
605 *
606 * @throws IllegalArgumentException
607 * if the parameter contains {@code null} (i.e., {@code newInstance(null);})
608 *
609 * @since 1.6, JAXB 2.0
610 */
611 public static JAXBContext newInstance( Class<?> ... classesToBeBound )
612 throws JAXBException {
613
614 return newInstance(classesToBeBound,Collections.<String,Object>emptyMap());
615 }
616
617 /**
618 * <p>
619 * Create a new instance of a <tt>JAXBContext</tt> class.
620 *
621 * <p>
622 * An overloading of {@link JAXBContext#newInstance(Class...)}
623 * to configure 'properties' for this instantiation of {@link JAXBContext}.
624 *
625 * <p>
626 * The interpretation of properties is up to implementations. Implementations should
627 * throw <tt>JAXBException</tt> if it finds properties that it doesn't understand.
628 *
629 * @param classesToBeBound
630 * list of java classes to be recognized by the new {@link JAXBContext}.
631 * Can be empty, in which case a {@link JAXBContext} that only knows about
632 * spec-defined classes will be returned.
633 * @param properties
634 * provider-specific properties. Can be null, which means the same thing as passing
635 * in an empty map.
636 *
637 * @return
638 * A new instance of a <tt>JAXBContext</tt>.
639 *
640 * @throws JAXBException
641 * if an error was encountered while creating the
642 * <tt>JAXBContext</tt>, such as (but not limited to):
643 * <ol>
644 * <li>No JAXB implementation was discovered
645 * <li>Classes use JAXB annotations incorrectly
646 * <li>Classes have colliding annotations (i.e., two classes with the same type name)
647 * <li>The JAXB implementation was unable to locate
648 * provider-specific out-of-band information (such as additional
649 * files generated at the development time.)
650 * </ol>
651 *
652 * @throws IllegalArgumentException
653 * if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);})
654 *
655 * @since 1.6, JAXB 2.0
656 */
657 public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
658 throws JAXBException {
659
660 if (classesToBeBound == null) {
661 throw new IllegalArgumentException();
662 }
663
664 // but it is an error to have nulls in it.
665 for (int i = classesToBeBound.length - 1; i >= 0; i--) {
666 if (classesToBeBound[i] == null) {
667 throw new IllegalArgumentException();
668 }
669 }
670
671 return ContextFinder.find(classesToBeBound,properties);
672 }
673
674 /**
675 * Create an <tt>Unmarshaller</tt> object that can be used to convert XML
676 * data into a java content tree.
677 *
769 *
770 * @throws IOException
771 * if {@link SchemaOutputResolver} throws an {@link IOException}.
772 *
773 * @throws UnsupportedOperationException
774 * Calling this method on JAXB 1.0 implementations will throw
775 * an UnsupportedOperationException.
776 *
777 * @since 1.6, JAXB 2.0
778 */
779 public void generateSchema(SchemaOutputResolver outputResolver) throws IOException {
780 // to make JAXB 1.0 implementations work, this method must not be
781 // abstract
782 throw new UnsupportedOperationException();
783 }
784
785 private static ClassLoader getContextClassLoader() {
786 if (System.getSecurityManager() == null) {
787 return Thread.currentThread().getContextClassLoader();
788 } else {
789 return java.security.AccessController.doPrivileged(
790 new java.security.PrivilegedAction<ClassLoader>() {
791 public ClassLoader run() {
792 return Thread.currentThread().getContextClassLoader();
793 }
794 });
795 }
796 }
797
798 }
|