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