src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/stax/NamespaceContexHelper.java

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     1 /*
     2  * Copyright (c) 2005, 2010, 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  */
    26 package com.sun.xml.internal.stream.buffer.stax;
    28 import java.util.ArrayList;
    29 import java.util.Collections;
    30 import java.util.Iterator;
    31 import java.util.List;
    32 import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
    34 /**
    35  * A helper class for managing the declaration of namespaces.
    36  * <p>
    37  * A namespace is declared on a namespace context.
    38  * Namespace contexts are pushed on and popped off the namespace context stack.
    39  * <p>
    40  * A declared namespace will be in scope iff the context that it was declared on
    41  * has not been popped off the stack.
    42  * <p>
    43  * When instantiated the namespace stack consists of the root namespace context,
    44  * which contains, by default, the "xml" and "xmlns" declarations.
    45  * Namespaces may be declarations may be declared on the root context.
    46  * The root context cannot be popped but can be reset to contain just the
    47  * "xml" and "xmlns" declarations.
    48  * <p>
    49  * Implementation note: determining the prefix from a namespace URI
    50  * (or vice versa) is efficient when there are few namespace
    51  * declarations i.e. what is considered to be the case for namespace
    52  * declarations in 'average' XML documents. The look up of a namespace URI
    53  * given a prefix is performed in O(n) time. The look up of a prefix given
    54  * a namespace URI is performed in O(2n) time.
    55  * <p>
    56  * The implementation does not scale when there are many namespace
    57  * declarations. TODO: Use a hash map when there are many namespace
    58  * declarations.
    59  *
    60  * @author Paul.Sandoz@Sun.Com
    61  */
    62 final public class NamespaceContexHelper implements NamespaceContextEx {
    63     private static int DEFAULT_SIZE = 8;
    65     // The prefixes of the namespace declarations
    66     private String[] prefixes = new String[DEFAULT_SIZE];
    67     // The URIs of the namespace declarations
    68     private String[] namespaceURIs = new String[DEFAULT_SIZE];
    69     // Current position to store the next namespace declaration
    70     private int namespacePosition;
    72     // The namespace contexts
    73     private int[] contexts = new int[DEFAULT_SIZE];
    74     // Current position to store the next namespace context
    75     private int contextPosition;
    77     // The current namespace context
    78     private int currentContext;
    80     /**
    81      * Create a new NamespaceContexHelper.
    82      *
    83      */
    84     public NamespaceContexHelper() {
    85         // The default namespace declarations that are always in scope
    86         prefixes[0] = "xml";
    87         namespaceURIs[0] = "http://www.w3.org/XML/1998/namespace";
    88         prefixes[1] = "xmlns";
    89         namespaceURIs[1] = "http://www.w3.org/2000/xmlns/";
    91         currentContext = namespacePosition = 2;
    92     }
    95     // NamespaceContext interface
    97     public String getNamespaceURI(String prefix) {
    98         if (prefix == null) throw new IllegalArgumentException();
   100         prefix = prefix.intern();
   102         for (int i = namespacePosition - 1; i >= 0; i--) {
   103             final String declaredPrefix = prefixes[i];
   104             if (declaredPrefix == prefix) {
   105                 return namespaceURIs[i];
   106             }
   107         }
   109         return "";
   110     }
   112     public String getPrefix(String namespaceURI) {
   113         if (namespaceURI == null) throw new IllegalArgumentException();
   115         for (int i = namespacePosition - 1; i >= 0; i--) {
   116             final String declaredNamespaceURI = namespaceURIs[i];
   117             if (declaredNamespaceURI == namespaceURI || declaredNamespaceURI.equals(namespaceURI)) {
   118                 final String declaredPrefix = prefixes[i];
   120                 // Check if prefix is out of scope
   121                 for (++i; i < namespacePosition; i++)
   122                     if (declaredPrefix == prefixes[i])
   123                         return null;
   125                 return declaredPrefix;
   126             }
   127         }
   129         return null;
   130     }
   132     public Iterator getPrefixes(String namespaceURI) {
   133         if (namespaceURI == null) throw new IllegalArgumentException();
   135         List<String> l = new ArrayList<String>();
   137         NAMESPACE_LOOP: for (int i = namespacePosition - 1; i >= 0; i--) {
   138             final String declaredNamespaceURI = namespaceURIs[i];
   139             if (declaredNamespaceURI == namespaceURI || declaredNamespaceURI.equals(namespaceURI)) {
   140                 final String declaredPrefix = prefixes[i];
   142                 // Check if prefix is out of scope
   143                 for (int j = i + 1; j < namespacePosition; j++)
   144                     if (declaredPrefix == prefixes[j])
   145                         continue NAMESPACE_LOOP;
   147                 l.add(declaredPrefix);
   148             }
   149         }
   151         return l.iterator();
   152     }
   154     // NamespaceContextEx interface
   156     public Iterator<NamespaceContextEx.Binding> iterator() {
   157         if (namespacePosition == 2)
   158             return Collections.EMPTY_LIST.iterator();
   160         final List<NamespaceContextEx.Binding> namespaces =
   161                 new ArrayList<NamespaceContextEx.Binding>(namespacePosition);
   163         NAMESPACE_LOOP: for (int i = namespacePosition - 1; i >= 2; i--) {
   164             final String declaredPrefix = prefixes[i];
   166             // Check if prefix is out of scope
   167             for (int j = i + 1; j < namespacePosition; j++) {
   168                 if (declaredPrefix == prefixes[j])
   169                     continue NAMESPACE_LOOP;
   171                 namespaces.add(new NamespaceBindingImpl(i));
   172             }
   173         }
   175         return namespaces.iterator();
   176     }
   178     final private class NamespaceBindingImpl implements NamespaceContextEx.Binding {
   179         int index;
   181         NamespaceBindingImpl(int index) {
   182             this.index = index;
   183         }
   185         public String getPrefix() {
   186             return prefixes[index];
   187         }
   189         public String getNamespaceURI() {
   190             return namespaceURIs[index];
   191         }
   192     }
   194     /**
   195      * Declare a default namespace.
   196      * <p>
   197      * @param namespaceURI the namespace URI to declare, may be null.
   198      */
   199     public void declareDefaultNamespace(String namespaceURI) {
   200         declareNamespace("", namespaceURI);
   201     }
   203     /**
   204      * Declare a namespace.
   205      * <p>
   206      * The namespace will be declared on the current namespace context.
   207      * <p>
   208      * The namespace can be removed by popping the current namespace
   209      * context, or, if the declaration occured in the root context, by
   210      * reseting the namespace context.
   211      * <p>
   212      * A default namespace can be declared by passing <code>""</code> as
   213      * the value of the prefix parameter.
   214      * A namespace may be undeclared by passing <code>null</code> as the
   215      * value of the namespaceURI parameter.
   216      * <p>
   217      * @param prefix the namespace prefix to declare, may not be null.
   218      * @param namespaceURI the namespace URI to declare, may be null.
   219      * @throws IllegalArgumentException, if the prefix is null.
   220      */
   221     public void declareNamespace(String prefix, String namespaceURI) {
   222         if (prefix == null) throw new IllegalArgumentException();
   224         prefix = prefix.intern();
   225         // Ignore the "xml" or "xmlns" declarations
   226         if (prefix == "xml" || prefix == "xmlns")
   227             return;
   229         // Check for undeclaration
   230         if (namespaceURI != null)
   231             namespaceURI = namespaceURI.intern();
   233         if (namespacePosition == namespaceURIs.length)
   234             resizeNamespaces();
   236         // Add new declaration
   237         prefixes[namespacePosition] = prefix;
   238         namespaceURIs[namespacePosition++] = namespaceURI;
   239     }
   241     private void resizeNamespaces() {
   242         final int newLength = namespaceURIs.length * 3 / 2 + 1;
   244         String[] newPrefixes = new String[newLength];
   245         System.arraycopy(prefixes, 0, newPrefixes, 0, prefixes.length);
   246         prefixes = newPrefixes;
   248         String[] newNamespaceURIs = new String[newLength];
   249         System.arraycopy(namespaceURIs, 0, newNamespaceURIs, 0, namespaceURIs.length);
   250         namespaceURIs = newNamespaceURIs;
   251     }
   253     /**
   254      * Push a namespace context on the stack.
   255      */
   256     public void pushContext() {
   257         if (contextPosition == contexts.length)
   258             resizeContexts();
   260         contexts[contextPosition++] = currentContext = namespacePosition;
   261     }
   263     private void resizeContexts() {
   264         int[] newContexts = new int[contexts.length * 3 / 2 + 1];
   265         System.arraycopy(contexts, 0, newContexts, 0, contexts.length);
   266         contexts = newContexts;
   267     }
   269     /**
   270      * Pop the namespace context off the stack.
   271      * <p>
   272      * Namespaces declared within the context (to be popped)
   273      * will be removed and no longer be in scope.
   274      */
   275     public void popContext() {
   276         if (contextPosition > 0) {
   277             namespacePosition = currentContext = contexts[--contextPosition];
   278         }
   279     }
   281     /**
   282      * Reset namespace contexts.
   283      * <p>
   284      * Pop all namespace contexts and reset the root context.
   285      */
   286     public void resetContexts() {
   287         currentContext = namespacePosition = 2;
   288     }
   289 }

mercurial