View Javadoc
1   /*
2    * Copyright (c) 1997, 2011, 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><xmp>
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      * </xmp></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><xmp>
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      * </xmp></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><xmp>
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      * </xmp></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 }