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

Wed, 27 Apr 2016 01:27:09 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:27:09 +0800
changeset 0
373ffda63c9a
child 637
9c07ef4934dd
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.stream.buffer.stax;
aoqi@0 27
aoqi@0 28 import java.util.ArrayList;
aoqi@0 29 import java.util.Collections;
aoqi@0 30 import java.util.Iterator;
aoqi@0 31 import java.util.List;
aoqi@0 32 import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
aoqi@0 33
aoqi@0 34 /**
aoqi@0 35 * A helper class for managing the declaration of namespaces.
aoqi@0 36 * <p>
aoqi@0 37 * A namespace is declared on a namespace context.
aoqi@0 38 * Namespace contexts are pushed on and popped off the namespace context stack.
aoqi@0 39 * <p>
aoqi@0 40 * A declared namespace will be in scope iff the context that it was declared on
aoqi@0 41 * has not been popped off the stack.
aoqi@0 42 * <p>
aoqi@0 43 * When instantiated the namespace stack consists of the root namespace context,
aoqi@0 44 * which contains, by default, the "xml" and "xmlns" declarations.
aoqi@0 45 * Namespaces may be declarations may be declared on the root context.
aoqi@0 46 * The root context cannot be popped but can be reset to contain just the
aoqi@0 47 * "xml" and "xmlns" declarations.
aoqi@0 48 * <p>
aoqi@0 49 * Implementation note: determining the prefix from a namespace URI
aoqi@0 50 * (or vice versa) is efficient when there are few namespace
aoqi@0 51 * declarations i.e. what is considered to be the case for namespace
aoqi@0 52 * declarations in 'average' XML documents. The look up of a namespace URI
aoqi@0 53 * given a prefix is performed in O(n) time. The look up of a prefix given
aoqi@0 54 * a namespace URI is performed in O(2n) time.
aoqi@0 55 * <p>
aoqi@0 56 * The implementation does not scale when there are many namespace
aoqi@0 57 * declarations. TODO: Use a hash map when there are many namespace
aoqi@0 58 * declarations.
aoqi@0 59 *
aoqi@0 60 * @author Paul.Sandoz@Sun.Com
aoqi@0 61 */
aoqi@0 62 final public class NamespaceContexHelper implements NamespaceContextEx {
aoqi@0 63 private static int DEFAULT_SIZE = 8;
aoqi@0 64
aoqi@0 65 // The prefixes of the namespace declarations
aoqi@0 66 private String[] prefixes = new String[DEFAULT_SIZE];
aoqi@0 67 // The URIs of the namespace declarations
aoqi@0 68 private String[] namespaceURIs = new String[DEFAULT_SIZE];
aoqi@0 69 // Current position to store the next namespace declaration
aoqi@0 70 private int namespacePosition;
aoqi@0 71
aoqi@0 72 // The namespace contexts
aoqi@0 73 private int[] contexts = new int[DEFAULT_SIZE];
aoqi@0 74 // Current position to store the next namespace context
aoqi@0 75 private int contextPosition;
aoqi@0 76
aoqi@0 77 /**
aoqi@0 78 * Create a new NamespaceContexHelper.
aoqi@0 79 *
aoqi@0 80 */
aoqi@0 81 public NamespaceContexHelper() {
aoqi@0 82 // The default namespace declarations that are always in scope
aoqi@0 83 prefixes[0] = "xml";
aoqi@0 84 namespaceURIs[0] = "http://www.w3.org/XML/1998/namespace";
aoqi@0 85 prefixes[1] = "xmlns";
aoqi@0 86 namespaceURIs[1] = "http://www.w3.org/2000/xmlns/";
aoqi@0 87
aoqi@0 88 namespacePosition = 2;
aoqi@0 89 }
aoqi@0 90
aoqi@0 91
aoqi@0 92 // NamespaceContext interface
aoqi@0 93
aoqi@0 94 public String getNamespaceURI(String prefix) {
aoqi@0 95 if (prefix == null) throw new IllegalArgumentException();
aoqi@0 96
aoqi@0 97 prefix = prefix.intern();
aoqi@0 98
aoqi@0 99 for (int i = namespacePosition - 1; i >= 0; i--) {
aoqi@0 100 final String declaredPrefix = prefixes[i];
aoqi@0 101 if (declaredPrefix == prefix) {
aoqi@0 102 return namespaceURIs[i];
aoqi@0 103 }
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 return "";
aoqi@0 107 }
aoqi@0 108
aoqi@0 109 public String getPrefix(String namespaceURI) {
aoqi@0 110 if (namespaceURI == null) throw new IllegalArgumentException();
aoqi@0 111
aoqi@0 112 for (int i = namespacePosition - 1; i >= 0; i--) {
aoqi@0 113 final String declaredNamespaceURI = namespaceURIs[i];
aoqi@0 114 if (declaredNamespaceURI == namespaceURI || declaredNamespaceURI.equals(namespaceURI)) {
aoqi@0 115 final String declaredPrefix = prefixes[i];
aoqi@0 116
aoqi@0 117 // Check if prefix is out of scope
aoqi@0 118 for (++i; i < namespacePosition; i++)
aoqi@0 119 if (declaredPrefix == prefixes[i])
aoqi@0 120 return null;
aoqi@0 121
aoqi@0 122 return declaredPrefix;
aoqi@0 123 }
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 return null;
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 public Iterator getPrefixes(String namespaceURI) {
aoqi@0 130 if (namespaceURI == null) throw new IllegalArgumentException();
aoqi@0 131
aoqi@0 132 List<String> l = new ArrayList<String>();
aoqi@0 133
aoqi@0 134 NAMESPACE_LOOP: for (int i = namespacePosition - 1; i >= 0; i--) {
aoqi@0 135 final String declaredNamespaceURI = namespaceURIs[i];
aoqi@0 136 if (declaredNamespaceURI == namespaceURI || declaredNamespaceURI.equals(namespaceURI)) {
aoqi@0 137 final String declaredPrefix = prefixes[i];
aoqi@0 138
aoqi@0 139 // Check if prefix is out of scope
aoqi@0 140 for (int j = i + 1; j < namespacePosition; j++)
aoqi@0 141 if (declaredPrefix == prefixes[j])
aoqi@0 142 continue NAMESPACE_LOOP;
aoqi@0 143
aoqi@0 144 l.add(declaredPrefix);
aoqi@0 145 }
aoqi@0 146 }
aoqi@0 147
aoqi@0 148 return l.iterator();
aoqi@0 149 }
aoqi@0 150
aoqi@0 151 // NamespaceContextEx interface
aoqi@0 152
aoqi@0 153 public Iterator<NamespaceContextEx.Binding> iterator() {
aoqi@0 154 if (namespacePosition == 2)
aoqi@0 155 return Collections.EMPTY_LIST.iterator();
aoqi@0 156
aoqi@0 157 final List<NamespaceContextEx.Binding> namespaces =
aoqi@0 158 new ArrayList<NamespaceContextEx.Binding>(namespacePosition);
aoqi@0 159
aoqi@0 160 NAMESPACE_LOOP: for (int i = namespacePosition - 1; i >= 2; i--) {
aoqi@0 161 final String declaredPrefix = prefixes[i];
aoqi@0 162
aoqi@0 163 // Check if prefix is out of scope
aoqi@0 164 for (int j = i + 1; j < namespacePosition; j++) {
aoqi@0 165 if (declaredPrefix == prefixes[j])
aoqi@0 166 continue NAMESPACE_LOOP;
aoqi@0 167
aoqi@0 168 namespaces.add(new NamespaceBindingImpl(i));
aoqi@0 169 }
aoqi@0 170 }
aoqi@0 171
aoqi@0 172 return namespaces.iterator();
aoqi@0 173 }
aoqi@0 174
aoqi@0 175 final private class NamespaceBindingImpl implements NamespaceContextEx.Binding {
aoqi@0 176 int index;
aoqi@0 177
aoqi@0 178 NamespaceBindingImpl(int index) {
aoqi@0 179 this.index = index;
aoqi@0 180 }
aoqi@0 181
aoqi@0 182 public String getPrefix() {
aoqi@0 183 return prefixes[index];
aoqi@0 184 }
aoqi@0 185
aoqi@0 186 public String getNamespaceURI() {
aoqi@0 187 return namespaceURIs[index];
aoqi@0 188 }
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 /**
aoqi@0 192 * Declare a default namespace.
aoqi@0 193 * <p>
aoqi@0 194 * @param namespaceURI the namespace URI to declare, may be null.
aoqi@0 195 */
aoqi@0 196 public void declareDefaultNamespace(String namespaceURI) {
aoqi@0 197 declareNamespace("", namespaceURI);
aoqi@0 198 }
aoqi@0 199
aoqi@0 200 /**
aoqi@0 201 * Declare a namespace.
aoqi@0 202 * <p>
aoqi@0 203 * The namespace will be declared on the current namespace context.
aoqi@0 204 * <p>
aoqi@0 205 * The namespace can be removed by popping the current namespace
aoqi@0 206 * context, or, if the declaration occured in the root context, by
aoqi@0 207 * reseting the namespace context.
aoqi@0 208 * <p>
aoqi@0 209 * A default namespace can be declared by passing <code>""</code> as
aoqi@0 210 * the value of the prefix parameter.
aoqi@0 211 * A namespace may be undeclared by passing <code>null</code> as the
aoqi@0 212 * value of the namespaceURI parameter.
aoqi@0 213 * <p>
aoqi@0 214 * @param prefix the namespace prefix to declare, may not be null.
aoqi@0 215 * @param namespaceURI the namespace URI to declare, may be null.
aoqi@0 216 * @throws IllegalArgumentException, if the prefix is null.
aoqi@0 217 */
aoqi@0 218 public void declareNamespace(String prefix, String namespaceURI) {
aoqi@0 219 if (prefix == null) throw new IllegalArgumentException();
aoqi@0 220
aoqi@0 221 prefix = prefix.intern();
aoqi@0 222 // Ignore the "xml" or "xmlns" declarations
aoqi@0 223 if (prefix == "xml" || prefix == "xmlns")
aoqi@0 224 return;
aoqi@0 225
aoqi@0 226 // Check for undeclaration
aoqi@0 227 if (namespaceURI != null)
aoqi@0 228 namespaceURI = namespaceURI.intern();
aoqi@0 229
aoqi@0 230 if (namespacePosition == namespaceURIs.length)
aoqi@0 231 resizeNamespaces();
aoqi@0 232
aoqi@0 233 // Add new declaration
aoqi@0 234 prefixes[namespacePosition] = prefix;
aoqi@0 235 namespaceURIs[namespacePosition++] = namespaceURI;
aoqi@0 236 }
aoqi@0 237
aoqi@0 238 private void resizeNamespaces() {
aoqi@0 239 final int newLength = namespaceURIs.length * 3 / 2 + 1;
aoqi@0 240
aoqi@0 241 String[] newPrefixes = new String[newLength];
aoqi@0 242 System.arraycopy(prefixes, 0, newPrefixes, 0, prefixes.length);
aoqi@0 243 prefixes = newPrefixes;
aoqi@0 244
aoqi@0 245 String[] newNamespaceURIs = new String[newLength];
aoqi@0 246 System.arraycopy(namespaceURIs, 0, newNamespaceURIs, 0, namespaceURIs.length);
aoqi@0 247 namespaceURIs = newNamespaceURIs;
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 /**
aoqi@0 251 * Push a namespace context on the stack.
aoqi@0 252 */
aoqi@0 253 public void pushContext() {
aoqi@0 254 if (contextPosition == contexts.length)
aoqi@0 255 resizeContexts();
aoqi@0 256
aoqi@0 257 contexts[contextPosition++] = namespacePosition;
aoqi@0 258 }
aoqi@0 259
aoqi@0 260 private void resizeContexts() {
aoqi@0 261 int[] newContexts = new int[contexts.length * 3 / 2 + 1];
aoqi@0 262 System.arraycopy(contexts, 0, newContexts, 0, contexts.length);
aoqi@0 263 contexts = newContexts;
aoqi@0 264 }
aoqi@0 265
aoqi@0 266 /**
aoqi@0 267 * Pop the namespace context off the stack.
aoqi@0 268 * <p>
aoqi@0 269 * Namespaces declared within the context (to be popped)
aoqi@0 270 * will be removed and no longer be in scope.
aoqi@0 271 */
aoqi@0 272 public void popContext() {
aoqi@0 273 if (contextPosition > 0) {
aoqi@0 274 namespacePosition = contexts[--contextPosition];
aoqi@0 275 }
aoqi@0 276 }
aoqi@0 277
aoqi@0 278 /**
aoqi@0 279 * Reset namespace contexts.
aoqi@0 280 * <p>
aoqi@0 281 * Pop all namespace contexts and reset the root context.
aoqi@0 282 */
aoqi@0 283 public void resetContexts() {
aoqi@0 284 namespacePosition = 2;
aoqi@0 285 }
aoqi@0 286 }

mercurial