1 /* 2 * Copyright (c) 1997, 2017, 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.messaging.saaj.soap.impl; 27 28 import java.net.URI; 29 import java.net.URISyntaxException; 30 import java.util.logging.Level; 31 import java.util.logging.Logger; 32 33 import javax.xml.namespace.QName; 34 35 import org.w3c.dom.Node; 36 37 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; 38 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument; 39 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl; 40 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl; 41 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants; 42 import com.sun.xml.internal.messaging.saaj.util.NamespaceContextIterator; 43 import java.util.ArrayList; 44 import java.util.Iterator; 45 import java.util.NoSuchElementException; 46 import javax.xml.soap.Name; 47 import javax.xml.soap.SOAPBodyElement; 48 import javax.xml.soap.SOAPConstants; 49 import javax.xml.soap.SOAPElement; 50 import javax.xml.soap.SOAPException; 51 import org.w3c.dom.Attr; 52 import org.w3c.dom.CharacterData; 53 import org.w3c.dom.DOMException; 54 import org.w3c.dom.Document; 55 import org.w3c.dom.DocumentFragment; 56 import org.w3c.dom.Element; 57 import org.w3c.dom.NamedNodeMap; 58 import org.w3c.dom.NodeList; 59 import org.w3c.dom.TypeInfo; 60 import org.w3c.dom.UserDataHandler; 61 62 public class ElementImpl implements SOAPElement, SOAPBodyElement { 63 64 public static final String DSIG_NS = "http://www.w3.org/2000/09/xmldsig#".intern(); 65 public static final String XENC_NS = "http://www.w3.org/2001/04/xmlenc#".intern(); 66 public static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd".intern(); 67 68 private transient AttributeManager encodingStyleAttribute = new AttributeManager(); 69 70 protected QName elementQName; 71 72 private Element element; 73 74 private SOAPDocumentImpl soapDocument; 75 76 @Override 77 public String getTagName() { 78 return element.getTagName(); 79 } 80 81 @Override 82 public String getAttribute(String name) { 83 return element.getAttribute(name); 84 } 85 86 @Override 87 public void setAttribute(String name, String value) throws DOMException { 88 boolean isQualifiedName = (name.indexOf(":") > 0); 89 //this is because of BugfixTest#testCR7020991, after removal internal dependencies 90 //SOAPDocumentImpl#createAttribute is not called anymore from xerces parent 91 if (isQualifiedName) { 92 String nsUri = null; 93 String prefix = name.substring(0, name.indexOf(":")); 94 //cannot do anything to resolve the URI if prefix is not 95 //XMLNS. 96 if (XMLNS.equals(prefix)) { 97 nsUri = ElementImpl.XMLNS_URI; 98 setAttributeNS(nsUri, name, value); 99 return; 100 } 101 } 102 element.setAttribute(name, value); 103 } 104 105 @Override 106 public void removeAttribute(String name) throws DOMException { 107 element.removeAttribute(name); 108 } 109 110 @Override 111 public Attr getAttributeNode(String name) { 112 return element.getAttributeNode(name); 113 } 114 115 @Override 116 public Attr setAttributeNode(Attr newAttr) throws DOMException { 117 return element.setAttributeNode(newAttr); 118 } 119 120 @Override 121 public Attr removeAttributeNode(Attr oldAttr) throws DOMException { 122 return element.removeAttributeNode(oldAttr); 123 } 124 125 @Override 126 public NodeList getElementsByTagName(String name) { 127 return new NodeListImpl(soapDocument, element.getElementsByTagName(name)); 128 } 129 130 @Override 131 public String getAttributeNS(String namespaceURI, String localName) throws DOMException { 132 return element.getAttributeNS(namespaceURI, localName); 133 } 134 135 protected static final Logger log = 136 Logger.getLogger(LogDomainConstants.SOAP_IMPL_DOMAIN, 137 "com.sun.xml.internal.messaging.saaj.soap.impl.LocalStrings"); 138 139 /** 140 * XML Information Set REC 141 * all namespace attributes (including those named xmlns, 142 * whose [prefix] property has no value) have a namespace URI of http://www.w3.org/2000/xmlns/ 143 */ 144 public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/".intern(); 145 146 /** 147 * The XML Namespace ("http://www.w3.org/XML/1998/namespace"). This is 148 * the Namespace URI that is automatically mapped to the "xml" prefix. 149 */ 150 public final static String XML_URI = "http://www.w3.org/XML/1998/namespace".intern(); 151 152 private final static String XMLNS = "xmlns".intern(); 153 154 public ElementImpl(SOAPDocumentImpl ownerDoc, Name name) { 155 this.soapDocument = ownerDoc; 156 this.element = ownerDoc.getDomDocument().createElementNS(name.getURI(), name.getQualifiedName()); 157 elementQName = NameImpl.convertToQName(name); 158 soapDocument.register(this); 159 } 160 161 public ElementImpl(SOAPDocumentImpl ownerDoc, QName name) { 162 this.soapDocument = ownerDoc; 163 this.element = ownerDoc.getDomDocument().createElementNS(name.getNamespaceURI(), getQualifiedName(name)); 164 elementQName = name; 165 soapDocument.register(this); 166 } 167 168 public ElementImpl(SOAPDocumentImpl ownerDoc, Element domElement) { 169 this.element = domElement; 170 this.soapDocument = ownerDoc; 171 this.elementQName = new QName(domElement.getNamespaceURI(), domElement.getLocalName()); 172 soapDocument.register(this); 173 } 174 175 public ElementImpl( 176 SOAPDocumentImpl ownerDoc, 177 String uri, 178 String qualifiedName) { 179 180 this.soapDocument = ownerDoc; 181 this.element = ownerDoc.getDomDocument().createElementNS(uri, qualifiedName); 182 elementQName = 183 new QName(uri, getLocalPart(qualifiedName), getPrefix(qualifiedName)); 184 soapDocument.register(this); 185 } 186 187 public void ensureNamespaceIsDeclared(String prefix, String uri) { 188 String alreadyDeclaredUri = getNamespaceURI(prefix); 189 if (alreadyDeclaredUri == null || !alreadyDeclaredUri.equals(uri)) { 190 try { 191 addNamespaceDeclaration(prefix, uri); 192 } catch (SOAPException e) { /*ignore*/ 193 } 194 } 195 } 196 197 @Override 198 public Document getOwnerDocument() { 199 return soapDocument; 200 } 201 202 @Override 203 public Node insertBefore(Node newChild, Node refChild) throws DOMException { 204 return soapDocument.findIfPresent(element.insertBefore(soapDocument.getDomNode(newChild), soapDocument.getDomNode(refChild))); 205 } 206 207 @Override 208 public Node replaceChild(Node newChild, Node oldChild) throws DOMException { 209 return soapDocument.findIfPresent(element.replaceChild(soapDocument.getDomNode(newChild), soapDocument.getDomNode(oldChild))); 210 } 211 212 @Override 213 public Node removeChild(Node oldChild) throws DOMException { 214 return soapDocument.findIfPresent(element.removeChild(soapDocument.getDomNode(oldChild))); 215 } 216 217 @Override 218 public Node appendChild(Node newChild) throws DOMException { 219 return soapDocument.findIfPresent(element.appendChild(soapDocument.getDomNode(newChild))); 220 } 221 222 @Override 223 public boolean hasChildNodes() { 224 return element.hasChildNodes(); 225 } 226 227 @Override 228 public Node cloneNode(boolean deep) { 229 Node elementNSNode = element.cloneNode(deep); 230 soapDocument.registerChildNodes(elementNSNode, deep); 231 return soapDocument.findIfPresent(soapDocument.getDomNode(elementNSNode)); 232 } 233 234 @Override 235 public void normalize() { 236 element.normalize(); 237 } 238 239 @Override 240 public boolean isSupported(String feature, String version) { 241 return element.isSupported(feature, version); 242 } 243 244 @Override 245 public String getNamespaceURI() { 246 return element.getNamespaceURI(); 247 } 248 249 @Override 250 public String getPrefix() { 251 return element.getPrefix(); 252 } 253 254 @Override 255 public void setPrefix(String prefix) throws DOMException { 256 element.setPrefix(prefix); 257 } 258 259 @Override 260 public String getLocalName() { 261 return element.getLocalName(); 262 } 263 264 @Override 265 public boolean hasAttributes() { 266 return element.hasAttributes(); 267 } 268 269 @Override 270 public String getBaseURI() { 271 return element.getBaseURI(); 272 } 273 274 @Override 275 public short compareDocumentPosition(Node other) throws DOMException { 276 return element.compareDocumentPosition(soapDocument.getDomNode(other)); 277 } 278 279 @Override 280 public String getTextContent() throws DOMException { 281 return element.getTextContent(); 282 } 283 284 @Override 285 public void setTextContent(String textContent) throws DOMException { 286 element.setTextContent(textContent); 287 } 288 289 @Override 290 public boolean isSameNode(Node other) { 291 return element.isSameNode(soapDocument.getDomNode(other)); 292 } 293 294 @Override 295 public String lookupPrefix(String namespaceURI) { 296 return element.lookupPrefix(namespaceURI); 297 } 298 299 @Override 300 public boolean isDefaultNamespace(String namespaceURI) { 301 return element.isDefaultNamespace(namespaceURI); 302 } 303 304 @Override 305 public String lookupNamespaceURI(String prefix) { 306 return element.lookupNamespaceURI(prefix); 307 } 308 309 @Override 310 public boolean isEqualNode(Node arg) { 311 return element.isEqualNode(soapDocument.getDomNode(arg)); 312 } 313 314 @Override 315 public Object getFeature(String feature, String version) { 316 return element.getFeature(feature, version); 317 } 318 319 @Override 320 public Object setUserData(String key, Object data, UserDataHandler handler) { 321 return element.setUserData(key, data, handler); 322 } 323 324 @Override 325 public Object getUserData(String key) { 326 return element.getUserData(key); 327 } 328 329 @Override 330 public SOAPElement addChildElement(Name name) throws SOAPException { 331 return addElement(name); 332 } 333 334 @Override 335 public SOAPElement addChildElement(QName qname) throws SOAPException { 336 return addElement(qname); 337 } 338 339 @Override 340 public SOAPElement addChildElement(String localName) throws SOAPException { 341 String nsUri = getNamespaceURI(""); 342 Name name = (nsUri == null || nsUri.isEmpty()) 343 ? NameImpl.createFromUnqualifiedName(localName) 344 : NameImpl.createFromQualifiedName(localName, nsUri); 345 return addChildElement(name); 346 } 347 348 @Override 349 public SOAPElement addChildElement(String localName, String prefix) 350 throws SOAPException { 351 String uri = getNamespaceURI(prefix); 352 if (uri == null) { 353 log.log( 354 Level.SEVERE, 355 "SAAJ0101.impl.parent.of.body.elem.mustbe.body", 356 new String[] { prefix }); 357 throw new SOAPExceptionImpl( 358 "Unable to locate namespace for prefix " + prefix); 359 } 360 return addChildElement(localName, prefix, uri); 361 } 362 363 @Override 364 public String getNamespaceURI(String prefix) { 365 366 if ("xmlns".equals(prefix)) { 367 return XMLNS_URI; 368 } 369 370 if("xml".equals(prefix)) { 371 return XML_URI; 372 } 373 374 if ("".equals(prefix)) { 375 376 org.w3c.dom.Node currentAncestor = this; 377 while (currentAncestor != null && 378 !(currentAncestor instanceof Document)) { 379 380 if (currentAncestor instanceof ElementImpl) { 381 /* 382 QName name = ((ElementImpl) currentAncestor).getElementQName(); 383 if (prefix.equals(name.getPrefix())) { 384 String uri = name.getNamespaceURI(); 385 if ("".equals(uri)) { 386 return null; 387 } 388 else { 389 return uri; 390 } 391 }*/ 392 if (((Element) currentAncestor).hasAttributeNS( 393 XMLNS_URI, "xmlns")) { 394 395 String uri = 396 ((Element) currentAncestor).getAttributeNS( 397 XMLNS_URI, "xmlns"); 398 if ("".equals(uri)) 399 return null; 400 else { 401 return uri; 402 } 403 } 404 } 405 currentAncestor = currentAncestor.getParentNode(); 406 } 407 408 } else if (prefix != null) { 409 // Find if there's an ancester whose name contains this prefix 410 org.w3c.dom.Node currentAncestor = this; 411 412 // String uri = currentAncestor.lookupNamespaceURI(prefix); 413 // return uri; 414 while (currentAncestor != null && 415 !(currentAncestor instanceof Document)) { 416 417 /* if (prefix.equals(currentAncestor.getPrefix())) { 418 String uri = currentAncestor.getNamespaceURI(); 419 // this is because the javadoc says getNamespaceURI() is not a computed value 420 // and URI for a non-empty prefix cannot be null 421 if (uri != null) 422 return uri; 423 }*/ 424 //String uri = currentAncestor.lookupNamespaceURI(prefix); 425 //if (uri != null) { 426 // return uri; 427 //} 428 429 if (((Element) currentAncestor).hasAttributeNS( 430 XMLNS_URI, prefix)) { 431 return ((Element) currentAncestor).getAttributeNS( 432 XMLNS_URI, prefix); 433 } 434 435 currentAncestor = currentAncestor.getParentNode(); 436 } 437 } 438 439 return null; 440 } 441 442 @Override 443 public SOAPElement setElementQName(QName newName) throws SOAPException { 444 ElementImpl copy = 445 new ElementImpl((SOAPDocumentImpl) getOwnerDocument(), newName); 446 return replaceElementWithSOAPElement(this,copy); 447 } 448 449 @Override 450 public QName createQName(String localName, String prefix) 451 throws SOAPException { 452 String uri = getNamespaceURI(prefix); 453 if (uri == null) { 454 log.log(Level.SEVERE, "SAAJ0102.impl.cannot.locate.ns", 455 new Object[] {prefix}); 456 throw new SOAPException("Unable to locate namespace for prefix " 457 + prefix); 458 } 459 return new QName(uri, localName, prefix); 460 } 461 462 public String getNamespacePrefix(String uri) { 463 464 NamespaceContextIterator eachNamespace = getNamespaceContextNodes(); 465 while (eachNamespace.hasNext()) { 466 org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr(); 467 if (namespaceDecl.getNodeValue().equals(uri)) { 468 String candidatePrefix = namespaceDecl.getLocalName(); 469 if ("xmlns".equals(candidatePrefix)) 470 return ""; 471 else 472 return candidatePrefix; 473 } 474 } 475 476 // Find if any of the ancestors' name has this uri 477 org.w3c.dom.Node currentAncestor = this; 478 while (currentAncestor != null && 479 !(currentAncestor instanceof Document)) { 480 481 if (uri.equals(currentAncestor.getNamespaceURI())) 482 return currentAncestor.getPrefix(); 483 currentAncestor = currentAncestor.getParentNode(); 484 } 485 486 return null; 487 } 488 489 protected org.w3c.dom.Attr getNamespaceAttr(String prefix) { 490 NamespaceContextIterator eachNamespace = getNamespaceContextNodes(); 491 if (!"".equals(prefix)) 492 prefix = ":"+prefix; 493 while (eachNamespace.hasNext()) { 494 org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr(); 495 if (!"".equals(prefix)) { 496 if (namespaceDecl.getNodeName().endsWith(prefix)) 497 return namespaceDecl; 498 } else { 499 if (namespaceDecl.getNodeName().equals("xmlns")) 500 return namespaceDecl; 501 } 502 } 503 return null; 504 } 505 506 public NamespaceContextIterator getNamespaceContextNodes() { 507 return getNamespaceContextNodes(true); 508 } 509 510 public NamespaceContextIterator getNamespaceContextNodes(boolean traverseStack) { 511 return new NamespaceContextIterator(this, traverseStack); 512 } 513 514 @Override 515 public SOAPElement addChildElement( 516 String localName, 517 String prefix, 518 String uri) 519 throws SOAPException { 520 521 SOAPElement newElement = createElement(NameImpl.create(localName, prefix, uri)); 522 addNode(newElement); 523 return convertToSoapElement(newElement); 524 } 525 526 @Override 527 public SOAPElement addChildElement(SOAPElement element) 528 throws SOAPException { 529 530 // check if Element falls in SOAP 1.1 or 1.2 namespace. 531 String elementURI = element.getElementName().getURI(); 532 String localName = element.getLocalName(); 533 534 if ((SOAPConstants.URI_NS_SOAP_ENVELOPE).equals(elementURI) 535 || (SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE).equals(elementURI)) { 536 537 538 if ("Envelope".equalsIgnoreCase(localName) || 539 "Header".equalsIgnoreCase(localName) || "Body".equalsIgnoreCase(localName)) { 540 log.severe("SAAJ0103.impl.cannot.add.fragements"); 541 throw new SOAPExceptionImpl( 542 "Cannot add fragments which contain elements " 543 + "which are in the SOAP namespace"); 544 } 545 546 if ("Fault".equalsIgnoreCase(localName) && !"Body".equalsIgnoreCase(this.getLocalName())) { 547 log.severe("SAAJ0154.impl.adding.fault.to.nonbody"); 548 throw new SOAPExceptionImpl("Cannot add a SOAPFault as a child of " + this.getLocalName()); 549 } 550 551 if ("Detail".equalsIgnoreCase(localName) && !"Fault".equalsIgnoreCase(this.getLocalName())) { 552 log.severe("SAAJ0155.impl.adding.detail.nonfault"); 553 throw new SOAPExceptionImpl("Cannot add a Detail as a child of " + this.getLocalName()); 554 } 555 556 if ("Fault".equalsIgnoreCase(localName)) { 557 // if body is not empty throw an exception 558 if (!elementURI.equals(this.getElementName().getURI())) { 559 log.severe("SAAJ0158.impl.version.mismatch.fault"); 560 throw new SOAPExceptionImpl("SOAP Version mismatch encountered when trying to add SOAPFault to SOAPBody"); 561 } 562 Iterator<javax.xml.soap.Node> it = this.getChildElements(); 563 if (it.hasNext()) { 564 log.severe("SAAJ0156.impl.adding.fault.error"); 565 throw new SOAPExceptionImpl("Cannot add SOAPFault as a child of a non-Empty SOAPBody"); 566 } 567 } 568 } 569 570 // preserve the encodingStyle attr as it may get lost in the import 571 String encodingStyle = element.getEncodingStyle(); 572 573 final Element importedElement = importElement(element); 574 addNode(importedElement); 575 576 final SOAPElement converted = convertToSoapElement(importedElement); 577 578 if (encodingStyle != null) 579 converted.setEncodingStyle(encodingStyle); 580 581 return converted; 582 } 583 584 protected Element importElement(Element element) { 585 Document document = getOwnerDocument(); 586 Document oldDocument = element.getOwnerDocument(); 587 if (!oldDocument.equals(document)) { 588 return (Element) document.importNode(element, true); 589 } else { 590 return element; 591 } 592 } 593 594 protected SOAPElement addElement(Name name) throws SOAPException { 595 SOAPElement newElement = createElement(name); 596 addNode(((ElementImpl) newElement).getDomElement()); 597 return newElement; 598 } 599 600 protected SOAPElement addElement(QName name) throws SOAPException { 601 SOAPElement newElement = createElement(name); 602 addNode(newElement); 603 return newElement; 604 } 605 606 protected SOAPElement createElement(Name name) { 607 608 if (isNamespaceQualified(name)) { 609 return (SOAPElement) 610 getOwnerDocument().createElementNS( 611 name.getURI(), 612 name.getQualifiedName()); 613 } else { 614 return (SOAPElement) 615 getOwnerDocument().createElement(name.getQualifiedName()); 616 } 617 } 618 619 protected SOAPElement createElement(QName name) { 620 621 if (isNamespaceQualified(name)) { 622 return (SOAPElement) 623 getOwnerDocument().createElementNS( 624 name.getNamespaceURI(), 625 getQualifiedName(name)); 626 } else { 627 return (SOAPElement) 628 getOwnerDocument().createElement(getQualifiedName(name)); 629 } 630 } 631 632 protected void addNode(org.w3c.dom.Node newElement) throws SOAPException { 633 insertBefore(soapDocument.getDomNode(newElement), null); 634 635 if (getOwnerDocument() instanceof DocumentFragment) 636 return; 637 638 if (newElement instanceof ElementImpl) { 639 ElementImpl element = (ElementImpl) newElement; 640 QName elementName = element.getElementQName(); 641 if (!"".equals(elementName.getNamespaceURI())) { 642 element.ensureNamespaceIsDeclared( 643 elementName.getPrefix(), elementName.getNamespaceURI()); 644 } 645 } 646 647 } 648 649 Element getFirstChildElement() { 650 Node child = getFirstChild(); 651 while (child != null) { 652 if (child instanceof Element) { 653 return (Element) soapDocument.find(child); 654 } 655 child = child.getNextSibling(); 656 } 657 return null; 658 } 659 660 protected SOAPElement findChild(NameImpl name) { 661 Node eachChild = getFirstChild(); 662 while (eachChild != null) { 663 if (eachChild instanceof Element) { 664 SOAPElement eachChildSoap = (SOAPElement) soapDocument.find(eachChild); 665 if (eachChildSoap != null) { 666 if (eachChildSoap.getElementName().equals(name)) { 667 return eachChildSoap; 668 } 669 } 670 } 671 eachChild = eachChild.getNextSibling(); 672 } 673 return null; 674 } 675 676 protected SOAPElement findAndConvertChildElement(NameImpl name) { 677 Iterator<Node> eachChild = getChildElementNodes(); 678 while (eachChild.hasNext()) { 679 SOAPElement child = (SOAPElement) eachChild.next(); 680 if (child.getElementName().equals(name)) { 681 return child; 682 } 683 } 684 685 return null; 686 } 687 688 @Override 689 public SOAPElement addTextNode(String text) throws SOAPException { 690 if (text.startsWith(CDATAImpl.cdataUC) 691 || text.startsWith(CDATAImpl.cdataLC)) 692 return addCDATA( 693 text.substring(CDATAImpl.cdataUC.length(), text.length() - 3)); 694 return addText(text); 695 } 696 697 protected SOAPElement addCDATA(String text) throws SOAPException { 698 org.w3c.dom.Text cdata = 699 getOwnerDocument().createCDATASection(text); 700 addNode(cdata); 701 return this; 702 } 703 704 protected SOAPElement addText(String text) throws SOAPException { 705 org.w3c.dom.Text textNode = 706 getOwnerDocument().createTextNode(text); 707 addNode(textNode); 708 return this; 709 } 710 711 @Override 712 public SOAPElement addAttribute(Name name, String value) 713 throws SOAPException { 714 addAttributeBare(name, value); 715 if (!"".equals(name.getURI())) { 716 ensureNamespaceIsDeclared(name.getPrefix(), name.getURI()); 717 } 718 return this; 719 } 720 721 @Override 722 public SOAPElement addAttribute(QName qname, String value) 723 throws SOAPException { 724 addAttributeBare(qname, value); 725 if (!"".equals(qname.getNamespaceURI())) { 726 ensureNamespaceIsDeclared(qname.getPrefix(), qname.getNamespaceURI()); 727 } 728 return this; 729 } 730 731 private void addAttributeBare(Name name, String value) { 732 addAttributeBare( 733 name.getURI(), 734 name.getPrefix(), 735 name.getQualifiedName(), 736 value); 737 } 738 private void addAttributeBare(QName name, String value) { 739 addAttributeBare( 740 name.getNamespaceURI(), 741 name.getPrefix(), 742 getQualifiedName(name), 743 value); 744 } 745 746 private void addAttributeBare( 747 String uri, 748 String prefix, 749 String qualifiedName, 750 String value) { 751 752 uri = uri.length() == 0 ? null : uri; 753 if (qualifiedName.equals("xmlns")) { 754 uri = XMLNS_URI; 755 } 756 757 if (uri == null) { 758 setAttribute(qualifiedName, value); 759 } else { 760 setAttributeNS(uri, qualifiedName, value); 761 } 762 } 763 764 @Override 765 public SOAPElement addNamespaceDeclaration(String prefix, String uri) 766 throws SOAPException { 767 if (prefix.length() > 0) { 768 setAttributeNS(XMLNS_URI, "xmlns:" + prefix, uri); 769 } else { 770 setAttributeNS(XMLNS_URI, "xmlns", uri); 771 } 772 //Fix for CR:6474641 773 //tryToFindEncodingStyleAttributeName(); 774 return this; 775 } 776 777 @Override 778 public String getAttributeValue(Name name) { 779 return getAttributeValueFrom(this, name); 780 } 781 782 @Override 783 public String getAttributeValue(QName qname) { 784 return getAttributeValueFrom( 785 this, 786 qname.getNamespaceURI(), 787 qname.getLocalPart(), 788 qname.getPrefix(), 789 getQualifiedName(qname)); 790 } 791 792 @Override 793 public Iterator<Name> getAllAttributes() { 794 Iterator<Name> i = getAllAttributesFrom(this); 795 ArrayList<Name> list = new ArrayList<>(); 796 while (i.hasNext()) { 797 Name name = i.next(); 798 if (!"xmlns".equalsIgnoreCase(name.getPrefix())) 799 list.add(name); 800 } 801 return list.iterator(); 802 } 803 804 @Override 805 public Iterator<QName> getAllAttributesAsQNames() { 806 Iterator<Name> i = getAllAttributesFrom(this); 807 ArrayList<QName> list = new ArrayList<>(); 808 while (i.hasNext()) { 809 Name name = i.next(); 810 if (!"xmlns".equalsIgnoreCase(name.getPrefix())) { 811 list.add(NameImpl.convertToQName(name)); 812 } 813 } 814 return list.iterator(); 815 } 816 817 818 @Override 819 public Iterator<String> getNamespacePrefixes() { 820 return doGetNamespacePrefixes(false); 821 } 822 823 @Override 824 public Iterator<String> getVisibleNamespacePrefixes() { 825 return doGetNamespacePrefixes(true); 826 } 827 828 protected Iterator<String> doGetNamespacePrefixes(final boolean deep) { 829 return new Iterator<String>() { 830 String next = null; 831 String last = null; 832 NamespaceContextIterator eachNamespace = 833 getNamespaceContextNodes(deep); 834 835 void findNext() { 836 while (next == null && eachNamespace.hasNext()) { 837 String attributeKey = 838 eachNamespace.nextNamespaceAttr().getNodeName(); 839 if (attributeKey.startsWith("xmlns:")) { 840 next = attributeKey.substring("xmlns:".length()); 841 } 842 } 843 } 844 845 @Override 846 public boolean hasNext() { 847 findNext(); 848 return next != null; 849 } 850 851 @Override 852 public String next() { 853 findNext(); 854 if (next == null) { 855 throw new NoSuchElementException(); 856 } 857 858 last = next; 859 next = null; 860 return last; 861 } 862 863 @Override 864 public void remove() { 865 if (last == null) { 866 throw new IllegalStateException(); 867 } 868 eachNamespace.remove(); 869 next = null; 870 last = null; 871 } 872 }; 873 } 874 875 @Override 876 public Name getElementName() { 877 return NameImpl.convertToName(elementQName); 878 } 879 880 @Override 881 public QName getElementQName() { 882 return elementQName; 883 } 884 885 @Override 886 public boolean removeAttribute(Name name) { 887 return removeAttribute(name.getURI(), name.getLocalName()); 888 } 889 890 @Override 891 public boolean removeAttribute(QName name) { 892 return removeAttribute(name.getNamespaceURI(), name.getLocalPart()); 893 } 894 895 private boolean removeAttribute(String uri, String localName) { 896 String nonzeroLengthUri = 897 (uri == null || uri.length() == 0) ? null : uri; 898 org.w3c.dom.Attr attribute = 899 getAttributeNodeNS(nonzeroLengthUri, localName); 900 if (attribute == null) { 901 return false; 902 } 903 removeAttributeNode(attribute); 904 return true; 905 } 906 907 @Override 908 public boolean removeNamespaceDeclaration(String prefix) { 909 org.w3c.dom.Attr declaration = getNamespaceAttr(prefix); 910 if (declaration == null) { 911 return false; 912 } 913 try { 914 removeAttributeNode(declaration); 915 } catch (DOMException de) { 916 // ignore 917 } 918 return true; 919 } 920 921 @Override 922 public Iterator<javax.xml.soap.Node> getChildElements() { 923 return getChildElementsFrom(this); 924 } 925 926 protected SOAPElement convertToSoapElement(Element element) { 927 final Node soapNode = soapDocument.findIfPresent(element); 928 if (soapNode instanceof SOAPElement) { 929 return (SOAPElement) soapNode; 930 } else { 931 return replaceElementWithSOAPElement( 932 element, 933 (ElementImpl) createElement(NameImpl.copyElementName(element))); 934 } 935 } 936 937 protected TextImpl convertToSoapText(CharacterData characterData) { 938 final Node soapNode = getSoapDocument().findIfPresent(characterData); 939 if (soapNode instanceof TextImpl) { 940 return (TextImpl) soapNode; 941 } else { 942 TextImpl t = null; 943 switch (characterData.getNodeType()) { 944 case CDATA_SECTION_NODE: 945 t = new CDATAImpl(getSoapDocument(), characterData.getData()); 946 break; 947 case COMMENT_NODE: 948 t = new SOAPCommentImpl(getSoapDocument(), characterData.getData()); 949 break; 950 case TEXT_NODE: 951 t = new SOAPTextImpl(getSoapDocument(), characterData.getData()); 952 break; 953 } 954 Node parent = getSoapDocument().find(characterData.getParentNode()); 955 if (parent != null) { 956 parent.replaceChild(t, characterData); 957 } // XXX else throw an exception? 958 959 return t; 960 961 // return replaceElementWithSOAPElement( 962 // element, 963 // (ElementImpl) createElement(NameImpl.copyElementName(element))); 964 } 965 } 966 967 protected SOAPElement replaceElementWithSOAPElement( 968 Element element, 969 ElementImpl copy) { 970 971 Iterator<Name> eachAttribute = getAllAttributesFrom(element); 972 while (eachAttribute.hasNext()) { 973 Name name = eachAttribute.next(); 974 copy.addAttributeBare(name, getAttributeValueFrom(element, name)); 975 } 976 977 Iterator<Node> eachChild = getChildElementsFromDOM(element); 978 while (eachChild.hasNext()) { 979 Node nextChild = eachChild.next(); 980 copy.insertBefore(nextChild, null); 981 } 982 983 Node parent = soapDocument.find(element.getParentNode()); 984 if (parent != null) { 985 parent.replaceChild(copy, element); 986 } // XXX else throw an exception? 987 988 return copy; 989 } 990 991 private Iterator<Node> getChildElementsFromDOM(final Element el) { 992 return new Iterator<Node>() { 993 Node next = el.getFirstChild(); 994 Node nextNext = null; 995 Node last = null; 996 Node soapElement = getSoapDocument().findIfPresent(el); 997 998 @Override 999 public boolean hasNext() { 1000 if (next != null) { 1001 return true; 1002 } 1003 if (nextNext != null) { 1004 next = nextNext; 1005 } 1006 1007 return next != null; 1008 } 1009 1010 public Node next() { 1011 if (hasNext()) { 1012 last = next; 1013 next = null; 1014 1015 if ((soapElement instanceof ElementImpl) 1016 && (last instanceof Element)) { 1017 last = 1018 ((ElementImpl) soapElement).convertToSoapElement( 1019 (Element) last); 1020 } else if ((soapElement instanceof ElementImpl) && (last instanceof CharacterData)) { 1021 last = ((ElementImpl) soapElement).convertToSoapText( 1022 (CharacterData) last); 1023 } 1024 1025 nextNext = last.getNextSibling(); 1026 return last; 1027 } 1028 throw new NoSuchElementException(); 1029 } 1030 1031 @Override 1032 public void remove() { 1033 if (last == null) { 1034 throw new IllegalStateException(); 1035 } 1036 Node target = last; 1037 last = null; 1038 el.removeChild(target); 1039 } 1040 }; 1041 } 1042 1043 protected Iterator<Node> getChildElementNodes() { 1044 return new Iterator<Node>() { 1045 Iterator<javax.xml.soap.Node> eachNode = getChildElements(); 1046 Node next = null; 1047 Node last = null; 1048 1049 @Override 1050 public boolean hasNext() { 1051 if (next == null) { 1052 while (eachNode.hasNext()) { 1053 Node node = eachNode.next(); 1054 if (node instanceof Element) { 1055 next = soapDocument.findIfPresent(node); 1056 break; 1057 } 1058 } 1059 } 1060 return next != null; 1061 } 1062 1063 @Override 1064 public javax.xml.soap.Node next() { 1065 if (hasNext()) { 1066 last = next; 1067 next = null; 1068 return (javax.xml.soap.Node) last; 1069 } 1070 throw new NoSuchElementException(); 1071 } 1072 1073 @Override 1074 public void remove() { 1075 if (last == null) { 1076 throw new IllegalStateException(); 1077 } 1078 Node target = last; 1079 last = null; 1080 removeChild(target); 1081 } 1082 }; 1083 } 1084 1085 @Override 1086 public Iterator<javax.xml.soap.Node> getChildElements(final Name name) { 1087 return getChildElements(name.getURI(), name.getLocalName()); 1088 } 1089 1090 @Override 1091 public Iterator<javax.xml.soap.Node> getChildElements(final QName qname) { 1092 return getChildElements(qname.getNamespaceURI(), qname.getLocalPart()); 1093 } 1094 1095 private Iterator<javax.xml.soap.Node> getChildElements(final String nameUri, final String nameLocal) { 1096 return new Iterator<javax.xml.soap.Node>() { 1097 Iterator<Node> eachElement = getChildElementNodes(); 1098 Node next = null; 1099 Node last = null; 1100 1101 @Override 1102 public boolean hasNext() { 1103 if (next == null) { 1104 while (eachElement.hasNext()) { 1105 Node element = eachElement.next(); 1106 String elementUri = element.getNamespaceURI(); 1107 elementUri = elementUri == null ? "" : elementUri; 1108 String elementName = element.getLocalName(); 1109 if (elementUri.equals(nameUri) 1110 && elementName.equals(nameLocal)) { 1111 next = element; 1112 break; 1113 } 1114 } 1115 } 1116 return next != null; 1117 } 1118 1119 @Override 1120 public javax.xml.soap.Node next() { 1121 if (!hasNext()) { 1122 throw new NoSuchElementException(); 1123 } 1124 last = next; 1125 next = null; 1126 return (javax.xml.soap.Node) last; 1127 } 1128 1129 @Override 1130 public void remove() { 1131 if (last == null) { 1132 throw new IllegalStateException(); 1133 } 1134 Node target = last; 1135 last = null; 1136 removeChild(target); 1137 } 1138 }; 1139 } 1140 1141 @Override 1142 public void removeContents() { 1143 Node currentChild = getFirstChild(); 1144 1145 while (currentChild != null) { 1146 Node temp = currentChild.getNextSibling(); 1147 if (currentChild instanceof javax.xml.soap.Node) { 1148 ((javax.xml.soap.Node) currentChild).detachNode(); 1149 } else { 1150 Node parent = currentChild.getParentNode(); 1151 if (parent != null) { 1152 parent.removeChild(currentChild); 1153 } 1154 1155 } 1156 currentChild = temp; 1157 } 1158 } 1159 1160 @Override 1161 public void setEncodingStyle(String encodingStyle) throws SOAPException { 1162 if (!"".equals(encodingStyle)) { 1163 try { 1164 new URI(encodingStyle); 1165 } catch (URISyntaxException m) { 1166 log.log( 1167 Level.SEVERE, 1168 "SAAJ0105.impl.encoding.style.mustbe.valid.URI", 1169 new String[] { encodingStyle }); 1170 throw new IllegalArgumentException( 1171 "Encoding style (" + encodingStyle + ") should be a valid URI"); 1172 } 1173 } 1174 encodingStyleAttribute.setValue(encodingStyle); 1175 tryToFindEncodingStyleAttributeName(); 1176 } 1177 1178 @Override 1179 public String getEncodingStyle() { 1180 String encodingStyle = encodingStyleAttribute.getValue(); 1181 if (encodingStyle != null) 1182 return encodingStyle; 1183 String soapNamespace = getSOAPNamespace(); 1184 if (soapNamespace != null) { 1185 Attr attr = getAttributeNodeNS(soapNamespace, "encodingStyle"); 1186 if (attr != null) { 1187 encodingStyle = attr.getValue(); 1188 try { 1189 setEncodingStyle(encodingStyle); 1190 } catch (SOAPException se) { 1191 // has to be ignored 1192 } 1193 return encodingStyle; 1194 } 1195 } 1196 return null; 1197 } 1198 1199 // Node methods 1200 @Override 1201 public String getValue() { 1202 javax.xml.soap.Node valueNode = getValueNode(); 1203 return valueNode == null ? null : valueNode.getValue(); 1204 } 1205 1206 @Override 1207 public void setValue(String value) { 1208 Node valueNode = getValueNodeStrict(); 1209 if (valueNode != null) { 1210 valueNode.setNodeValue(value); 1211 } else { 1212 try { 1213 addTextNode(value); 1214 } catch (SOAPException e) { 1215 throw new RuntimeException(e.getMessage()); 1216 } 1217 } 1218 } 1219 1220 protected Node getValueNodeStrict() { 1221 Node node = getFirstChild(); 1222 if (node != null) { 1223 if (node.getNextSibling() == null 1224 && node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) { 1225 return node; 1226 } else { 1227 log.severe("SAAJ0107.impl.elem.child.not.single.text"); 1228 throw new IllegalStateException(); 1229 } 1230 } 1231 1232 return null; 1233 } 1234 1235 protected javax.xml.soap.Node getValueNode() { 1236 Iterator<javax.xml.soap.Node> i = getChildElements(); 1237 while (i.hasNext()) { 1238 Node n = i.next(); 1239 if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE || 1240 n.getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) { 1241 // TODO: Hack to fix text node split into multiple lines. 1242 normalize(); 1243 // Should remove the normalization step when this gets fixed in 1244 // DOM/Xerces. 1245 return soapDocument.find(n); 1246 } 1247 } 1248 return null; 1249 } 1250 1251 @Override 1252 public void setParentElement(SOAPElement element) throws SOAPException { 1253 if (element == null) { 1254 log.severe("SAAJ0106.impl.no.null.to.parent.elem"); 1255 throw new SOAPException("Cannot pass NULL to setParentElement"); 1256 } 1257 element.addChildElement(this); 1258 findEncodingStyleAttributeName(); 1259 } 1260 1261 protected void findEncodingStyleAttributeName() throws SOAPException { 1262 String soapNamespace = getSOAPNamespace(); 1263 if (soapNamespace != null) { 1264 String soapNamespacePrefix = getNamespacePrefix(soapNamespace); 1265 if (soapNamespacePrefix != null) { 1266 setEncodingStyleNamespace(soapNamespace, soapNamespacePrefix); 1267 } 1268 } 1269 } 1270 1271 protected void setEncodingStyleNamespace( 1272 String soapNamespace, 1273 String soapNamespacePrefix) 1274 throws SOAPException { 1275 Name encodingStyleAttributeName = 1276 NameImpl.create( 1277 "encodingStyle", 1278 soapNamespacePrefix, 1279 soapNamespace); 1280 encodingStyleAttribute.setName(encodingStyleAttributeName); 1281 } 1282 1283 @Override 1284 public SOAPElement getParentElement() { 1285 Node parentNode = getParentNode(); 1286 if (parentNode instanceof SOAPDocument) { 1287 return null; 1288 } 1289 return (SOAPElement) soapDocument.find(parentNode); 1290 } 1291 1292 protected String getSOAPNamespace() { 1293 String soapNamespace = null; 1294 1295 SOAPElement antecedent = this; 1296 while (antecedent != null) { 1297 Name antecedentName = antecedent.getElementName(); 1298 String antecedentNamespace = antecedentName.getURI(); 1299 1300 if (NameImpl.SOAP11_NAMESPACE.equals(antecedentNamespace) 1301 || NameImpl.SOAP12_NAMESPACE.equals(antecedentNamespace)) { 1302 1303 soapNamespace = antecedentNamespace; 1304 break; 1305 } 1306 1307 antecedent = antecedent.getParentElement(); 1308 } 1309 1310 return soapNamespace; 1311 } 1312 1313 @Override 1314 public void detachNode() { 1315 Node parent = getParentNode(); 1316 if (parent != null) { 1317 parent.removeChild(element); 1318 } 1319 encodingStyleAttribute.clearNameAndValue(); 1320 // Fix for CR: 6474641 1321 //tryToFindEncodingStyleAttributeName(); 1322 } 1323 1324 public void tryToFindEncodingStyleAttributeName() { 1325 try { 1326 findEncodingStyleAttributeName(); 1327 } catch (SOAPException e) { /*okay to fail*/ 1328 } 1329 } 1330 1331 @Override 1332 public void recycleNode() { 1333 detachNode(); 1334 // TBD 1335 // - add this to the factory so subsequent 1336 // creations can reuse this object. 1337 } 1338 1339 class AttributeManager { 1340 Name attributeName = null; 1341 String attributeValue = null; 1342 1343 public void setName(Name newName) throws SOAPException { 1344 clearAttribute(); 1345 attributeName = newName; 1346 reconcileAttribute(); 1347 } 1348 public void clearName() { 1349 clearAttribute(); 1350 attributeName = null; 1351 } 1352 public void setValue(String value) throws SOAPException { 1353 attributeValue = value; 1354 reconcileAttribute(); 1355 } 1356 public Name getName() { 1357 return attributeName; 1358 } 1359 public String getValue() { 1360 return attributeValue; 1361 } 1362 1363 /** Note: to be used only in detachNode method */ 1364 public void clearNameAndValue() { 1365 attributeName = null; 1366 attributeValue = null; 1367 } 1368 1369 private void reconcileAttribute() throws SOAPException { 1370 if (attributeName != null) { 1371 removeAttribute(attributeName); 1372 if (attributeValue != null) { 1373 addAttribute(attributeName, attributeValue); 1374 } 1375 } 1376 } 1377 private void clearAttribute() { 1378 if (attributeName != null) { 1379 removeAttribute(attributeName); 1380 } 1381 } 1382 } 1383 1384 protected static org.w3c.dom.Attr getNamespaceAttrFrom( 1385 Element element, 1386 String prefix) { 1387 NamespaceContextIterator eachNamespace = 1388 new NamespaceContextIterator(element); 1389 while (eachNamespace.hasNext()) { 1390 org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr(); 1391 String declaredPrefix = 1392 NameImpl.getLocalNameFromTagName(namespaceDecl.getNodeName()); 1393 if (declaredPrefix.equals(prefix)) { 1394 return namespaceDecl; 1395 } 1396 } 1397 return null; 1398 } 1399 1400 protected static Iterator<Name> getAllAttributesFrom(final Element element) { 1401 final NamedNodeMap attributes = element.getAttributes(); 1402 1403 return new Iterator<Name>() { 1404 int attributesLength = attributes.getLength(); 1405 int attributeIndex = 0; 1406 String currentName; 1407 1408 @Override 1409 public boolean hasNext() { 1410 return attributeIndex < attributesLength; 1411 } 1412 1413 @Override 1414 public Name next() { 1415 if (!hasNext()) { 1416 throw new NoSuchElementException(); 1417 } 1418 Node current = attributes.item(attributeIndex++); 1419 currentName = current.getNodeName(); 1420 1421 String prefix = NameImpl.getPrefixFromTagName(currentName); 1422 if (prefix.length() == 0) { 1423 return NameImpl.createFromUnqualifiedName(currentName); 1424 } else { 1425 Name attributeName = 1426 NameImpl.createFromQualifiedName( 1427 currentName, 1428 current.getNamespaceURI()); 1429 return attributeName; 1430 } 1431 } 1432 1433 @Override 1434 public void remove() { 1435 if (currentName == null) { 1436 throw new IllegalStateException(); 1437 } 1438 attributes.removeNamedItem(currentName); 1439 } 1440 }; 1441 } 1442 1443 protected static String getAttributeValueFrom(Element element, Name name) { 1444 return getAttributeValueFrom( 1445 element, 1446 name.getURI(), 1447 name.getLocalName(), 1448 name.getPrefix(), 1449 name.getQualifiedName()); 1450 } 1451 1452 private static String getAttributeValueFrom( 1453 Element element, 1454 String uri, 1455 String localName, 1456 String prefix, 1457 String qualifiedName) { 1458 1459 String nonzeroLengthUri = 1460 (uri == null || uri.length() == 0) ? null : uri; 1461 1462 boolean mustUseGetAttributeNodeNS = (nonzeroLengthUri != null); 1463 1464 if (mustUseGetAttributeNodeNS) { 1465 1466 if (!element.hasAttributeNS(uri, localName)) { 1467 return null; 1468 } 1469 1470 String attrValue = 1471 element.getAttributeNS(nonzeroLengthUri, localName); 1472 1473 return attrValue; 1474 } 1475 1476 Attr attribute = null; 1477 attribute = element.getAttributeNode(qualifiedName); 1478 1479 return attribute == null ? null : attribute.getValue(); 1480 } 1481 1482 protected Iterator<javax.xml.soap.Node> getChildElementsFrom(final Element element) { 1483 return new Iterator<javax.xml.soap.Node>() { 1484 Node next = element.getFirstChild(); 1485 Node nextNext = null; 1486 Node last = null; 1487 Node soapElement = soapDocument.findIfPresent(element); 1488 1489 @Override 1490 public boolean hasNext() { 1491 if (next != null) { 1492 return true; 1493 } 1494 if (nextNext != null) { 1495 next = nextNext; 1496 } 1497 1498 return next != null; 1499 } 1500 1501 @Override 1502 public javax.xml.soap.Node next() { 1503 if (hasNext()) { 1504 last = next; 1505 next = null; 1506 1507 if ((soapElement instanceof ElementImpl) 1508 && (last instanceof Element)) { 1509 last = 1510 ((ElementImpl) soapElement).convertToSoapElement( 1511 (Element) last); 1512 } 1513 1514 nextNext = last.getNextSibling(); 1515 return (javax.xml.soap.Node) soapDocument.findIfPresent(last); 1516 } 1517 throw new NoSuchElementException(); 1518 } 1519 1520 @Override 1521 public void remove() { 1522 if (last == null) { 1523 throw new IllegalStateException(); 1524 } 1525 Node target = last; 1526 last = null; 1527 element.removeChild(target); 1528 } 1529 }; 1530 } 1531 1532 public static String getQualifiedName(QName name) { 1533 String prefix = name.getPrefix(); 1534 String localName = name.getLocalPart(); 1535 String qualifiedName = null; 1536 1537 if (prefix != null && prefix.length() > 0) { 1538 qualifiedName = prefix + ":" + localName; 1539 } else { 1540 qualifiedName = localName; 1541 } 1542 return qualifiedName; 1543 } 1544 1545 public static String getLocalPart(String qualifiedName) { 1546 if (qualifiedName == null) { 1547 // Log 1548 throw new IllegalArgumentException("Cannot get local name for a \"null\" qualified name"); 1549 } 1550 1551 int index = qualifiedName.indexOf(':'); 1552 if (index < 0) 1553 return qualifiedName; 1554 else 1555 return qualifiedName.substring(index + 1); 1556 } 1557 1558 public static String getPrefix(String qualifiedName) { 1559 if (qualifiedName == null) { 1560 // Log 1561 throw new IllegalArgumentException("Cannot get prefix for a \"null\" qualified name"); 1562 } 1563 1564 int index = qualifiedName.indexOf(':'); 1565 if (index < 0) 1566 return ""; 1567 else 1568 return qualifiedName.substring(0, index); 1569 } 1570 1571 protected boolean isNamespaceQualified(Name name) { 1572 return !"".equals(name.getURI()); 1573 } 1574 1575 protected boolean isNamespaceQualified(QName name) { 1576 return !"".equals(name.getNamespaceURI()); 1577 } 1578 1579 //TODO: This is a temporary SAAJ workaround for optimizing XWS 1580 // should be removed once the corresponding JAXP bug is fixed 1581 // It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe) 1582 @Override 1583 public void setAttributeNS( 1584 String namespaceURI,String qualifiedName, String value) { 1585 int index = qualifiedName.indexOf(':'); 1586 String localName; 1587 if (index < 0) 1588 localName = qualifiedName; 1589 else 1590 localName = qualifiedName.substring(index + 1); 1591 1592 // Workaround for bug 6467808 - This needs to be fixed in JAXP 1593 1594 // Rolling back this fix, this is a wrong fix, infact its causing other regressions in JAXWS tck and 1595 // other tests, because of this change the namespace declarations on soapenv:Fault element are never 1596 // picked up. The fix for bug 6467808 should be in JAXP. 1597 // if(elementQName.getLocalPart().equals("Fault") && 1598 // (SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE.equals(value) || 1599 // SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE.equals(value))) 1600 // return; 1601 1602 element.setAttributeNS(namespaceURI,qualifiedName,value); 1603 //String tmpLocalName = this.getLocalName(); 1604 String tmpURI = this.getNamespaceURI(); 1605 boolean isIDNS = false; 1606 if( tmpURI != null && (tmpURI.equals(DSIG_NS) || tmpURI.equals(XENC_NS))){ 1607 isIDNS = true; 1608 } 1609 //No need to check for Signature/encryption element 1610 //just check for namespace. 1611 if(localName.equals("Id")){ 1612 if(namespaceURI == null || namespaceURI.equals("")){ 1613 setIdAttribute(localName,true); 1614 }else if(isIDNS || WSU_NS.equals(namespaceURI)){ 1615 setIdAttributeNS(namespaceURI,localName,true); 1616 } 1617 } 1618 1619 } 1620 1621 @Override 1622 public void removeAttributeNS(String namespaceURI, String localName) throws DOMException { 1623 element.removeAttributeNS(namespaceURI, localName); 1624 } 1625 1626 @Override 1627 public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException { 1628 return element.getAttributeNodeNS(namespaceURI, localName); 1629 } 1630 1631 @Override 1632 public Attr setAttributeNodeNS(Attr newAttr) throws DOMException { 1633 return element.setAttributeNodeNS(newAttr); 1634 } 1635 1636 @Override 1637 public NodeList getElementsByTagNameNS(String namespaceURI, String localName) throws DOMException { 1638 return new NodeListImpl(soapDocument, element.getElementsByTagNameNS(namespaceURI, localName)); 1639 } 1640 1641 @Override 1642 public boolean hasAttribute(String name) { 1643 return element.hasAttribute(name); 1644 } 1645 1646 @Override 1647 public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException { 1648 return element.hasAttributeNS(namespaceURI, localName); 1649 } 1650 1651 @Override 1652 public TypeInfo getSchemaTypeInfo() { 1653 return element.getSchemaTypeInfo(); 1654 } 1655 1656 @Override 1657 public void setIdAttribute(String name, boolean isId) throws DOMException { 1658 element.setIdAttribute(name, isId); 1659 } 1660 1661 @Override 1662 public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException { 1663 element.setIdAttributeNS(namespaceURI, localName, isId); 1664 } 1665 1666 @Override 1667 public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException { 1668 element.setIdAttributeNode(idAttr, isId); 1669 } 1670 1671 @Override 1672 public String getNodeName() { 1673 return element.getNodeName(); 1674 } 1675 1676 @Override 1677 public String getNodeValue() throws DOMException { 1678 return element.getNodeValue(); 1679 } 1680 1681 @Override 1682 public void setNodeValue(String nodeValue) throws DOMException { 1683 element.setNodeValue(nodeValue); 1684 } 1685 1686 @Override 1687 public short getNodeType() { 1688 return element.getNodeType(); 1689 } 1690 1691 @Override 1692 public Node getParentNode() { 1693 return soapDocument.find(element.getParentNode()); 1694 } 1695 1696 @Override 1697 public NodeList getChildNodes() { 1698 return new NodeListImpl(soapDocument, element.getChildNodes()); 1699 } 1700 1701 @Override 1702 public Node getFirstChild() { 1703 return soapDocument.findIfPresent(element.getFirstChild()); 1704 } 1705 1706 @Override 1707 public Node getLastChild() { 1708 return soapDocument.findIfPresent(element.getLastChild()); 1709 } 1710 1711 @Override 1712 public Node getPreviousSibling() { 1713 return soapDocument.findIfPresent(element.getPreviousSibling()); 1714 } 1715 1716 @Override 1717 public Node getNextSibling() { 1718 return soapDocument.findIfPresent(element.getNextSibling()); 1719 } 1720 1721 @Override 1722 public NamedNodeMap getAttributes() { 1723 NamedNodeMap attributes = element.getAttributes(); 1724 if (attributes == null) { 1725 return null; 1726 } 1727 return new NamedNodeMapImpl(attributes, soapDocument); 1728 } 1729 1730 public Element getDomElement() { 1731 return element; 1732 } 1733 1734 public SOAPDocumentImpl getSoapDocument() { 1735 return soapDocument; 1736 } 1737 }