aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.bind.marshaller; aoqi@0: aoqi@0: import java.io.OutputStream; aoqi@0: aoqi@0: import javax.xml.bind.JAXBContext; aoqi@0: import javax.xml.stream.XMLEventWriter; aoqi@0: import javax.xml.stream.XMLStreamWriter; aoqi@0: import javax.xml.transform.dom.DOMResult; aoqi@0: aoqi@0: import org.w3c.dom.Node; aoqi@0: aoqi@0: // be careful about changing this class. this class is supposed to be aoqi@0: // extended by users and therefore we are not allowed to break aoqi@0: // those user code. aoqi@0: // aoqi@0: // this means: aoqi@0: // - don't add any abstract method aoqi@0: // - don't change any existing method signature aoqi@0: // - don't remove any existing method. aoqi@0: aoqi@0: /** aoqi@0: * Implemented by the user application to determine URI -> prefix aoqi@0: * mapping. aoqi@0: * aoqi@0: * This is considered as an interface, though it's implemented aoqi@0: * as an abstract class to make it easy to add new methods in aoqi@0: * a future. aoqi@0: * aoqi@0: * @author aoqi@0: * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) aoqi@0: */ aoqi@0: public abstract class NamespacePrefixMapper { aoqi@0: aoqi@0: private static final String[] EMPTY_STRING = new String[0]; aoqi@0: aoqi@0: /** aoqi@0: * Returns a preferred prefix for the given namespace URI. aoqi@0: * aoqi@0: * This method is intended to be overrided by a derived class. aoqi@0: * aoqi@0: *

aoqi@0: * As noted in the return value portion of the javadoc, there aoqi@0: * are several cases where the preference cannot be honored. aoqi@0: * Specifically, as of JAXB RI 2.0 and onward: aoqi@0: * aoqi@0: *

    aoqi@0: *
  1. aoqi@0: * If the prefix returned is already in use as one of the in-scope aoqi@0: * namespace bindings. This is partly necessary for correctness aoqi@0: * (so that we don't unexpectedly change the meaning of QNames aoqi@0: * bound to {@link String}), partly to simplify the marshaller. aoqi@0: *
  2. aoqi@0: * If the prefix returned is "" yet the current {@link JAXBContext} aoqi@0: * includes classes that use the empty namespace URI. This allows aoqi@0: * the JAXB RI to reserve the "" prefix for the empty namespace URI, aoqi@0: * which is the only possible prefix for the URI. aoqi@0: * This restriction is also to simplify the marshaller. aoqi@0: *
aoqi@0: * aoqi@0: * @param namespaceUri aoqi@0: * The namespace URI for which the prefix needs to be found. aoqi@0: * Never be null. "" is used to denote the default namespace. aoqi@0: * @param suggestion aoqi@0: * When the content tree has a suggestion for the prefix aoqi@0: * to the given namespaceUri, that suggestion is passed as a aoqi@0: * parameter. Typicall this value comes from the QName.getPrefix aoqi@0: * to show the preference of the content tree. This parameter aoqi@0: * may be null, and this parameter may represent an already aoqi@0: * occupied prefix. aoqi@0: * @param requirePrefix aoqi@0: * If this method is expected to return non-empty prefix. aoqi@0: * When this flag is true, it means that the given namespace URI aoqi@0: * cannot be set as the default namespace. aoqi@0: * aoqi@0: * @return aoqi@0: * null if there's no prefered prefix for the namespace URI. aoqi@0: * In this case, the system will generate a prefix for you. aoqi@0: * aoqi@0: * Otherwise the system will try to use the returned prefix, aoqi@0: * but generally there's no guarantee if the prefix will be aoqi@0: * actually used or not. aoqi@0: * aoqi@0: * return "" to map this namespace URI to the default namespace. aoqi@0: * Again, there's no guarantee that this preference will be aoqi@0: * honored. aoqi@0: * aoqi@0: * If this method returns "" when requirePrefix=true, the return aoqi@0: * value will be ignored and the system will generate one. aoqi@0: * aoqi@0: * @since JAXB 1.0.1 aoqi@0: */ aoqi@0: public abstract String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix); aoqi@0: aoqi@0: /** aoqi@0: * Returns a list of namespace URIs that should be declared aoqi@0: * at the root element. aoqi@0: * aoqi@0: *

aoqi@0: * By default, the JAXB RI 1.0.x produces namespace declarations only when aoqi@0: * they are necessary, only at where they are used. Because of this aoqi@0: * lack of look-ahead, sometimes the marshaller produces a lot of aoqi@0: * namespace declarations that look redundant to human eyes. For example, aoqi@0: *


aoqi@0:      * <?xml version="1.0"?>
aoqi@0:      * <root>
aoqi@0:      *   <ns1:child xmlns:ns1="urn:foo"> ... </ns1:child>
aoqi@0:      *   <ns2:child xmlns:ns2="urn:foo"> ... </ns2:child>
aoqi@0:      *   <ns3:child xmlns:ns3="urn:foo"> ... </ns3:child>
aoqi@0:      *   ...
aoqi@0:      * </root>
aoqi@0:      * 
aoqi@0: * aoqi@0: *

aoqi@0: * The JAXB RI 2.x mostly doesn't exhibit this behavior any more, aoqi@0: * as it declares all statically known namespace URIs (those URIs aoqi@0: * that are used as element/attribute names in JAXB annotations), aoqi@0: * but it may still declare additional namespaces in the middle of aoqi@0: * a document, for example when (i) a QName as an attribute/element value aoqi@0: * requires a new namespace URI, or (ii) DOM nodes as a portion of an object aoqi@0: * tree requires a new namespace URI. aoqi@0: * aoqi@0: *

aoqi@0: * If you know in advance that you are going to use a certain set of aoqi@0: * namespace URIs, you can override this method and have the marshaller aoqi@0: * declare those namespace URIs at the root element. aoqi@0: * aoqi@0: *

aoqi@0: * For example, by returning new String[]{"urn:foo"}, aoqi@0: * the marshaller will produce: aoqi@0: *


aoqi@0:      * <?xml version="1.0"?>
aoqi@0:      * <root xmlns:ns1="urn:foo">
aoqi@0:      *   <ns1:child> ... </ns1:child>
aoqi@0:      *   <ns1:child> ... </ns1:child>
aoqi@0:      *   <ns1:child> ... </ns1:child>
aoqi@0:      *   ...
aoqi@0:      * </root>
aoqi@0:      * 
aoqi@0: *

aoqi@0: * To control prefixes assigned to those namespace URIs, use the aoqi@0: * {@link #getPreferredPrefix(String, String, boolean)} method. aoqi@0: * aoqi@0: * @return aoqi@0: * A list of namespace URIs as an array of {@link String}s. aoqi@0: * This method can return a length-zero array but not null. aoqi@0: * None of the array component can be null. To represent aoqi@0: * the empty namespace, use the empty string "". aoqi@0: * aoqi@0: * @since aoqi@0: * JAXB RI 1.0.2 aoqi@0: */ aoqi@0: public String[] getPreDeclaredNamespaceUris() { aoqi@0: return EMPTY_STRING; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Similar to {@link #getPreDeclaredNamespaceUris()} but allows the aoqi@0: * (prefix,nsUri) pairs to be returned. aoqi@0: * aoqi@0: *

aoqi@0: * With {@link #getPreDeclaredNamespaceUris()}, applications who wish to control aoqi@0: * the prefixes as well as the namespaces needed to implement both aoqi@0: * {@link #getPreDeclaredNamespaceUris()} and {@link #getPreferredPrefix(String, String, boolean)}. aoqi@0: * aoqi@0: *

aoqi@0: * This version eliminates the needs by returning an array of pairs. aoqi@0: * aoqi@0: * @return aoqi@0: * always return a non-null (but possibly empty) array. The array stores aoqi@0: * data like (prefix1,nsUri1,prefix2,nsUri2,...) Use an empty string to represent aoqi@0: * the empty namespace URI and the default prefix. Null is not allowed as a value aoqi@0: * in the array. aoqi@0: * aoqi@0: * @since aoqi@0: * JAXB RI 2.0 beta aoqi@0: */ aoqi@0: public String[] getPreDeclaredNamespaceUris2() { aoqi@0: return EMPTY_STRING; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Returns a list of (prefix,namespace URI) pairs that represents aoqi@0: * namespace bindings available on ancestor elements (that need not be repeated aoqi@0: * by the JAXB RI.) aoqi@0: * aoqi@0: *

aoqi@0: * Sometimes JAXB is used to marshal an XML document, which will be aoqi@0: * used as a subtree of a bigger document. When this happens, it's nice aoqi@0: * for a JAXB marshaller to be able to use in-scope namespace bindings aoqi@0: * of the larger document and avoid declaring redundant namespace URIs. aoqi@0: * aoqi@0: *

aoqi@0: * This is automatically done when you are marshalling to {@link XMLStreamWriter}, aoqi@0: * {@link XMLEventWriter}, {@link DOMResult}, or {@link Node}, because aoqi@0: * those output format allows us to inspect what's currently available aoqi@0: * as in-scope namespace binding. However, with other output format, aoqi@0: * such as {@link OutputStream}, the JAXB RI cannot do this automatically. aoqi@0: * That's when this method comes into play. aoqi@0: * aoqi@0: *

aoqi@0: * Namespace bindings returned by this method will be used by the JAXB RI, aoqi@0: * but will not be re-declared. They are assumed to be available when you insert aoqi@0: * this subtree into a bigger document. aoqi@0: * aoqi@0: *

aoqi@0: * It is NOT OK to return the same binding, or give aoqi@0: * the receiver a conflicting binding information. aoqi@0: * It's a responsibility of the caller to make sure that this doesn't happen aoqi@0: * even if the ancestor elements look like: aoqi@0: *


aoqi@0:      *   <foo:abc xmlns:foo="abc">
aoqi@0:      *     <foo:abc xmlns:foo="def">
aoqi@0:      *       <foo:abc xmlns:foo="abc">
aoqi@0:      *         ... JAXB marshalling into here.
aoqi@0:      *       </foo:abc>
aoqi@0:      *     </foo:abc>
aoqi@0:      *   </foo:abc>
aoqi@0:      * 
aoqi@0: * aoqi@0: * @return aoqi@0: * always return a non-null (but possibly empty) array. The array stores aoqi@0: * data like (prefix1,nsUri1,prefix2,nsUri2,...) Use an empty string to represent aoqi@0: * the empty namespace URI and the default prefix. Null is not allowed as a value aoqi@0: * in the array. aoqi@0: * aoqi@0: * @since JAXB RI 2.0 beta aoqi@0: */ aoqi@0: public String[] getContextualNamespaceDecls() { aoqi@0: return EMPTY_STRING; aoqi@0: } aoqi@0: }