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