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