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
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 <tt>/META-INF/services/javax.xml.bind.JAXBContext</tt> 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 *
259 * <li>
260 * Look for resource <tt>/META-INF/services/javax.xml.bind.JAXBContext</tt> using provided class loader.
261 * Methods without class loader parameter use {@code Thread.currentThread().getContextClassLoader()}.
262 * If such a resource exists, its content is assumed to be the provider factory class and must supply
263 * an implementation class containing the following method signatures:
264 *
265 * <pre>
266 *
267 * public static JAXBContext createContext(
268 * String contextPath,
269 * ClassLoader classLoader,
270 * Map<String,Object> properties throws JAXBException
271 *
272 * public static JAXBContext createContext(
273 * Class[] classes,
274 * Map<String,Object> properties ) throws JAXBException
275 * </pre>
276 * </li>
277 *
278 * <li>
279 * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said,
280 * the recommended behavior is to simply look for some hard-coded platform default JAXB implementation.
281 * This phase of the look up is so that JavaSE can have its own JAXB implementation as the last resort.
282 * </ol>
283 *
284 * <p>
285 * Once the provider factory class {@link javax.xml.bind.JAXBContextFactory} is discovered, one of its methods
286 * {@link javax.xml.bind.JAXBContextFactory#createContext(String, ClassLoader, java.util.Map)} or
287 * {@link javax.xml.bind.JAXBContextFactory#createContext(Class[], java.util.Map)} is invoked
288 * to create a {@link JAXBContext}.
289 *
290 * <p/>
291 *
292 * @apiNote
293 * <p>Service discovery method using file /META-INF/services/javax.xml.bind.JAXBContext (described in step 4)
294 * and leveraging provider's static methods is supported only to allow backwards compatibility, but it is strongly
295 * recommended to migrate to standard ServiceLoader mechanism (described in step 3).
296 *
297 * @implNote
298 * Within the last step, if Glassfish AS environment detected, its specific service loader is used to find factory class.
299 *
300 * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul>
301 * @see Marshaller
302 * @see Unmarshaller
303 * @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>
304 * @since 1.6, JAXB 1.0
305 */
306 public abstract class JAXBContext {
307
308 /**
309 * The name of the property that contains the name of the class capable
310 * of creating new <tt>JAXBContext</tt> objects.
311 */
312 public static final String JAXB_CONTEXT_FACTORY = "javax.xml.bind.JAXBContextFactory";
313
314 protected JAXBContext() {
315 }
316
317
318 /**
319 * <p>
320 * Create a new instance of a <tt>JAXBContext</tt> class.
321 *
322 * <p>
323 * This is a convenience method to invoke the
324 * {@link #newInstance(String,ClassLoader)} method with
325 * the context class loader of the current thread.
326 *
327 * @throws JAXBException if an error was encountered while creating the
328 * <tt>JAXBContext</tt> such as
329 * <ol>
330 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
331 * <li>an ambiguity among global elements contained in the contextPath</li>
332 * <li>failure to locate a value for the context factory provider property</li>
333 * <li>mixing schema derived packages from different providers on the same contextPath</li>
334 * </ol>
335 */
336 public static JAXBContext newInstance( String contextPath )
337 throws JAXBException {
338
339 //return newInstance( contextPath, JAXBContext.class.getClassLoader() );
340 return newInstance( contextPath, getContextClassLoader());
341 }
342
343 /**
344 * <p>
345 * Create a new instance of a <tt>JAXBContext</tt> class.
346 *
347 * <p>
348 * The client application must supply a context path which is a list of
349 * colon (':', \u005Cu003A) separated java package names that contain
350 * schema-derived classes and/or fully qualified JAXB-annotated classes.
351 * Schema-derived
352 * code is registered with the JAXBContext by the
353 * ObjectFactory.class generated per package.
354 * Alternatively than being listed in the context path, programmer
355 * annotated JAXB mapped classes can be listed in a
356 * <tt>jaxb.index</tt> resource file, format described below.
357 * Note that a java package can contain both schema-derived classes and
358 * user annotated JAXB classes. Additionally, the java package may
359 * contain JAXB package annotations that must be processed. (see JLS,
360 * Section 7.4.1 "Named Packages").
361 * </p>
362 *
363 * <p>
364 * Every package listed on the contextPath must meet <b>one or both</b> of the
365 * following conditions otherwise a <tt>JAXBException</tt> will be thrown:
421 * This class loader will be used to locate the implementation
422 * classes.
423 *
424 * @return a new instance of a <tt>JAXBContext</tt>
425 * @throws JAXBException if an error was encountered while creating the
426 * <tt>JAXBContext</tt> such as
427 * <ol>
428 * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li>
429 * <li>an ambiguity among global elements contained in the contextPath</li>
430 * <li>failure to locate a value for the context factory provider property</li>
431 * <li>mixing schema derived packages from different providers on the same contextPath</li>
432 * </ol>
433 */
434 public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException {
435
436 return newInstance(contextPath,classLoader,Collections.<String,Object>emptyMap());
437 }
438
439 /**
440 * <p>
441 * Create a new instance of a <tt>JAXBContext</tt> class.
442 *
443 * <p>
444 * This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)},
445 * but this version allows you to pass in provider-specific properties to configure
446 * the instantiation of {@link JAXBContext}.
447 *
448 * <p>
449 * The interpretation of properties is up to implementations. Implementations should
450 * throw <tt>JAXBException</tt> if it finds properties that it doesn't understand.
451 *
452 * @param contextPath list of java package names that contain schema derived classes
453 * @param classLoader
454 * This class loader will be used to locate the implementation classes.
455 * @param properties
456 * provider-specific properties. Can be null, which means the same thing as passing
457 * in an empty map.
458 *
459 * @return a new instance of a <tt>JAXBContext</tt>
460 * @throws JAXBException if an error was encountered while creating the
461 * <tt>JAXBContext</tt> such as
468 * @since 1.6, JAXB 2.0
469 */
470 public static JAXBContext newInstance( String contextPath, ClassLoader classLoader, Map<String,?> properties )
471 throws JAXBException {
472
473 return ContextFinder.find(
474 /* The default property name according to the JAXB spec */
475 JAXB_CONTEXT_FACTORY,
476
477 /* the context path supplied by the client app */
478 contextPath,
479
480 /* class loader to be used */
481 classLoader,
482 properties );
483 }
484
485 // TODO: resurrect this once we introduce external annotations
486 // /**
487 // * <p>
488 // * Create a new instance of a <tt>JAXBContext</tt> class.
489 // *
490 // * <p>
491 // * The client application must supply a list of classes that the new
492 // * context object needs to recognize.
493 // *
494 // * Not only the new context will recognize all the classes specified,
495 // * but it will also recognize any classes that are directly/indirectly
496 // * referenced statically from the specified classes.
497 // *
498 // * For example, in the following Java code, if you do
499 // * <tt>newInstance(Foo.class)</tt>, the newly created {@link JAXBContext}
500 // * will recognize both <tt>Foo</tt> and <tt>Bar</tt>, but not <tt>Zot</tt>:
501 // * <pre>
502 // * class Foo {
503 // * Bar b;
504 // * }
505 // * class Bar { int x; }
506 // * class Zot extends Bar { int y; }
507 // * </pre>
508 // *
509 // * Therefore, a typical client application only needs to specify the
510 // * top-level classes, but it needs to be careful.
511 // *
512 // * TODO: if we are to define other mechanisms, refer to them.
513 // *
514 // * @param externalBindings
515 // * list of external binding files. Can be null or empty if none is used.
516 // * when specified, those files determine how the classes are bound.
517 // *
518 // * @param classesToBeBound
519 // * list of java classes to be recognized by the new {@link JAXBContext}.
520 // * Can be empty, in which case a {@link JAXBContext} that only knows about
521 // * spec-defined classes will be returned.
522 // *
523 // * @return
524 // * A new instance of a <tt>JAXBContext</tt>.
525 // *
526 // * @throws JAXBException
527 // * if an error was encountered while creating the
528 // * <tt>JAXBContext</tt>, such as (but not limited to):
529 // * <ol>
530 // * <li>No JAXB implementation was discovered
531 // * <li>Classes use JAXB annotations incorrectly
532 // * <li>Classes have colliding annotations (i.e., two classes with the same type name)
533 // * <li>Specified external bindings are incorrect
534 // * <li>The JAXB implementation was unable to locate
535 // * provider-specific out-of-band information (such as additional
536 // * files generated at the development time.)
537 // * </ol>
538 // *
539 // * @throws IllegalArgumentException
540 // * if the parameter contains {@code null} (i.e., {@code newInstance(null);})
541 // *
542 // * @since JAXB 2.0
543 // */
544 // public static JAXBContext newInstance( Source[] externalBindings, Class... classesToBeBound )
545 // throws JAXBException {
546 //
547 // // empty class list is not an error, because the context will still include
548 // // spec-specified classes like String and Integer.
549 // // if(classesToBeBound.length==0)
550 // // throw new IllegalArgumentException();
551 //
552 // // but it is an error to have nulls in it.
553 // for( int i=classesToBeBound.length-1; i>=0; i-- )
554 // if(classesToBeBound[i]==null)
555 // throw new IllegalArgumentException();
556 //
557 // return ContextFinder.find(externalBindings,classesToBeBound);
558 // }
559
560 /**
561 * <p>
562 * Create a new instance of a <tt>JAXBContext</tt> class.
563 *
564 * <p>
565 * The client application must supply a list of classes that the new
566 * context object needs to recognize.
567 *
568 * Not only the new context will recognize all the classes specified,
569 * but it will also recognize any classes that are directly/indirectly
570 * referenced statically from the specified classes. Subclasses of
571 * referenced classes nor <tt>@XmlTransient</tt> referenced classes
572 * are not registered with JAXBContext.
573 *
574 * For example, in the following Java code, if you do
575 * <tt>newInstance(Foo.class)</tt>, the newly created {@link JAXBContext}
576 * will recognize both <tt>Foo</tt> and <tt>Bar</tt>, but not <tt>Zot</tt> or <tt>FooBar</tt>:
577 * <pre>
578 * class Foo {
579 * @XmlTransient FooBar c;
580 * Bar b;
581 * }
582 * class Bar { int x; }
584 * class FooBar { }
585 * </pre>
586 *
587 * Therefore, a typical client application only needs to specify the
588 * top-level classes, but it needs to be careful.
589 *
590 * <p>
591 * Note that for each java package registered with JAXBContext,
592 * when the optional package annotations exist, they must be processed.
593 * (see JLS, Section 7.4.1 "Named Packages").
594 *
595 * <p>
596 * The steps involved in discovering the JAXB implementation is discussed in the class javadoc.
597 *
598 * @param classesToBeBound
599 * list of java classes to be recognized by the new {@link JAXBContext}.
600 * Can be empty, in which case a {@link JAXBContext} that only knows about
601 * spec-defined classes will be returned.
602 *
603 * @return
604 * A new instance of a <tt>JAXBContext</tt>.
605 *
606 * @throws JAXBException
607 * if an error was encountered while creating the
608 * <tt>JAXBContext</tt>, such as (but not limited to):
609 * <ol>
610 * <li>No JAXB implementation was discovered
611 * <li>Classes use JAXB annotations incorrectly
612 * <li>Classes have colliding annotations (i.e., two classes with the same type name)
613 * <li>The JAXB implementation was unable to locate
614 * provider-specific out-of-band information (such as additional
615 * files generated at the development time.)
616 * </ol>
617 *
618 * @throws IllegalArgumentException
619 * if the parameter contains {@code null} (i.e., {@code newInstance(null);})
620 *
621 * @since 1.6, JAXB 2.0
622 */
623 public static JAXBContext newInstance( Class<?> ... classesToBeBound )
624 throws JAXBException {
625
626 return newInstance(classesToBeBound,Collections.<String,Object>emptyMap());
627 }
628
629 /**
630 * <p>
631 * Create a new instance of a <tt>JAXBContext</tt> class.
632 *
633 * <p>
634 * An overloading of {@link JAXBContext#newInstance(Class...)}
635 * to configure 'properties' for this instantiation of {@link JAXBContext}.
636 *
637 * <p>
638 * The interpretation of properties is up to implementations. Implementations should
639 * throw <tt>JAXBException</tt> if it finds properties that it doesn't understand.
640 *
641 * @param classesToBeBound
642 * list of java classes to be recognized by the new {@link JAXBContext}.
643 * Can be empty, in which case a {@link JAXBContext} that only knows about
644 * spec-defined classes will be returned.
645 * @param properties
646 * provider-specific properties. Can be null, which means the same thing as passing
647 * in an empty map.
648 *
649 * @return
650 * A new instance of a <tt>JAXBContext</tt>.
651 *
652 * @throws JAXBException
653 * if an error was encountered while creating the
654 * <tt>JAXBContext</tt>, such as (but not limited to):
655 * <ol>
656 * <li>No JAXB implementation was discovered
657 * <li>Classes use JAXB annotations incorrectly
658 * <li>Classes have colliding annotations (i.e., two classes with the same type name)
659 * <li>The JAXB implementation was unable to locate
660 * provider-specific out-of-band information (such as additional
661 * files generated at the development time.)
662 * </ol>
663 *
664 * @throws IllegalArgumentException
665 * if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);})
666 *
667 * @since 1.6, JAXB 2.0
668 */
669 public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
670 throws JAXBException {
671
672 if (classesToBeBound == null) {
673 throw new IllegalArgumentException();
674 }
675
676 // but it is an error to have nulls in it.
677 for (int i = classesToBeBound.length - 1; i >= 0; i--) {
678 if (classesToBeBound[i] == null) {
679 throw new IllegalArgumentException();
680 }
681 }
682
683 return ContextFinder.find(classesToBeBound,properties);
684 }
685
686 /**
687 * Create an <tt>Unmarshaller</tt> object that can be used to convert XML
688 * data into a java content tree.
689 *
781 *
782 * @throws IOException
783 * if {@link SchemaOutputResolver} throws an {@link IOException}.
784 *
785 * @throws UnsupportedOperationException
786 * Calling this method on JAXB 1.0 implementations will throw
787 * an UnsupportedOperationException.
788 *
789 * @since 1.6, JAXB 2.0
790 */
791 public void generateSchema(SchemaOutputResolver outputResolver) throws IOException {
792 // to make JAXB 1.0 implementations work, this method must not be
793 // abstract
794 throw new UnsupportedOperationException();
795 }
796
797 private static ClassLoader getContextClassLoader() {
798 if (System.getSecurityManager() == null) {
799 return Thread.currentThread().getContextClassLoader();
800 } else {
801 return java.security.AccessController.doPrivileged(
802 new java.security.PrivilegedAction<ClassLoader>() {
803 public ClassLoader run() {
804 return Thread.currentThread().getContextClassLoader();
805 }
806 });
807 }
808 }
809
810 }
|