1 /*
   2  * Copyright (c) 1997, 2012, 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.marshaller;
  27 
  28 import java.io.OutputStream;
  29 
  30 import javax.xml.bind.JAXBContext;
  31 import javax.xml.stream.XMLEventWriter;
  32 import javax.xml.stream.XMLStreamWriter;
  33 import javax.xml.transform.dom.DOMResult;
  34 
  35 import org.w3c.dom.Node;
  36 
  37 // be careful about changing this class. this class is supposed to be
  38 // extended by users and therefore we are not allowed to break
  39 // those user code.
  40 //
  41 // this means:
  42 // - don't add any abstract method
  43 // - don't change any existing method signature
  44 // - don't remove any existing method.
  45 
  46 /**
  47  * Implemented by the user application to determine URI -> prefix
  48  * mapping.
  49  *
  50  * This is considered as an interface, though it's implemented
  51  * as an abstract class to make it easy to add new methods in
  52  * a future.
  53  *
  54  * @author
  55  *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  56  */
  57 public abstract class NamespacePrefixMapper {
  58 
  59     private static final String[] EMPTY_STRING = new String[0];
  60 
  61     /**
  62      * Returns a preferred prefix for the given namespace URI.
  63      *
  64      * This method is intended to be overrided by a derived class.
  65      *
  66      * <p>
  67      * As noted in the return value portion of the javadoc, there
  68      * are several cases where the preference cannot be honored.
  69      * Specifically, as of JAXB RI 2.0 and onward:
  70      *
  71      * <ol>
  72      * <li>
  73      * If the prefix returned is already in use as one of the in-scope
  74      * namespace bindings. This is partly necessary for correctness
  75      * (so that we don't unexpectedly change the meaning of QNames
  76      * bound to {@link String}), partly to simplify the marshaller.
  77      * <li>
  78      * If the prefix returned is "" yet the current {@link JAXBContext}
  79      * includes classes that use the empty namespace URI. This allows
  80      * the JAXB RI to reserve the "" prefix for the empty namespace URI,
  81      * which is the only possible prefix for the URI.
  82      * This restriction is also to simplify the marshaller.
  83      * </ol>
  84      *
  85      * @param namespaceUri
  86      *      The namespace URI for which the prefix needs to be found.
  87      *      Never be null. "" is used to denote the default namespace.
  88      * @param suggestion
  89      *      When the content tree has a suggestion for the prefix
  90      *      to the given namespaceUri, that suggestion is passed as a
  91      *      parameter. Typicall this value comes from the QName.getPrefix
  92      *      to show the preference of the content tree. This parameter
  93      *      may be null, and this parameter may represent an already
  94      *      occupied prefix.
  95      * @param requirePrefix
  96      *      If this method is expected to return non-empty prefix.
  97      *      When this flag is true, it means that the given namespace URI
  98      *      cannot be set as the default namespace.
  99      *
 100      * @return
 101      *      null if there's no prefered prefix for the namespace URI.
 102      *      In this case, the system will generate a prefix for you.
 103      *
 104      *      Otherwise the system will try to use the returned prefix,
 105      *      but generally there's no guarantee if the prefix will be
 106      *      actually used or not.
 107      *
 108      *      return "" to map this namespace URI to the default namespace.
 109      *      Again, there's no guarantee that this preference will be
 110      *      honored.
 111      *
 112      *      If this method returns "" when requirePrefix=true, the return
 113      *      value will be ignored and the system will generate one.
 114      *
 115      * @since JAXB 1.0.1
 116      */
 117     public abstract String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix);
 118 
 119     /**
 120      * Returns a list of namespace URIs that should be declared
 121      * at the root element.
 122      *
 123      * <p>
 124      * By default, the JAXB RI 1.0.x produces namespace declarations only when
 125      * they are necessary, only at where they are used. Because of this
 126      * lack of look-ahead, sometimes the marshaller produces a lot of
 127      * namespace declarations that look redundant to human eyes. For example,
 128      * <pre>{@code
 129      * <?xml version="1.0"?>
 130      * <root>
 131      *   <ns1:child xmlns:ns1="urn:foo"> ... </ns1:child>
 132      *   <ns2:child xmlns:ns2="urn:foo"> ... </ns2:child>
 133      *   <ns3:child xmlns:ns3="urn:foo"> ... </ns3:child>
 134      *   ...
 135      * </root>
 136      * }</pre>
 137      *
 138      * <p>
 139      * The JAXB RI 2.x mostly doesn't exhibit this behavior any more,
 140      * as it declares all statically known namespace URIs (those URIs
 141      * that are used as element/attribute names in JAXB annotations),
 142      * but it may still declare additional namespaces in the middle of
 143      * a document, for example when (i) a QName as an attribute/element value
 144      * requires a new namespace URI, or (ii) DOM nodes as a portion of an object
 145      * tree requires a new namespace URI.
 146      *
 147      * <p>
 148      * If you know in advance that you are going to use a certain set of
 149      * namespace URIs, you can override this method and have the marshaller
 150      * declare those namespace URIs at the root element.
 151      *
 152      * <p>
 153      * For example, by returning <code>new String[]{"urn:foo"}</code>,
 154      * the marshaller will produce:
 155      * <pre>{@code
 156      * <?xml version="1.0"?>
 157      * <root xmlns:ns1="urn:foo">
 158      *   <ns1:child> ... </ns1:child>
 159      *   <ns1:child> ... </ns1:child>
 160      *   <ns1:child> ... </ns1:child>
 161      *   ...
 162      * </root>
 163      * }</pre>
 164      * <p>
 165      * To control prefixes assigned to those namespace URIs, use the
 166      * {@link #getPreferredPrefix(String, String, boolean)} method.
 167      *
 168      * @return
 169      *      A list of namespace URIs as an array of {@link String}s.
 170      *      This method can return a length-zero array but not null.
 171      *      None of the array component can be null. To represent
 172      *      the empty namespace, use the empty string <code>""</code>.
 173      *
 174      * @since
 175      *      JAXB RI 1.0.2
 176      */
 177     public String[] getPreDeclaredNamespaceUris() {
 178         return EMPTY_STRING;
 179     }
 180 
 181     /**
 182      * Similar to {@link #getPreDeclaredNamespaceUris()} but allows the
 183      * (prefix,nsUri) pairs to be returned.
 184      *
 185      * <p>
 186      * With {@link #getPreDeclaredNamespaceUris()}, applications who wish to control
 187      * the prefixes as well as the namespaces needed to implement both
 188      * {@link #getPreDeclaredNamespaceUris()} and {@link #getPreferredPrefix(String, String, boolean)}.
 189      *
 190      * <p>
 191      * This version eliminates the needs by returning an array of pairs.
 192      *
 193      * @return
 194      *      always return a non-null (but possibly empty) array. The array stores
 195      *      data like (prefix1,nsUri1,prefix2,nsUri2,...) Use an empty string to represent
 196      *      the empty namespace URI and the default prefix. Null is not allowed as a value
 197      *      in the array.
 198      *
 199      * @since
 200      *      JAXB RI 2.0 beta
 201      */
 202     public String[] getPreDeclaredNamespaceUris2() {
 203         return EMPTY_STRING;
 204     }
 205 
 206     /**
 207      * Returns a list of (prefix,namespace URI) pairs that represents
 208      * namespace bindings available on ancestor elements (that need not be repeated
 209      * by the JAXB RI.)
 210      *
 211      * <p>
 212      * Sometimes JAXB is used to marshal an XML document, which will be
 213      * used as a subtree of a bigger document. When this happens, it's nice
 214      * for a JAXB marshaller to be able to use in-scope namespace bindings
 215      * of the larger document and avoid declaring redundant namespace URIs.
 216      *
 217      * <p>
 218      * This is automatically done when you are marshalling to {@link XMLStreamWriter},
 219      * {@link XMLEventWriter}, {@link DOMResult}, or {@link Node}, because
 220      * those output format allows us to inspect what's currently available
 221      * as in-scope namespace binding. However, with other output format,
 222      * such as {@link OutputStream}, the JAXB RI cannot do this automatically.
 223      * That's when this method comes into play.
 224      *
 225      * <p>
 226      * Namespace bindings returned by this method will be used by the JAXB RI,
 227      * but will not be re-declared. They are assumed to be available when you insert
 228      * this subtree into a bigger document.
 229      *
 230      * <p>
 231      * It is <b>NOT</b> OK to return  the same binding, or give
 232      * the receiver a conflicting binding information.
 233      * It's a responsibility of the caller to make sure that this doesn't happen
 234      * even if the ancestor elements look like:
 235      * <pre>{@code
 236      *   <foo:abc xmlns:foo="abc">
 237      *     <foo:abc xmlns:foo="def">
 238      *       <foo:abc xmlns:foo="abc">
 239      *         ... JAXB marshalling into here.
 240      *       </foo:abc>
 241      *     </foo:abc>
 242      *   </foo:abc>
 243      * }</pre>
 244      *
 245      * @return
 246      *      always return a non-null (but possibly empty) array. The array stores
 247      *      data like (prefix1,nsUri1,prefix2,nsUri2,...) Use an empty string to represent
 248      *      the empty namespace URI and the default prefix. Null is not allowed as a value
 249      *      in the array.
 250      *
 251      * @since JAXB RI 2.0 beta
 252      */
 253     public String[] getContextualNamespaceDecls() {
 254         return EMPTY_STRING;
 255     }
 256 }