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 }