1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.bind.api;
  27 
  28 import java.io.IOException;
  29 import java.lang.reflect.Type;
  30 import java.util.Collection;
  31 import java.util.Collections;
  32 import java.util.List;
  33 import java.util.Map;
  34 
  35 import javax.xml.bind.JAXBContext;
  36 import javax.xml.bind.JAXBException;
  37 import javax.xml.bind.Marshaller;
  38 import javax.xml.bind.SchemaOutputResolver;
  39 import javax.xml.bind.annotation.XmlAttachmentRef;
  40 import javax.xml.namespace.QName;
  41 import javax.xml.transform.Result;
  42 
  43 import com.sun.istack.internal.NotNull;
  44 import com.sun.istack.internal.Nullable;
  45 import com.sun.xml.internal.bind.api.impl.NameConverter;
  46 import com.sun.xml.internal.bind.v2.ContextFactory;
  47 import com.sun.xml.internal.bind.v2.model.annotation.RuntimeAnnotationReader;
  48 import com.sun.xml.internal.bind.v2.model.nav.Navigator;
  49 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeTypeInfoSet;
  50 import java.util.HashMap;
  51 
  52 /**
  53  * {@link JAXBContext} enhanced with JAXB RI specific functionalities.
  54  *
  55  * <p>
  56  * <b>Subject to change without notice</b>.
  57  *
  58  * @since 2.0 EA1
  59  * @author
  60  *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  61  */
  62 public abstract class JAXBRIContext extends JAXBContext {
  63 
  64     protected JAXBRIContext() {}
  65 
  66     /**
  67      * Creates a new {@link JAXBRIContext}.
  68      *
  69      * <p>
  70      * {@link JAXBContext#newInstance(Class[]) JAXBContext.newInstance()} methods may
  71      * return other JAXB providers that are not compatible with the JAX-RPC RI.
  72      * This method guarantees that the JAX-WS RI will finds the JAXB RI.
  73      *
  74      * @param classes
  75      *      Classes to be bound. See {@link JAXBContext#newInstance(Class[])} for the meaning.
  76      * @param typeRefs
  77      *      See {@link #TYPE_REFERENCES} for the meaning of this parameter.
  78      *      Can be null.
  79      * @param subclassReplacements
  80      *      See {@link #SUBCLASS_REPLACEMENTS} for the meaning of this parameter.
  81      *      Can be null.
  82      * @param defaultNamespaceRemap
  83      *      See {@link #DEFAULT_NAMESPACE_REMAP} for the meaning of this parameter.
  84      *      Can be null (and should be null for ordinary use of JAXB.)
  85      * @param c14nSupport
  86      *      See {@link #CANONICALIZATION_SUPPORT} for the meaning of this parameter.
  87      * @param ar
  88      *      See {@link #ANNOTATION_READER} for the meaning of this parameter.
  89      *      Can be null.
  90      * @since JAXB 2.1 EA2
  91      */
  92     public static JAXBRIContext newInstance(@NotNull Class[] classes,
  93        @Nullable Collection<TypeReference> typeRefs,
  94        @Nullable Map<Class,Class> subclassReplacements,
  95        @Nullable String defaultNamespaceRemap, boolean c14nSupport,
  96        @Nullable RuntimeAnnotationReader ar) throws JAXBException {
  97         return newInstance(classes, typeRefs, subclassReplacements,
  98                 defaultNamespaceRemap, c14nSupport, ar, false, false, false, false);
  99     }
 100 
 101     /**
 102      * Creates a new {@link JAXBRIContext}.
 103      *
 104      * <p>
 105      * {@link JAXBContext#newInstance(Class[]) JAXBContext.newInstance()} methods may
 106      * return other JAXB providers that are not compatible with the JAX-RPC RI.
 107      * This method guarantees that the JAX-WS RI will finds the JAXB RI.
 108      *
 109      * @param classes
 110      *      Classes to be bound. See {@link JAXBContext#newInstance(Class[])} for the meaning.
 111      * @param typeRefs
 112      *      See {@link #TYPE_REFERENCES} for the meaning of this parameter.
 113      *      Can be null.
 114      * @param subclassReplacements
 115      *      See {@link #SUBCLASS_REPLACEMENTS} for the meaning of this parameter.
 116      *      Can be null.
 117      * @param defaultNamespaceRemap
 118      *      See {@link #DEFAULT_NAMESPACE_REMAP} for the meaning of this parameter.
 119      *      Can be null (and should be null for ordinary use of JAXB.)
 120      * @param c14nSupport
 121      *      See {@link #CANONICALIZATION_SUPPORT} for the meaning of this parameter.
 122      * @param ar
 123      *      See {@link #ANNOTATION_READER} for the meaning of this parameter.
 124      *      Can be null.
 125      * @param xmlAccessorFactorySupport
 126      *      See {@link #XMLACCESSORFACTORY_SUPPORT} for the meaning of this parameter.
 127      * @param allNillable
 128      *      See {@link #TREAT_EVERYTHING_NILLABLE} for the meaning of this parameter.
 129      * @param retainPropertyInfo
 130      *      See {@link #RETAIN_REFERENCE_TO_INFO} for the meaning of this parameter.
 131      * @param supressAccessorWarnings
 132      *      See {@link #SUPRESS_ACCESSOR_WARNINGS} for the meaning of this parameter.
 133      */
 134     public static JAXBRIContext newInstance(@NotNull Class[] classes,
 135        @Nullable Collection<TypeReference> typeRefs,
 136        @Nullable Map<Class,Class> subclassReplacements,
 137        @Nullable String defaultNamespaceRemap, boolean c14nSupport,
 138        @Nullable RuntimeAnnotationReader ar,
 139        boolean xmlAccessorFactorySupport,
 140        boolean allNillable,
 141        boolean retainPropertyInfo,
 142        boolean supressAccessorWarnings) throws JAXBException {
 143         Map<String, Object> properties = new HashMap<String, Object>();
 144         if (typeRefs != null) properties.put(JAXBRIContext.TYPE_REFERENCES, typeRefs);
 145         if (subclassReplacements != null) properties.put(JAXBRIContext.SUBCLASS_REPLACEMENTS, subclassReplacements);
 146         if (defaultNamespaceRemap != null) properties.put(JAXBRIContext.DEFAULT_NAMESPACE_REMAP, defaultNamespaceRemap);
 147         if (ar != null) properties.put(JAXBRIContext.ANNOTATION_READER, ar);
 148         properties.put(JAXBRIContext.CANONICALIZATION_SUPPORT, Boolean.valueOf(c14nSupport));
 149         properties.put(JAXBRIContext.XMLACCESSORFACTORY_SUPPORT, Boolean.valueOf(xmlAccessorFactorySupport));
 150         properties.put(JAXBRIContext.TREAT_EVERYTHING_NILLABLE, Boolean.valueOf(allNillable));
 151         properties.put(JAXBRIContext.RETAIN_REFERENCE_TO_INFO, Boolean.valueOf(retainPropertyInfo));
 152         properties.put(JAXBRIContext.SUPRESS_ACCESSOR_WARNINGS, Boolean.valueOf(supressAccessorWarnings));
 153         return (JAXBRIContext) ContextFactory.createContext(classes, properties);
 154     }
 155 
 156     /**
 157      * @deprecated
 158      *      Compatibility with older versions.
 159      */
 160     public static JAXBRIContext newInstance(@NotNull Class[] classes,
 161         @Nullable Collection<TypeReference> typeRefs,
 162         @Nullable String defaultNamespaceRemap, boolean c14nSupport ) throws JAXBException {
 163         return newInstance(classes,typeRefs, Collections.<Class,Class>emptyMap(),
 164                 defaultNamespaceRemap,c14nSupport,null);
 165     }
 166 
 167     /**
 168      * Returns true if this context includes a class
 169      * that has {@link XmlAttachmentRef}.
 170      *
 171      * @since 2.1
 172      */
 173     public abstract boolean hasSwaRef();
 174 
 175     /**
 176      * If the given object is bound to an element in XML by JAXB,
 177      * returns the element name.
 178      *
 179      * @return null
 180      *      if the object is not bound to an element.
 181      * @throws JAXBException
 182      *      if the object is not known to this context.
 183      *
 184      * @since 2.0 EA1
 185      */
 186     public abstract @Nullable QName getElementName(@NotNull Object o) throws JAXBException;
 187 
 188     /**
 189      * Allows to retrieve the element name based on Class.
 190      * @param o
 191      * @return
 192      * @throws javax.xml.bind.JAXBException
 193      * @since 2.1.10
 194      */
 195     public abstract @Nullable QName getElementName(@NotNull Class o) throws JAXBException;
 196 
 197     /**
 198      * Creates a mini-marshaller/unmarshaller that can process a {@link TypeReference}.
 199      *
 200      * @return
 201      *      null if the specified reference is not given to {@link JAXBRIContext#newInstance}.
 202      *
 203      * @since 2.0 EA1
 204      */
 205     public abstract Bridge createBridge(@NotNull TypeReference ref);
 206 
 207     /**
 208      * Creates a new {@link BridgeContext} instance.
 209      *
 210      * @return
 211      *      always a valid non-null instance.
 212      *
 213      * @since 2.0 EA1
 214      */
 215     public abstract @NotNull BridgeContext createBridgeContext();
 216 
 217     /**
 218      * Gets a {@link RawAccessor} for the specified element property of the specified wrapper bean class.
 219      *
 220      * <p>
 221      * This method is designed to assist the JAX-RPC RI fill in a wrapper bean (in the doc/lit/wrap mode.)
 222      * In the said mode, a wrapper bean is supposed to only have properties that match elements,
 223      * and for each element that appear in the content model there's one property.
 224      *
 225      * <p>
 226      * Therefore, this method takes a wrapper bean and a tag name that identifies a property
 227      * on the given wrapper bean, then returns a {@link RawAccessor} that allows the caller
 228      * to set/get a value from the property of the bean.
 229      *
 230      * <p>
 231      * This method is not designed for a performance. The caller is expected to cache the result.
 232      *
 233      * @param <B>
 234      *      type of the wrapper bean
 235      * @param <V>
 236      *      type of the property of the bean
 237      * @return
 238      *      always return non-null valid accessor object.
 239      * @throws JAXBException
 240      *      if the specified wrapper bean is not bound by JAXB, or if it doesn't have an element property
 241      *      of the given name.
 242      *
 243      * @since 2.0 EA1
 244      */
 245     public abstract <B,V> RawAccessor<B,V> getElementPropertyAccessor( Class<B> wrapperBean, String nsUri, String localName )
 246             throws JAXBException;
 247 
 248     /**
 249      * Gets the namespace URIs statically known to this {@link JAXBContext}.
 250      *
 251      * <p>
 252      * When JAXB is used to marshal into sub-trees, it declares
 253      * these namespace URIs at each top-level element that it marshals.
 254      *
 255      * To avoid repeated namespace declarations at sub-elements, the application
 256      * may declare those namespaces at a higher level.
 257      *
 258      * @return
 259      *      always non-null.
 260      *
 261      * @since 2.0 EA2
 262      */
 263     public abstract @NotNull List<String> getKnownNamespaceURIs();
 264 
 265 
 266     /**
 267      * Generates the schema documents from the model.
 268      *
 269      * <p>
 270      * The caller can use the additionalElementDecls parameter to
 271      * add element declarations to the generate schema.
 272      * For example, if the JAX-RPC passes in the following entry:
 273      *
 274      * {foo}bar -> DeclaredType for java.lang.String
 275      *
 276      * then JAXB generates the following element declaration (in the schema
 277      * document for the namespace "foo")"
 278      *
 279      * &lt;xs:element name="bar" type="xs:string" />
 280      *
 281      * This can be used for generating schema components necessary for WSDL.
 282      *
 283      * @param outputResolver
 284      *      this object controls the output to which schemas
 285      *      will be sent.
 286      *
 287      * @throws IOException
 288      *      if {@link SchemaOutputResolver} throws an {@link IOException}.
 289      */
 290     @Override
 291     public abstract void generateSchema(@NotNull SchemaOutputResolver outputResolver) throws IOException;
 292 
 293     /**
 294      * Returns the name of the XML Type bound to the
 295      * specified Java type.
 296      *
 297      * @param tr
 298      *      must not be null. This must be one of the {@link TypeReference}s specified
 299      *      in the {@link JAXBRIContext#newInstance} method.
 300      *
 301      * @throws IllegalArgumentException
 302      *      if the parameter is null or not a part of the {@link TypeReference}s specified
 303      *      in the {@link JAXBRIContext#newInstance} method.
 304      *
 305      * @return null
 306      *      if the referenced type is an anonymous and therefore doesn't have a name.
 307      */
 308     public abstract QName getTypeName(@NotNull TypeReference tr);
 309 
 310     /**
 311      * Gets the build information of the JAXB runtime.
 312      *
 313      * @return
 314      *      may be null, if the runtime is loaded by a class loader that doesn't support
 315      *      the access to the manifest informatino.
 316      */
 317     public abstract @NotNull String getBuildId();
 318 
 319     /**
 320      * Generates the episode file that represents the binding known to this {@link JAXBContext},
 321      * so that XJC can later do separate compilation.
 322      *
 323      * <p>
 324      * Episode file is really just a JAXB customization file, except that currently
 325      * we use the RI-specific SCD to refer to schema components.
 326      *
 327      * @param output
 328      *      This receives the generated episode file.
 329      *
 330      * @since 2.1
 331      */
 332     public abstract void generateEpisode(Result output);
 333 
 334     /**
 335      * Allows you to access the runtime model information of the JAXB XML/Java binding.
 336      *
 337      * <p>
 338      * This is useful for doing a deeper integration with the JAXB RI.
 339      * For more information about the model, see https://jaxb2-reflection.dev.java.net/
 340      *
 341      * @since 2.1.10
 342      */
 343     public abstract RuntimeTypeInfoSet getRuntimeTypeInfoSet();
 344 
 345     /**
 346      * Computes a Java identifier from a local name.
 347      *
 348      * <p>
 349      * This method faithfully implements the name mangling rule as specified in the JAXB spec.
 350      *
 351      * <p>
 352      * In JAXB, a collision with a Java reserved word (such as "return") never happens.
 353      * Accordingly, this method may return an identifier that collides with reserved words.
 354      *
 355      * <p>
 356      * Use <tt>JJavaName.isJavaIdentifier(String)</tt> to check for such collision.
 357      *
 358      * @return
 359      *      Typically, this method returns "nameLikeThis".
 360      */
 361     public static @NotNull String mangleNameToVariableName(@NotNull String localName) {
 362         return NameConverter.standard.toVariableName(localName);
 363     }
 364 
 365     /**
 366      * Computes a Java class name from a local name.
 367      *
 368      * <p>
 369      * This method faithfully implements the name mangling rule as specified in the JAXB spec.
 370      *
 371      * @return
 372      *      Typically, this method returns "NameLikeThis".
 373      */
 374     public static @NotNull String mangleNameToClassName(@NotNull String localName) {
 375         return NameConverter.standard.toClassName(localName);
 376     }
 377 
 378     /**
 379      * Computes a Java class name from a local name.
 380      *
 381      * <p>
 382      * This method faithfully implements the name mangling rule as specified in the JAXB spec.
 383      * This method works like {@link #mangleNameToClassName(String)} except that it looks
 384      * for "getClass" and returns something else.
 385      *
 386      * @return
 387      *      Typically, this method returns "NameLikeThis".
 388      */
 389     public static @NotNull String mangleNameToPropertyName(@NotNull String localName) {
 390         return NameConverter.standard.toPropertyName(localName);
 391     }
 392 
 393     /**
 394      * Gets the parameterization of the given base type.
 395      *
 396      * <p>
 397      * For example, given the following
 398      * <pre><xmp>
 399      * interface Foo<T> extends List<List<T>> {}
 400      * interface Bar extends Foo<String> {}
 401      * </xmp></pre>
 402      * This method works like this:
 403      * <pre><xmp>
 404      * getBaseClass( Bar, List ) = List<List<String>
 405      * getBaseClass( Bar, Foo  ) = Foo<String>
 406      * getBaseClass( Foo<? extends Number>, Collection ) = Collection<List<? extends Number>>
 407      * getBaseClass( ArrayList<? extends BigInteger>, List ) = List<? extends BigInteger>
 408      * </xmp></pre>
 409      *
 410      * @param type
 411      *      The type that derives from {@code baseType}
 412      * @param baseType
 413      *      The class whose parameterization we are interested in.
 414      * @return
 415      *      The use of {@code baseType} in {@code type}.
 416      *      or null if the type is not assignable to the base type.
 417      * @since 2.0 FCS
 418      */
 419     public static @Nullable Type getBaseType(@NotNull Type type, @NotNull Class baseType) {
 420         return Navigator.REFLECTION.getBaseClass(type,baseType);
 421     }
 422 
 423     /**
 424      * The property that you can specify to {@link JAXBContext#newInstance}
 425      * to reassign the default namespace URI to something else at the runtime.
 426      *
 427      * <p>
 428      * The value of the property is {@link String}, and it is used as the namespace URI
 429      * that succeeds the default namespace URI.
 430      *
 431      * @since 2.0 EA1
 432      */
 433     public static final String DEFAULT_NAMESPACE_REMAP = "com.sun.xml.internal.bind.defaultNamespaceRemap";
 434 
 435     /**
 436      * The property that you can specify to {@link JAXBContext#newInstance}
 437      * to put additional JAXB type references into the {@link JAXBContext}.
 438      *
 439      * <p>
 440      * The value of the property is {@link Collection}&lt;{@link TypeReference}>.
 441      * Those {@link TypeReference}s can then be used to create {@link Bridge}s.
 442      *
 443      * <p>
 444      * This mechanism allows additional element declarations that were not a part of
 445      * the schema into the created {@link JAXBContext}.
 446      *
 447      * @since 2.0 EA1
 448      */
 449     public static final String TYPE_REFERENCES = "com.sun.xml.internal.bind.typeReferences";
 450 
 451     /**
 452      * The property that you can specify to {@link JAXBContext#newInstance}
 453      * and {@link Marshaller#setProperty(String, Object)}
 454      * to enable the c14n marshalling support in the {@link JAXBContext}.
 455      *
 456      * Boolean
 457      * @see C14nSupport_ArchitectureDocument
 458      * @since 2.0 EA2
 459      */
 460     public static final String CANONICALIZATION_SUPPORT = "com.sun.xml.internal.bind.c14n";
 461 
 462     /**
 463      * The property that you can specify to {@link JAXBContext#newInstance}
 464      * to allow unmarshaller to honor <tt>xsi:nil</tt> anywhere, even if they are
 465      * not specifically allowed by the schema.
 466      *
 467      * Boolean
 468      * @since 2.1.3
 469      */
 470     public static final String TREAT_EVERYTHING_NILLABLE = "com.sun.xml.internal.bind.treatEverythingNillable";
 471 
 472     /**
 473      * The property that you can specify to {@link JAXBContext#newInstance}
 474      * to use alternative {@link RuntimeAnnotationReader} implementation.
 475      *
 476      * @since 2.1 EA2
 477      */
 478     public static final String ANNOTATION_READER = RuntimeAnnotationReader.class.getName();
 479 
 480     /**
 481      * Marshaller/Unmarshaller property to enable XOP processing.
 482      *
 483      * @since 2.0 EA2
 484      */
 485     public static final String ENABLE_XOP = "com.sun.xml.internal.bind.XOP";
 486 
 487     /**
 488      * The property that you can specify to {@link JAXBContext#newInstance}
 489      * to specify specific classes that replace the reference to generic classes.
 490      *
 491      * <p>
 492      * See the release notes for more details about this feature.
 493      *
 494      * @since 2.1 EA2
 495      */
 496     public static final String SUBCLASS_REPLACEMENTS = "com.sun.xml.internal.bind.subclassReplacements";
 497 
 498     /**
 499      * The property that you can specify to {@link JAXBContext#newInstance}
 500      * enable support of XmlAccessorFactory annotation in the {@link JAXBContext}.
 501      *
 502      * @since 2.1 EA2
 503      */
 504     public static final String XMLACCESSORFACTORY_SUPPORT = "com.sun.xml.internal.bind.XmlAccessorFactory";
 505 
 506     /**
 507      * Retains references to PropertyInfos.
 508      *
 509      * Boolean
 510      * @since 2.1.10
 511      */
 512     public static final String RETAIN_REFERENCE_TO_INFO = "retainReferenceToInfo";
 513 
 514     /**
 515      * Supress security warnings when trying to access fields through reflection.
 516      *
 517      * Boolean
 518      * @since 2.1.14, 2.2.2
 519      */
 520     public static final String SUPRESS_ACCESSOR_WARNINGS = "supressAccessorWarnings";
 521 
 522     /**
 523      * Improves handling of xsi:type used on leaf properties.
 524      *
 525      * Boolean
 526      * @since 2.2.3
 527      */
 528     public static final String IMPROVED_XSI_TYPE_HANDLING = "com.sun.xml.internal.bind.improvedXsiTypeHandling";
 529 
 530     /**
 531      * If true XML security features when parsing XML documents will be disabled.
 532      * The default value is false.
 533      *
 534      * Boolean
 535      * @since 2.2.6
 536      */
 537     public static final String DISABLE_XML_SECURITY  = "com.sun.xml.internal.bind.disableXmlSecurity";
 538 }