src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/NamespaceContextImpl.java

Sun, 18 Jun 2017 23:18:45 +0100

author
aefimov
date
Sun, 18 Jun 2017 23:18:45 +0100
changeset 1491
d5c5a205d7fb
parent 0
373ffda63c9a
permissions
-rw-r--r--

8172297: In java 8, the marshalling with JAX-WS does not escape carriage return
Reviewed-by: lancea

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2011, 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.bind.v2.runtime.output;
aoqi@0 27
aoqi@0 28 import java.io.IOException;
aoqi@0 29 import java.util.Collections;
aoqi@0 30 import java.util.Iterator;
aoqi@0 31
aoqi@0 32 import javax.xml.XMLConstants;
aoqi@0 33 import javax.xml.stream.XMLStreamException;
aoqi@0 34
aoqi@0 35 import com.sun.istack.internal.NotNull;
aoqi@0 36 import com.sun.istack.internal.Nullable;
aoqi@0 37 import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
aoqi@0 38 import com.sun.xml.internal.bind.v2.WellKnownNamespace;
aoqi@0 39 import com.sun.xml.internal.bind.v2.runtime.Name;
aoqi@0 40 import com.sun.xml.internal.bind.v2.runtime.NamespaceContext2;
aoqi@0 41 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer;
aoqi@0 42
aoqi@0 43 import org.xml.sax.SAXException;
aoqi@0 44
aoqi@0 45 /**
aoqi@0 46 * Keeps track of in-scope namespace bindings for the marshaller.
aoqi@0 47 *
aoqi@0 48 * <p>
aoqi@0 49 * This class is also used to keep track of tag names for each element
aoqi@0 50 * for the marshaller (for the performance reason.)
aoqi@0 51 *
aoqi@0 52 * @author Kohsuke Kawaguchi
aoqi@0 53 */
aoqi@0 54 public final class NamespaceContextImpl implements NamespaceContext2 {
aoqi@0 55 private final XMLSerializer owner;
aoqi@0 56
aoqi@0 57 private String[] prefixes = new String[4];
aoqi@0 58 private String[] nsUris = new String[4];
aoqi@0 59 // /**
aoqi@0 60 // * True if the correponding namespace declaration is an authentic one that should be printed.
aoqi@0 61 // *
aoqi@0 62 // * False if it's a re-discovered in-scope namespace binding available at the ancestor elements
aoqi@0 63 // * outside this marhsalling. The false value is used to incorporate the in-scope namespace binding
aoqi@0 64 // * information from {@link #inscopeNamespaceContext}. When false, such a declaration does not need
aoqi@0 65 // * to be printed, as it's already available in ancestors.
aoqi@0 66 // */
aoqi@0 67 // private boolean[] visible = new boolean[4];
aoqi@0 68 //
aoqi@0 69 // /**
aoqi@0 70 // * {@link NamespaceContext} that informs this {@link XMLSerializer} about the
aoqi@0 71 // * in-scope namespace bindings of the ancestor elements outside this marshalling.
aoqi@0 72 // *
aoqi@0 73 // * <p>
aoqi@0 74 // * This is used when the marshaller is marshalling into a subtree that has ancestor
aoqi@0 75 // * elements created outside the JAXB marshaller.
aoqi@0 76 // *
aoqi@0 77 // * Its {@link NamespaceContext#getPrefix(String)} is used to discover in-scope namespace
aoqi@0 78 // * binding,
aoqi@0 79 // */
aoqi@0 80 // private final NamespaceContext inscopeNamespaceContext;
aoqi@0 81
aoqi@0 82 /**
aoqi@0 83 * Number of URIs declared. Identifies the valid portion of
aoqi@0 84 * the {@link #prefixes} and {@link #nsUris} arrays.
aoqi@0 85 */
aoqi@0 86 private int size;
aoqi@0 87
aoqi@0 88 private Element current;
aoqi@0 89
aoqi@0 90 /**
aoqi@0 91 * This is the {@link Element} whose prev==null.
aoqi@0 92 * This element is used to hold the contextual namespace bindings
aoqi@0 93 * that are assumed to be outside of the document we are marshalling.
aoqi@0 94 * Specifically the xml prefix and any other user-specified bindings.
aoqi@0 95 *
aoqi@0 96 * @see NamespacePrefixMapper#getPreDeclaredNamespaceUris()
aoqi@0 97 */
aoqi@0 98 private final Element top;
aoqi@0 99
aoqi@0 100 /**
aoqi@0 101 * Never null.
aoqi@0 102 */
aoqi@0 103 private NamespacePrefixMapper prefixMapper = defaultNamespacePrefixMapper;
aoqi@0 104
aoqi@0 105 /**
aoqi@0 106 * True to allow new URIs to be declared. False otherwise.
aoqi@0 107 */
aoqi@0 108 public boolean collectionMode;
aoqi@0 109
aoqi@0 110
aoqi@0 111 public NamespaceContextImpl(XMLSerializer owner) {
aoqi@0 112 this.owner = owner;
aoqi@0 113
aoqi@0 114 current = top = new Element(this,null);
aoqi@0 115 // register namespace URIs that are implicitly bound
aoqi@0 116 put(XMLConstants.XML_NS_URI,XMLConstants.XML_NS_PREFIX);
aoqi@0 117 }
aoqi@0 118
aoqi@0 119 public void setPrefixMapper( NamespacePrefixMapper mapper ) {
aoqi@0 120 if(mapper==null)
aoqi@0 121 mapper = defaultNamespacePrefixMapper;
aoqi@0 122 this.prefixMapper = mapper;
aoqi@0 123 }
aoqi@0 124
aoqi@0 125 public NamespacePrefixMapper getPrefixMapper() {
aoqi@0 126 return prefixMapper;
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 public void reset() {
aoqi@0 130 current = top;
aoqi@0 131 size = 1;
aoqi@0 132 collectionMode = false;
aoqi@0 133 }
aoqi@0 134
aoqi@0 135 /**
aoqi@0 136 * Returns the prefix index to the specified URI.
aoqi@0 137 * This method allocates a new URI if necessary.
aoqi@0 138 */
aoqi@0 139 public int declareNsUri( String uri, String preferedPrefix, boolean requirePrefix ) {
aoqi@0 140 preferedPrefix = prefixMapper.getPreferredPrefix(uri,preferedPrefix,requirePrefix);
aoqi@0 141
aoqi@0 142 if(uri.length()==0) {
aoqi@0 143 for( int i=size-1; i>=0; i-- ) {
aoqi@0 144 if(nsUris[i].length()==0)
aoqi@0 145 return i; // already declared
aoqi@0 146 if(prefixes[i].length()==0) {
aoqi@0 147 // the default prefix is already taken.
aoqi@0 148 // move that URI to another prefix, then assign "" to the default prefix.
aoqi@0 149 assert current.defaultPrefixIndex==-1 && current.oldDefaultNamespaceUriIndex==-1;
aoqi@0 150
aoqi@0 151 String oldUri = nsUris[i];
aoqi@0 152 String[] knownURIs = owner.nameList.namespaceURIs;
aoqi@0 153
aoqi@0 154 if(current.baseIndex<=i) {
aoqi@0 155 // this default prefix is declared in this context. just reassign it
aoqi@0 156
aoqi@0 157 nsUris[i] = "";
aoqi@0 158
aoqi@0 159 int subst = put(oldUri,null);
aoqi@0 160
aoqi@0 161 // update uri->prefix table if necessary
aoqi@0 162 for( int j=knownURIs.length-1; j>=0; j-- ) {
aoqi@0 163 if(knownURIs[j].equals(oldUri)) {
aoqi@0 164 owner.knownUri2prefixIndexMap[j] = subst;
aoqi@0 165 break;
aoqi@0 166 }
aoqi@0 167 }
aoqi@0 168 if (current.elementLocalName != null) {
aoqi@0 169 current.setTagName(subst, current.elementLocalName, current.getOuterPeer());
aoqi@0 170 }
aoqi@0 171 return i;
aoqi@0 172 } else {
aoqi@0 173 // first, if the previous URI assigned to "" is
aoqi@0 174 // a "known URI", remember what we've reallocated
aoqi@0 175 // so that we can fix it when this context pops.
aoqi@0 176 for( int j=knownURIs.length-1; j>=0; j-- ) {
aoqi@0 177 if(knownURIs[j].equals(oldUri)) {
aoqi@0 178 current.defaultPrefixIndex = i;
aoqi@0 179 current.oldDefaultNamespaceUriIndex = j;
aoqi@0 180 // assert commented out; too strict/not valid any more
aoqi@0 181 // assert owner.knownUri2prefixIndexMap[j]==current.defaultPrefixIndex;
aoqi@0 182 // update the table to point to the prefix we'll declare
aoqi@0 183 owner.knownUri2prefixIndexMap[j] = size;
aoqi@0 184 break;
aoqi@0 185 }
aoqi@0 186 }
aoqi@0 187 if (current.elementLocalName!=null) {
aoqi@0 188 current.setTagName(size, current.elementLocalName, current.getOuterPeer());
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 put(nsUris[i],null);
aoqi@0 192 return put("", "");
aoqi@0 193 }
aoqi@0 194 }
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 // "" isn't in use
aoqi@0 198 return put("", "");
aoqi@0 199 } else {
aoqi@0 200 // check for the existing binding
aoqi@0 201 for( int i=size-1; i>=0; i-- ) {
aoqi@0 202 String p = prefixes[i];
aoqi@0 203 if(nsUris[i].equals(uri)) {
aoqi@0 204 if (!requirePrefix || p.length()>0)
aoqi@0 205 return i;
aoqi@0 206 // declared but this URI is bound to empty. Look further
aoqi@0 207 }
aoqi@0 208 if(p.equals(preferedPrefix)) {
aoqi@0 209 // the suggested prefix is already taken. can't use it
aoqi@0 210 preferedPrefix = null;
aoqi@0 211 }
aoqi@0 212 }
aoqi@0 213
aoqi@0 214 if(preferedPrefix==null && requirePrefix)
aoqi@0 215 // we know we can't bind to "", but we don't have any possible name at hand.
aoqi@0 216 // generate it here to avoid this namespace to be bound to "".
aoqi@0 217 preferedPrefix = makeUniquePrefix();
aoqi@0 218
aoqi@0 219 // haven't been declared. allocate a new one
aoqi@0 220 // if the preferred prefix is already in use, it should have been set to null by this time
aoqi@0 221 return put(uri, preferedPrefix);
aoqi@0 222 }
aoqi@0 223 }
aoqi@0 224
aoqi@0 225 public int force(@NotNull String uri, @NotNull String prefix) {
aoqi@0 226 // check for the existing binding
aoqi@0 227
aoqi@0 228 for( int i=size-1; i>=0; i-- ) {
aoqi@0 229 if(prefixes[i].equals(prefix)) {
aoqi@0 230 if(nsUris[i].equals(uri))
aoqi@0 231 return i; // found duplicate
aoqi@0 232 else
aoqi@0 233 // the prefix is used for another namespace. we need to declare it
aoqi@0 234 break;
aoqi@0 235 }
aoqi@0 236 }
aoqi@0 237
aoqi@0 238 return put(uri, prefix);
aoqi@0 239 }
aoqi@0 240
aoqi@0 241 /**
aoqi@0 242 * Puts this new binding into the declared prefixes list
aoqi@0 243 * without doing any duplicate check.
aoqi@0 244 *
aoqi@0 245 * This can be used to forcibly set namespace declarations.
aoqi@0 246 *
aoqi@0 247 * <p>
aoqi@0 248 * Most of the time {@link #declareNamespace(String, String, boolean)} shall be used.
aoqi@0 249 *
aoqi@0 250 * @return
aoqi@0 251 * the index of this new binding.
aoqi@0 252 */
aoqi@0 253 public int put(@NotNull String uri, @Nullable String prefix) {
aoqi@0 254 if(size==nsUris.length) {
aoqi@0 255 // reallocate
aoqi@0 256 String[] u = new String[nsUris.length*2];
aoqi@0 257 String[] p = new String[prefixes.length*2];
aoqi@0 258 System.arraycopy(nsUris,0,u,0,nsUris.length);
aoqi@0 259 System.arraycopy(prefixes,0,p,0,prefixes.length);
aoqi@0 260 nsUris = u;
aoqi@0 261 prefixes = p;
aoqi@0 262 }
aoqi@0 263 if(prefix==null) {
aoqi@0 264 if(size==1)
aoqi@0 265 prefix = ""; // if this is the first user namespace URI we see, use "".
aoqi@0 266 else {
aoqi@0 267 // otherwise make up an unique name
aoqi@0 268 prefix = makeUniquePrefix();
aoqi@0 269 }
aoqi@0 270 }
aoqi@0 271 nsUris[size] = uri;
aoqi@0 272 prefixes[size] = prefix;
aoqi@0 273
aoqi@0 274 return size++;
aoqi@0 275 }
aoqi@0 276
aoqi@0 277 private String makeUniquePrefix() {
aoqi@0 278 String prefix;
aoqi@0 279 prefix = new StringBuilder(5).append("ns").append(size).toString();
aoqi@0 280 while(getNamespaceURI(prefix)!=null) {
aoqi@0 281 prefix += '_'; // under a rare circumstance there might be existing 'nsNNN', so rename them
aoqi@0 282 }
aoqi@0 283 return prefix;
aoqi@0 284 }
aoqi@0 285
aoqi@0 286
aoqi@0 287 public Element getCurrent() {
aoqi@0 288 return current;
aoqi@0 289 }
aoqi@0 290
aoqi@0 291 /**
aoqi@0 292 * Returns the prefix index of the specified URI.
aoqi@0 293 * It is an error if the URI is not declared.
aoqi@0 294 */
aoqi@0 295 public int getPrefixIndex( String uri ) {
aoqi@0 296 for( int i=size-1; i>=0; i-- ) {
aoqi@0 297 if(nsUris[i].equals(uri))
aoqi@0 298 return i;
aoqi@0 299 }
aoqi@0 300 throw new IllegalStateException();
aoqi@0 301 }
aoqi@0 302
aoqi@0 303 /**
aoqi@0 304 * Gets the prefix from a prefix index.
aoqi@0 305 *
aoqi@0 306 * The behavior is undefined if the index is out of range.
aoqi@0 307 */
aoqi@0 308 public String getPrefix(int prefixIndex) {
aoqi@0 309 return prefixes[prefixIndex];
aoqi@0 310 }
aoqi@0 311
aoqi@0 312 public String getNamespaceURI(int prefixIndex) {
aoqi@0 313 return nsUris[prefixIndex];
aoqi@0 314 }
aoqi@0 315
aoqi@0 316 /**
aoqi@0 317 * Gets the namespace URI that is bound to the specified prefix.
aoqi@0 318 *
aoqi@0 319 * @return null
aoqi@0 320 * if the prefix is unbound.
aoqi@0 321 */
aoqi@0 322 public String getNamespaceURI(String prefix) {
aoqi@0 323 for( int i=size-1; i>=0; i-- )
aoqi@0 324 if(prefixes[i].equals(prefix))
aoqi@0 325 return nsUris[i];
aoqi@0 326 return null;
aoqi@0 327 }
aoqi@0 328
aoqi@0 329 /**
aoqi@0 330 * Returns the prefix of the specified URI,
aoqi@0 331 * or null if none exists.
aoqi@0 332 */
aoqi@0 333 public String getPrefix( String uri ) {
aoqi@0 334 if(collectionMode) {
aoqi@0 335 return declareNamespace(uri,null,false);
aoqi@0 336 } else {
aoqi@0 337 for( int i=size-1; i>=0; i-- )
aoqi@0 338 if(nsUris[i].equals(uri))
aoqi@0 339 return prefixes[i];
aoqi@0 340 return null;
aoqi@0 341 }
aoqi@0 342 }
aoqi@0 343
aoqi@0 344 public Iterator<String> getPrefixes(String uri) {
aoqi@0 345 String prefix = getPrefix(uri);
aoqi@0 346 if(prefix==null)
aoqi@0 347 return Collections.<String>emptySet().iterator();
aoqi@0 348 else
aoqi@0 349 return Collections.singleton(uri).iterator();
aoqi@0 350 }
aoqi@0 351
aoqi@0 352 public String declareNamespace(String namespaceUri, String preferedPrefix, boolean requirePrefix) {
aoqi@0 353 int idx = declareNsUri(namespaceUri,preferedPrefix,requirePrefix);
aoqi@0 354 return getPrefix(idx);
aoqi@0 355 }
aoqi@0 356
aoqi@0 357 /**
aoqi@0 358 * Number of total bindings declared.
aoqi@0 359 */
aoqi@0 360 public int count() {
aoqi@0 361 return size;
aoqi@0 362 }
aoqi@0 363
aoqi@0 364
aoqi@0 365 /**
aoqi@0 366 * This model of namespace declarations maintain the following invariants.
aoqi@0 367 *
aoqi@0 368 * <ul>
aoqi@0 369 * <li>If a non-empty prefix is declared, it will never be reassigned to different namespace URIs.
aoqi@0 370 * <li>
aoqi@0 371 */
aoqi@0 372 public final class Element {
aoqi@0 373
aoqi@0 374 public final NamespaceContextImpl context;
aoqi@0 375
aoqi@0 376 /**
aoqi@0 377 * {@link Element}s form a doubly-linked list.
aoqi@0 378 */
aoqi@0 379 private final Element prev;
aoqi@0 380 private Element next;
aoqi@0 381
aoqi@0 382 private int oldDefaultNamespaceUriIndex;
aoqi@0 383 private int defaultPrefixIndex;
aoqi@0 384
aoqi@0 385
aoqi@0 386 /**
aoqi@0 387 * The numbe of prefixes declared by ancestor {@link Element}s.
aoqi@0 388 */
aoqi@0 389 private int baseIndex;
aoqi@0 390
aoqi@0 391 /**
aoqi@0 392 * The depth of the {@link Element}.
aoqi@0 393 *
aoqi@0 394 * This value is equivalent as the result of the following computation.
aoqi@0 395 *
aoqi@0 396 * <pre>
aoqi@0 397 * int depth() {
aoqi@0 398 * int i=-1;
aoqi@0 399 * for(Element e=this; e!=null;e=e.prev)
aoqi@0 400 * i++;
aoqi@0 401 * return i;
aoqi@0 402 * }
aoqi@0 403 * </pre>
aoqi@0 404 */
aoqi@0 405 private final int depth;
aoqi@0 406
aoqi@0 407
aoqi@0 408
aoqi@0 409 private int elementNamePrefix;
aoqi@0 410 private String elementLocalName;
aoqi@0 411
aoqi@0 412 /**
aoqi@0 413 * Tag name of this element.
aoqi@0 414 * Either this field is used or the {@link #elementNamePrefix} and {@link #elementLocalName} pair.
aoqi@0 415 */
aoqi@0 416 private Name elementName;
aoqi@0 417
aoqi@0 418 /**
aoqi@0 419 * Used for the binder. The JAXB object that corresponds to this element.
aoqi@0 420 */
aoqi@0 421 private Object outerPeer;
aoqi@0 422 private Object innerPeer;
aoqi@0 423
aoqi@0 424
aoqi@0 425 private Element(NamespaceContextImpl context,Element prev) {
aoqi@0 426 this.context = context;
aoqi@0 427 this.prev = prev;
aoqi@0 428 this.depth = (prev==null) ? 0 : prev.depth+1;
aoqi@0 429 }
aoqi@0 430
aoqi@0 431 /**
aoqi@0 432 * Returns true if this {@link Element} represents the root element that
aoqi@0 433 * we are marshalling.
aoqi@0 434 */
aoqi@0 435 public boolean isRootElement() {
aoqi@0 436 return depth==1;
aoqi@0 437 }
aoqi@0 438
aoqi@0 439 public Element push() {
aoqi@0 440 if(next==null)
aoqi@0 441 next = new Element(context,this);
aoqi@0 442 next.onPushed();
aoqi@0 443 return next;
aoqi@0 444 }
aoqi@0 445
aoqi@0 446 public Element pop() {
aoqi@0 447 if(oldDefaultNamespaceUriIndex>=0) {
aoqi@0 448 // restore the old default namespace URI binding
aoqi@0 449 context.owner.knownUri2prefixIndexMap[oldDefaultNamespaceUriIndex] = defaultPrefixIndex;
aoqi@0 450 }
aoqi@0 451 context.size = baseIndex;
aoqi@0 452 context.current = prev;
aoqi@0 453 // release references to user objects
aoqi@0 454 outerPeer = innerPeer = null;
aoqi@0 455 return prev;
aoqi@0 456 }
aoqi@0 457
aoqi@0 458 private void onPushed() {
aoqi@0 459 oldDefaultNamespaceUriIndex = defaultPrefixIndex = -1;
aoqi@0 460 baseIndex = context.size;
aoqi@0 461 context.current = this;
aoqi@0 462 }
aoqi@0 463
aoqi@0 464 public void setTagName( int prefix, String localName, Object outerPeer ) {
aoqi@0 465 assert localName!=null;
aoqi@0 466 this.elementNamePrefix = prefix;
aoqi@0 467 this.elementLocalName = localName;
aoqi@0 468 this.elementName = null;
aoqi@0 469 this.outerPeer = outerPeer;
aoqi@0 470 }
aoqi@0 471
aoqi@0 472 public void setTagName( Name tagName, Object outerPeer ) {
aoqi@0 473 assert tagName!=null;
aoqi@0 474 this.elementName = tagName;
aoqi@0 475 this.outerPeer = outerPeer;
aoqi@0 476 }
aoqi@0 477
aoqi@0 478 public void startElement(XmlOutput out, Object innerPeer) throws IOException, XMLStreamException {
aoqi@0 479 this.innerPeer = innerPeer;
aoqi@0 480 if(elementName!=null) {
aoqi@0 481 out.beginStartTag(elementName);
aoqi@0 482 } else {
aoqi@0 483 out.beginStartTag(elementNamePrefix,elementLocalName);
aoqi@0 484 }
aoqi@0 485 }
aoqi@0 486
aoqi@0 487 public void endElement(XmlOutput out) throws IOException, SAXException, XMLStreamException {
aoqi@0 488 if(elementName!=null) {
aoqi@0 489 out.endTag(elementName);
aoqi@0 490 elementName = null;
aoqi@0 491 } else {
aoqi@0 492 out.endTag(elementNamePrefix,elementLocalName);
aoqi@0 493 }
aoqi@0 494 }
aoqi@0 495
aoqi@0 496 /**
aoqi@0 497 * Gets the number of bindings declared on this element.
aoqi@0 498 */
aoqi@0 499 public final int count() {
aoqi@0 500 return context.size-baseIndex;
aoqi@0 501 }
aoqi@0 502
aoqi@0 503 /**
aoqi@0 504 * Gets the prefix declared in this context.
aoqi@0 505 *
aoqi@0 506 * @param idx
aoqi@0 507 * between 0 and {@link #count()}
aoqi@0 508 */
aoqi@0 509 public final String getPrefix(int idx) {
aoqi@0 510 return context.prefixes[baseIndex+idx];
aoqi@0 511 }
aoqi@0 512
aoqi@0 513 /**
aoqi@0 514 * Gets the namespace URI declared in this context.
aoqi@0 515 *
aoqi@0 516 * @param idx
aoqi@0 517 * between 0 and {@link #count()}
aoqi@0 518 */
aoqi@0 519 public final String getNsUri(int idx) {
aoqi@0 520 return context.nsUris[baseIndex+idx];
aoqi@0 521 }
aoqi@0 522
aoqi@0 523 public int getBase() {
aoqi@0 524 return baseIndex;
aoqi@0 525 }
aoqi@0 526
aoqi@0 527 public Object getOuterPeer() {
aoqi@0 528 return outerPeer;
aoqi@0 529 }
aoqi@0 530
aoqi@0 531 public Object getInnerPeer() {
aoqi@0 532 return innerPeer;
aoqi@0 533 }
aoqi@0 534
aoqi@0 535 /**
aoqi@0 536 * Gets the parent {@link Element}.
aoqi@0 537 */
aoqi@0 538 public Element getParent() {
aoqi@0 539 return prev;
aoqi@0 540 }
aoqi@0 541 }
aoqi@0 542
aoqi@0 543
aoqi@0 544 /**
aoqi@0 545 * Default {@link NamespacePrefixMapper} implementation used when
aoqi@0 546 * it is not specified by the user.
aoqi@0 547 */
aoqi@0 548 private static final NamespacePrefixMapper defaultNamespacePrefixMapper = new NamespacePrefixMapper() {
aoqi@0 549 public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
aoqi@0 550 if( namespaceUri.equals(WellKnownNamespace.XML_SCHEMA_INSTANCE) )
aoqi@0 551 return "xsi";
aoqi@0 552 if( namespaceUri.equals(WellKnownNamespace.XML_SCHEMA) )
aoqi@0 553 return "xs";
aoqi@0 554 if( namespaceUri.equals(WellKnownNamespace.XML_MIME_URI) )
aoqi@0 555 return "xmime";
aoqi@0 556 return suggestion;
aoqi@0 557 }
aoqi@0 558 };
aoqi@0 559 }

mercurial