src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/impl/ElementImpl.java

Thu, 24 May 2018 17:55:52 +0800

author
aoqi
date
Thu, 24 May 2018 17:55:52 +0800
changeset 1435
a90b319bae7a
parent 1341
e5cc521294d8
parent 637
9c07ef4934dd
permissions
-rw-r--r--

Merge

     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  */
    26 package com.sun.xml.internal.messaging.saaj.soap.impl;
    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;
    34 import javax.xml.namespace.QName;
    35 import javax.xml.soap.*;
    37 import org.w3c.dom.*;
    38 import org.w3c.dom.Node;
    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.*;
    46 public class ElementImpl
    47     extends com.sun.org.apache.xerces.internal.dom.ElementNSImpl
    48     implements SOAPElement, SOAPBodyElement {
    50     public static final String DSIG_NS = "http://www.w3.org/2000/09/xmldsig#".intern();
    51     public static final String XENC_NS = "http://www.w3.org/2001/04/xmlenc#".intern();
    52     public static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd".intern();
    54     private AttributeManager encodingStyleAttribute = new AttributeManager();
    56     protected QName elementQName;
    58     protected static final Logger log =
    59         Logger.getLogger(LogDomainConstants.SOAP_IMPL_DOMAIN,
    60                          "com.sun.xml.internal.messaging.saaj.soap.impl.LocalStrings");
    62     /**
    63      * XML Information Set REC
    64      * all namespace attributes (including those named xmlns,
    65      * whose [prefix] property has no value) have a namespace URI of http://www.w3.org/2000/xmlns/
    66      */
    67     public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/".intern();
    69     /**
    70      * The XML Namespace ("http://www.w3.org/XML/1998/namespace"). This is
    71      * the Namespace URI that is automatically mapped to the "xml" prefix.
    72      */
    73     public final static String XML_URI = "http://www.w3.org/XML/1998/namespace".intern();
    75     public ElementImpl(SOAPDocumentImpl ownerDoc, Name name) {
    76         super(
    77             ownerDoc,
    78             name.getURI(),
    79             name.getQualifiedName(),
    80             name.getLocalName());
    81         elementQName = NameImpl.convertToQName(name);
    82     }
    84     public ElementImpl(SOAPDocumentImpl ownerDoc, QName name) {
    85         super(
    86             ownerDoc,
    87             name.getNamespaceURI(),
    88             getQualifiedName(name),
    89             name.getLocalPart());
    90         elementQName = name;
    91     }
    93     public ElementImpl(
    94         SOAPDocumentImpl ownerDoc,
    95         String uri,
    96         String qualifiedName) {
    98         super(ownerDoc, uri, qualifiedName);
    99         elementQName =
   100             new QName(uri, getLocalPart(qualifiedName), getPrefix(qualifiedName));
   101     }
   103     public void ensureNamespaceIsDeclared(String prefix, String uri) {
   104         String alreadyDeclaredUri = getNamespaceURI(prefix);
   105         if (alreadyDeclaredUri == null || !alreadyDeclaredUri.equals(uri)) {
   106             try {
   107                 addNamespaceDeclaration(prefix, uri);
   108             } catch (SOAPException e) { /*ignore*/
   109             }
   110         }
   111     }
   113     public Document getOwnerDocument() {
   114         Document doc = super.getOwnerDocument();
   115         if (doc instanceof SOAPDocument)
   116             return ((SOAPDocument) doc).getDocument();
   117         else
   118             return doc;
   119     }
   121     public SOAPElement addChildElement(Name name) throws SOAPException {
   122         return  addElement(name);
   123     }
   125     public SOAPElement addChildElement(QName qname) throws SOAPException {
   126         return  addElement(qname);
   127     }
   129     public SOAPElement addChildElement(String localName) throws SOAPException {
   130         String nsUri = getNamespaceURI("");
   131         Name name = (nsUri == null || nsUri.isEmpty())
   132                 ?  NameImpl.createFromUnqualifiedName(localName)
   133                 :  NameImpl.createFromQualifiedName(localName, nsUri);
   134         return addChildElement(name);
   135     }
   137     public SOAPElement addChildElement(String localName, String prefix)
   138         throws SOAPException {
   139         String uri = getNamespaceURI(prefix);
   140         if (uri == null) {
   141             log.log(
   142                 Level.SEVERE,
   143                 "SAAJ0101.impl.parent.of.body.elem.mustbe.body",
   144                 new String[] { prefix });
   145             throw new SOAPExceptionImpl(
   146                 "Unable to locate namespace for prefix " + prefix);
   147         }
   148         return addChildElement(localName, prefix, uri);
   149     }
   151     public String getNamespaceURI(String prefix) {
   153         if ("xmlns".equals(prefix)) {
   154             return XMLNS_URI;
   155         }
   157         if("xml".equals(prefix)) {
   158             return XML_URI;
   159         }
   161         if ("".equals(prefix)) {
   163             org.w3c.dom.Node currentAncestor = this;
   164             while (currentAncestor != null &&
   165                    !(currentAncestor instanceof Document)) {
   167                 if (currentAncestor instanceof ElementImpl) {
   168                     QName name = ((ElementImpl) currentAncestor).getElementQName();
   169                     /*
   170                     if (prefix.equals(name.getPrefix())) {
   171                         String uri = name.getNamespaceURI();
   172                         if ("".equals(uri)) {
   173                             return null;
   174                         }
   175                         else {
   176                             return uri;
   177                         }
   178                     }*/
   179                     if (((Element) currentAncestor).hasAttributeNS(
   180                             XMLNS_URI, "xmlns")) {
   182                         String uri =
   183                             ((Element) currentAncestor).getAttributeNS(
   184                                 XMLNS_URI, "xmlns");
   185                         if ("".equals(uri))
   186                             return null;
   187                         else {
   188                             return uri;
   189                         }
   190                     }
   191                 }
   192                 currentAncestor = currentAncestor.getParentNode();
   193             }
   195         } else if (prefix != null) {
   196             // Find if there's an ancester whose name contains this prefix
   197             org.w3c.dom.Node currentAncestor = this;
   199 //            String uri = currentAncestor.lookupNamespaceURI(prefix);
   200 //            return uri;
   201             while (currentAncestor != null &&
   202                    !(currentAncestor instanceof Document)) {
   204                /* if (prefix.equals(currentAncestor.getPrefix())) {
   205                     String uri = currentAncestor.getNamespaceURI();
   206                     // this is because the javadoc says getNamespaceURI() is not a computed value
   207                     // and URI for a non-empty prefix cannot be null
   208                     if (uri != null)
   209                         return uri;
   210                 }*/
   211                 //String uri = currentAncestor.lookupNamespaceURI(prefix);
   212                 //if (uri != null) {
   213                 //    return uri;
   214                 //}
   216                 if (((Element) currentAncestor).hasAttributeNS(
   217                         XMLNS_URI, prefix)) {
   218                     return ((Element) currentAncestor).getAttributeNS(
   219                                XMLNS_URI, prefix);
   220                 }
   222                 currentAncestor = currentAncestor.getParentNode();
   223             }
   224         }
   226         return null;
   227     }
   229     public SOAPElement setElementQName(QName newName) throws SOAPException {
   230         ElementImpl copy =
   231             new ElementImpl((SOAPDocumentImpl) getOwnerDocument(), newName);
   232         return replaceElementWithSOAPElement(this,copy);
   233     }
   235     public QName createQName(String localName, String prefix)
   236         throws SOAPException {
   237         String uri = getNamespaceURI(prefix);
   238         if (uri == null) {
   239             log.log(Level.SEVERE, "SAAJ0102.impl.cannot.locate.ns",
   240                     new Object[] {prefix});
   241             throw new SOAPException("Unable to locate namespace for prefix "
   242                                     + prefix);
   243         }
   244         return new QName(uri, localName, prefix);
   245     }
   247     public String getNamespacePrefix(String uri) {
   249         NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
   250         while (eachNamespace.hasNext()) {
   251             org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
   252             if (namespaceDecl.getNodeValue().equals(uri)) {
   253                 String candidatePrefix = namespaceDecl.getLocalName();
   254                 if ("xmlns".equals(candidatePrefix))
   255                     return "";
   256                 else
   257                     return candidatePrefix;
   258             }
   259         }
   261         // Find if any of the ancestors' name has this uri
   262         org.w3c.dom.Node currentAncestor = this;
   263         while (currentAncestor != null &&
   264                !(currentAncestor instanceof Document)) {
   266             if (uri.equals(currentAncestor.getNamespaceURI()))
   267                 return currentAncestor.getPrefix();
   268             currentAncestor = currentAncestor.getParentNode();
   269         }
   271         return null;
   272     }
   274     protected org.w3c.dom.Attr getNamespaceAttr(String prefix) {
   275         NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
   276         if (!"".equals(prefix))
   277             prefix = ":"+prefix;
   278         while (eachNamespace.hasNext()) {
   279             org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
   280             if (!"".equals(prefix)) {
   281                 if (namespaceDecl.getNodeName().endsWith(prefix))
   282                     return namespaceDecl;
   283             } else {
   284                 if (namespaceDecl.getNodeName().equals("xmlns"))
   285                     return namespaceDecl;
   286             }
   287         }
   288         return null;
   289     }
   291     public NamespaceContextIterator getNamespaceContextNodes() {
   292         return getNamespaceContextNodes(true);
   293     }
   295     public NamespaceContextIterator getNamespaceContextNodes(boolean traverseStack) {
   296         return new NamespaceContextIterator(this, traverseStack);
   297     }
   299     public SOAPElement addChildElement(
   300         String localName,
   301         String prefix,
   302         String uri)
   303         throws SOAPException {
   305         SOAPElement newElement = createElement(NameImpl.create(localName, prefix, uri));
   306         addNode(newElement);
   307         return convertToSoapElement(newElement);
   308     }
   310     public SOAPElement addChildElement(SOAPElement element)
   311         throws SOAPException {
   313         // check if Element falls in SOAP 1.1 or 1.2 namespace.
   314         String elementURI = element.getElementName().getURI();
   315         String localName = element.getLocalName();
   317         if ((SOAPConstants.URI_NS_SOAP_ENVELOPE).equals(elementURI)
   318             || (SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE).equals(elementURI)) {
   321             if ("Envelope".equalsIgnoreCase(localName) ||
   322                 "Header".equalsIgnoreCase(localName) || "Body".equalsIgnoreCase(localName)) {
   323                 log.severe("SAAJ0103.impl.cannot.add.fragements");
   324                 throw new SOAPExceptionImpl(
   325                     "Cannot add fragments which contain elements "
   326                         + "which are in the SOAP namespace");
   327             }
   329             if ("Fault".equalsIgnoreCase(localName) && !"Body".equalsIgnoreCase(this.getLocalName())) {
   330                 log.severe("SAAJ0154.impl.adding.fault.to.nonbody");
   331                 throw new SOAPExceptionImpl("Cannot add a SOAPFault as a child of " + this.getLocalName());
   332             }
   334             if ("Detail".equalsIgnoreCase(localName) && !"Fault".equalsIgnoreCase(this.getLocalName())) {
   335                 log.severe("SAAJ0155.impl.adding.detail.nonfault");
   336                 throw new SOAPExceptionImpl("Cannot add a Detail as a child of " + this.getLocalName());
   337             }
   339             if ("Fault".equalsIgnoreCase(localName)) {
   340                // if body is not empty throw an exception
   341                if (!elementURI.equals(this.getElementName().getURI())) {
   342                    log.severe("SAAJ0158.impl.version.mismatch.fault");
   343                    throw new SOAPExceptionImpl("SOAP Version mismatch encountered when trying to add SOAPFault to SOAPBody");
   344                }
   345                Iterator it = this.getChildElements();
   346                if (it.hasNext()) {
   347                    log.severe("SAAJ0156.impl.adding.fault.error");
   348                    throw new SOAPExceptionImpl("Cannot add SOAPFault as a child of a non-Empty SOAPBody");
   349                }
   350             }
   351         }
   353         // preserve the encodingStyle attr as it may get lost in the import
   354         String encodingStyle = element.getEncodingStyle();
   356         ElementImpl importedElement = (ElementImpl) importElement(element);
   357         addNode(importedElement);
   359         if (encodingStyle != null)
   360             importedElement.setEncodingStyle(encodingStyle);
   362         return convertToSoapElement(importedElement);
   363     }
   365     protected Element importElement(Element element) {
   366         Document document = getOwnerDocument();
   367         Document oldDocument = element.getOwnerDocument();
   368         if (!oldDocument.equals(document)) {
   369             return (Element) document.importNode(element, true);
   370         } else {
   371             return element;
   372         }
   373     }
   375     protected SOAPElement addElement(Name name) throws SOAPException {
   376         SOAPElement newElement = createElement(name);
   377         addNode(newElement);
   378         return newElement;
   379     }
   381     protected SOAPElement addElement(QName name) throws SOAPException {
   382         SOAPElement newElement = createElement(name);
   383         addNode(newElement);
   384         return newElement;
   385     }
   387     protected SOAPElement createElement(Name name) {
   389         if (isNamespaceQualified(name)) {
   390             return (SOAPElement)
   391                 getOwnerDocument().createElementNS(
   392                                        name.getURI(),
   393                                        name.getQualifiedName());
   394         } else {
   395             return (SOAPElement)
   396                 getOwnerDocument().createElement(name.getQualifiedName());
   397         }
   398     }
   400     protected SOAPElement createElement(QName name) {
   402         if (isNamespaceQualified(name)) {
   403             return (SOAPElement)
   404                 getOwnerDocument().createElementNS(
   405                                        name.getNamespaceURI(),
   406                                        getQualifiedName(name));
   407         } else {
   408             return (SOAPElement)
   409                 getOwnerDocument().createElement(getQualifiedName(name));
   410         }
   411     }
   413     protected void addNode(org.w3c.dom.Node newElement) throws SOAPException {
   414         insertBefore(newElement, null);
   416         if (getOwnerDocument() instanceof DocumentFragment)
   417             return;
   419         if (newElement instanceof ElementImpl) {
   420             ElementImpl element = (ElementImpl) newElement;
   421             QName elementName = element.getElementQName();
   422             if (!"".equals(elementName.getNamespaceURI())) {
   423                 element.ensureNamespaceIsDeclared(
   424                     elementName.getPrefix(), elementName.getNamespaceURI());
   425             }
   426         }
   428     }
   430     protected SOAPElement findChild(NameImpl name) {
   431         Iterator eachChild = getChildElementNodes();
   432         while (eachChild.hasNext()) {
   433             SOAPElement child = (SOAPElement) eachChild.next();
   434             if (child.getElementName().equals(name)) {
   435                 return child;
   436             }
   437         }
   439         return null;
   440     }
   442     public SOAPElement addTextNode(String text) throws SOAPException {
   443         if (text.startsWith(CDATAImpl.cdataUC)
   444             || text.startsWith(CDATAImpl.cdataLC))
   445             return addCDATA(
   446                 text.substring(CDATAImpl.cdataUC.length(), text.length() - 3));
   447         return addText(text);
   448     }
   450     protected SOAPElement addCDATA(String text) throws SOAPException {
   451         org.w3c.dom.Text cdata =
   452             (org.w3c.dom.Text) getOwnerDocument().createCDATASection(text);
   453         addNode(cdata);
   454         return this;
   455     }
   457     protected SOAPElement addText(String text) throws SOAPException {
   458         org.w3c.dom.Text textNode =
   459             (org.w3c.dom.Text) getOwnerDocument().createTextNode(text);
   460         addNode(textNode);
   461         return this;
   462     }
   464     public SOAPElement addAttribute(Name name, String value)
   465         throws SOAPException {
   466         addAttributeBare(name, value);
   467         if (!"".equals(name.getURI())) {
   468             ensureNamespaceIsDeclared(name.getPrefix(), name.getURI());
   469         }
   470         return this;
   471     }
   473     public SOAPElement addAttribute(QName qname, String value)
   474         throws SOAPException {
   475         addAttributeBare(qname, value);
   476         if (!"".equals(qname.getNamespaceURI())) {
   477             ensureNamespaceIsDeclared(qname.getPrefix(), qname.getNamespaceURI());
   478         }
   479         return this;
   480     }
   482     private void addAttributeBare(Name name, String value) {
   483         addAttributeBare(
   484             name.getURI(),
   485             name.getPrefix(),
   486             name.getQualifiedName(),
   487             value);
   488     }
   489     private void addAttributeBare(QName name, String value) {
   490         addAttributeBare(
   491             name.getNamespaceURI(),
   492             name.getPrefix(),
   493             getQualifiedName(name),
   494             value);
   495     }
   497     private void addAttributeBare(
   498         String uri,
   499         String prefix,
   500         String qualifiedName,
   501         String value) {
   503         uri = uri.length() == 0 ? null : uri;
   504         if (qualifiedName.equals("xmlns")) {
   505             uri = XMLNS_URI;
   506         }
   508         if (uri == null) {
   509             setAttribute(qualifiedName, value);
   510         } else {
   511             setAttributeNS(uri, qualifiedName, value);
   512         }
   513     }
   515     public SOAPElement addNamespaceDeclaration(String prefix, String uri)
   516         throws SOAPException {
   517         if (prefix.length() > 0) {
   518             setAttributeNS(XMLNS_URI, "xmlns:" + prefix, uri);
   519         } else {
   520             setAttributeNS(XMLNS_URI, "xmlns", uri);
   521         }
   522         //Fix for CR:6474641
   523         //tryToFindEncodingStyleAttributeName();
   524         return this;
   525     }
   527     public String getAttributeValue(Name name) {
   528         return getAttributeValueFrom(this, name);
   529     }
   531     public String getAttributeValue(QName qname) {
   532         return getAttributeValueFrom(
   533                    this,
   534                    qname.getNamespaceURI(),
   535                    qname.getLocalPart(),
   536                    qname.getPrefix(),
   537                    getQualifiedName(qname));
   538     }
   540     public Iterator getAllAttributes() {
   541         Iterator i = getAllAttributesFrom(this);
   542         ArrayList list = new ArrayList();
   543         while (i.hasNext()) {
   544             Name name = (Name) i.next();
   545             if (!"xmlns".equalsIgnoreCase(name.getPrefix()))
   546                 list.add(name);
   547         }
   548         return list.iterator();
   549     }
   551     public Iterator getAllAttributesAsQNames() {
   552         Iterator i = getAllAttributesFrom(this);
   553         ArrayList list = new ArrayList();
   554         while (i.hasNext()) {
   555             Name name = (Name) i.next();
   556             if (!"xmlns".equalsIgnoreCase(name.getPrefix())) {
   557                 list.add(NameImpl.convertToQName(name));
   558             }
   559         }
   560         return list.iterator();
   561     }
   564     public Iterator getNamespacePrefixes() {
   565         return doGetNamespacePrefixes(false);
   566     }
   568     public Iterator getVisibleNamespacePrefixes() {
   569         return doGetNamespacePrefixes(true);
   570     }
   572     protected Iterator doGetNamespacePrefixes(final boolean deep) {
   573         return new Iterator() {
   574             String next = null;
   575             String last = null;
   576             NamespaceContextIterator eachNamespace =
   577                 getNamespaceContextNodes(deep);
   579             void findNext() {
   580                 while (next == null && eachNamespace.hasNext()) {
   581                     String attributeKey =
   582                         eachNamespace.nextNamespaceAttr().getNodeName();
   583                     if (attributeKey.startsWith("xmlns:")) {
   584                         next = attributeKey.substring("xmlns:".length());
   585                     }
   586                 }
   587             }
   589             public boolean hasNext() {
   590                 findNext();
   591                 return next != null;
   592             }
   594             public Object next() {
   595                 findNext();
   596                 if (next == null) {
   597                     throw new NoSuchElementException();
   598                 }
   600                 last = next;
   601                 next = null;
   602                 return last;
   603             }
   605             public void remove() {
   606                 if (last == null) {
   607                     throw new IllegalStateException();
   608                 }
   609                 eachNamespace.remove();
   610                 next = null;
   611                 last = null;
   612             }
   613         };
   614     }
   616     public Name getElementName() {
   617         return NameImpl.convertToName(elementQName);
   618     }
   620     public QName getElementQName() {
   621         return elementQName;
   622     }
   624     public boolean removeAttribute(Name name) {
   625         return removeAttribute(name.getURI(), name.getLocalName());
   626     }
   628     public boolean removeAttribute(QName name) {
   629         return removeAttribute(name.getNamespaceURI(), name.getLocalPart());
   630     }
   632     private boolean removeAttribute(String uri, String localName) {
   633         String nonzeroLengthUri =
   634             (uri == null || uri.length() == 0) ? null : uri;
   635         org.w3c.dom.Attr attribute =
   636             getAttributeNodeNS(nonzeroLengthUri, localName);
   637         if (attribute == null) {
   638             return false;
   639         }
   640         removeAttributeNode(attribute);
   641         return true;
   642     }
   644     public boolean removeNamespaceDeclaration(String prefix) {
   645         org.w3c.dom.Attr declaration = getNamespaceAttr(prefix);
   646         if (declaration == null) {
   647             return false;
   648         }
   649         try {
   650             removeAttributeNode(declaration);
   651         } catch (DOMException de) {
   652             // ignore
   653         }
   654         return true;
   655     }
   657     public Iterator getChildElements() {
   658         return getChildElementsFrom(this);
   659     }
   661     protected SOAPElement convertToSoapElement(Element element) {
   662         if (element instanceof SOAPElement) {
   663             return (SOAPElement) element;
   664         } else {
   665             return replaceElementWithSOAPElement(
   666                 element,
   667                 (ElementImpl) createElement(NameImpl.copyElementName(element)));
   668         }
   669     }
   671     protected static SOAPElement replaceElementWithSOAPElement(
   672         Element element,
   673         ElementImpl copy) {
   675         Iterator eachAttribute = getAllAttributesFrom(element);
   676         while (eachAttribute.hasNext()) {
   677             Name name = (Name) eachAttribute.next();
   678             copy.addAttributeBare(name, getAttributeValueFrom(element, name));
   679         }
   681         Iterator eachChild = getChildElementsFrom(element);
   682         while (eachChild.hasNext()) {
   683             Node nextChild = (Node) eachChild.next();
   684             copy.insertBefore(nextChild, null);
   685         }
   687         Node parent = element.getParentNode();
   688         if (parent != null) {
   689             parent.replaceChild(copy, element);
   690         } // XXX else throw an exception?
   692         return copy;
   693     }
   695     protected Iterator getChildElementNodes() {
   696         return new Iterator() {
   697             Iterator eachNode = getChildElements();
   698             Node next = null;
   699             Node last = null;
   701             public boolean hasNext() {
   702                 if (next == null) {
   703                     while (eachNode.hasNext()) {
   704                         Node node = (Node) eachNode.next();
   705                         if (node instanceof SOAPElement) {
   706                             next = node;
   707                             break;
   708                         }
   709                     }
   710                 }
   711                 return next != null;
   712             }
   714             public Object next() {
   715                 if (hasNext()) {
   716                     last = next;
   717                     next = null;
   718                     return last;
   719                 }
   720                 throw new NoSuchElementException();
   721             }
   723             public void remove() {
   724                 if (last == null) {
   725                     throw new IllegalStateException();
   726                 }
   727                 Node target = last;
   728                 last = null;
   729                 removeChild(target);
   730             }
   731         };
   732     }
   734     public Iterator getChildElements(final Name name) {
   735        return getChildElements(name.getURI(), name.getLocalName());
   736     }
   738     public Iterator getChildElements(final QName qname) {
   739         return getChildElements(qname.getNamespaceURI(), qname.getLocalPart());
   740     }
   742     private Iterator getChildElements(final String nameUri, final String nameLocal) {
   743         return new Iterator() {
   744             Iterator eachElement = getChildElementNodes();
   745             Node next = null;
   746             Node last = null;
   748             public boolean hasNext() {
   749                 if (next == null) {
   750                     while (eachElement.hasNext()) {
   751                         Node element = (Node) eachElement.next();
   752                         String elementUri = element.getNamespaceURI();
   753                         elementUri = elementUri == null ? "" : elementUri;
   754                         String elementName = element.getLocalName();
   755                         if (elementUri.equals(nameUri)
   756                             && elementName.equals(nameLocal)) {
   757                             next = element;
   758                             break;
   759                         }
   760                     }
   761                 }
   762                 return next != null;
   763             }
   765             public Object next() {
   766                 if (!hasNext()) {
   767                     throw new NoSuchElementException();
   768                 }
   769                 last = next;
   770                 next = null;
   771                 return last;
   772             }
   774             public void remove() {
   775                 if (last == null) {
   776                     throw new IllegalStateException();
   777                 }
   778                 Node target = last;
   779                 last = null;
   780                 removeChild(target);
   781             }
   782         };
   783     }
   785     public void removeContents() {
   786         Node currentChild = getFirstChild();
   788         while (currentChild != null) {
   789             Node temp = currentChild.getNextSibling();
   790             if (currentChild instanceof javax.xml.soap.Node) {
   791                 ((javax.xml.soap.Node) currentChild).detachNode();
   792             } else {
   793                 Node parent = currentChild.getParentNode();
   794                 if (parent != null) {
   795                     parent.removeChild(currentChild);
   796                 }
   798             }
   799             currentChild = temp;
   800         }
   801     }
   803     public void setEncodingStyle(String encodingStyle) throws SOAPException {
   804         if (!"".equals(encodingStyle)) {
   805             try {
   806                 new URI(encodingStyle);
   807             } catch (URISyntaxException m) {
   808                 log.log(
   809                     Level.SEVERE,
   810                     "SAAJ0105.impl.encoding.style.mustbe.valid.URI",
   811                     new String[] { encodingStyle });
   812                 throw new IllegalArgumentException(
   813                     "Encoding style (" + encodingStyle + ") should be a valid URI");
   814             }
   815         }
   816         encodingStyleAttribute.setValue(encodingStyle);
   817         tryToFindEncodingStyleAttributeName();
   818     }
   820     public String getEncodingStyle() {
   821         String encodingStyle = encodingStyleAttribute.getValue();
   822         if (encodingStyle != null)
   823             return encodingStyle;
   824         String soapNamespace = getSOAPNamespace();
   825         if (soapNamespace != null) {
   826             Attr attr = getAttributeNodeNS(soapNamespace, "encodingStyle");
   827             if (attr != null) {
   828                 encodingStyle = attr.getValue();
   829                 try {
   830                     setEncodingStyle(encodingStyle);
   831                 } catch (SOAPException se) {
   832                     // has to be ignored
   833                 }
   834                 return encodingStyle;
   835             }
   836         }
   837         return null;
   838     }
   840     // Node methods
   841     public String getValue() {
   842         javax.xml.soap.Node valueNode = getValueNode();
   843         return valueNode == null ? null : valueNode.getValue();
   844     }
   846     public void setValue(String value) {
   847         Node valueNode = getValueNodeStrict();
   848         if (valueNode != null) {
   849             valueNode.setNodeValue(value);
   850         } else {
   851             try {
   852                 addTextNode(value);
   853             } catch (SOAPException e) {
   854                 throw new RuntimeException(e.getMessage());
   855             }
   856         }
   857     }
   859     protected Node getValueNodeStrict() {
   860         Node node = getFirstChild();
   861         if (node != null) {
   862             if (node.getNextSibling() == null
   863                 && node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
   864                 return node;
   865             } else {
   866                 log.severe("SAAJ0107.impl.elem.child.not.single.text");
   867                 throw new IllegalStateException();
   868             }
   869         }
   871         return null;
   872     }
   874     protected javax.xml.soap.Node getValueNode() {
   875         Iterator i = getChildElements();
   876         while (i.hasNext()) {
   877             javax.xml.soap.Node n = (javax.xml.soap.Node) i.next();
   878             if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE ||
   879                 n.getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) {
   880                 // TODO: Hack to fix text node split into multiple lines.
   881                 normalize();
   882                 // Should remove the normalization step when this gets fixed in
   883                 // DOM/Xerces.
   884                 return (javax.xml.soap.Node) n;
   885             }
   886         }
   887         return null;
   888     }
   890     public void setParentElement(SOAPElement element) throws SOAPException {
   891         if (element == null) {
   892             log.severe("SAAJ0106.impl.no.null.to.parent.elem");
   893             throw new SOAPException("Cannot pass NULL to setParentElement");
   894         }
   895         element.addChildElement(this);
   896         findEncodingStyleAttributeName();
   897     }
   899     protected void findEncodingStyleAttributeName() throws SOAPException {
   900         String soapNamespace = getSOAPNamespace();
   901         if (soapNamespace != null) {
   902             String soapNamespacePrefix = getNamespacePrefix(soapNamespace);
   903             if (soapNamespacePrefix != null) {
   904                 setEncodingStyleNamespace(soapNamespace, soapNamespacePrefix);
   905             }
   906         }
   907     }
   909     protected void setEncodingStyleNamespace(
   910         String soapNamespace,
   911         String soapNamespacePrefix)
   912         throws SOAPException {
   913         Name encodingStyleAttributeName =
   914             NameImpl.create(
   915                 "encodingStyle",
   916                 soapNamespacePrefix,
   917                 soapNamespace);
   918         encodingStyleAttribute.setName(encodingStyleAttributeName);
   919     }
   921     public SOAPElement getParentElement() {
   922         Node parentNode = getParentNode();
   923         if (parentNode instanceof SOAPDocument) {
   924             return null;
   925         }
   926         return (SOAPElement) parentNode;
   927     }
   929     protected String getSOAPNamespace() {
   930         String soapNamespace = null;
   932         SOAPElement antecedent = this;
   933         while (antecedent != null) {
   934             Name antecedentName = antecedent.getElementName();
   935             String antecedentNamespace = antecedentName.getURI();
   937             if (NameImpl.SOAP11_NAMESPACE.equals(antecedentNamespace)
   938                 || NameImpl.SOAP12_NAMESPACE.equals(antecedentNamespace)) {
   940                 soapNamespace = antecedentNamespace;
   941                 break;
   942             }
   944             antecedent = antecedent.getParentElement();
   945         }
   947         return soapNamespace;
   948     }
   950     public void detachNode() {
   951         Node parent = getParentNode();
   952         if (parent != null) {
   953             parent.removeChild(this);
   954         }
   955         encodingStyleAttribute.clearNameAndValue();
   956         // Fix for CR: 6474641
   957         //tryToFindEncodingStyleAttributeName();
   958     }
   960     public void tryToFindEncodingStyleAttributeName() {
   961         try {
   962             findEncodingStyleAttributeName();
   963         } catch (SOAPException e) { /*okay to fail*/
   964         }
   965     }
   967     public void recycleNode() {
   968         detachNode();
   969         // TBD
   970         //  - add this to the factory so subsequent
   971         //    creations can reuse this object.
   972     }
   974     class AttributeManager {
   975         Name attributeName = null;
   976         String attributeValue = null;
   978         public void setName(Name newName) throws SOAPException {
   979             clearAttribute();
   980             attributeName = newName;
   981             reconcileAttribute();
   982         }
   983         public void clearName() {
   984             clearAttribute();
   985             attributeName = null;
   986         }
   987         public void setValue(String value) throws SOAPException {
   988             attributeValue = value;
   989             reconcileAttribute();
   990         }
   991         public Name getName() {
   992             return attributeName;
   993         }
   994         public String getValue() {
   995             return attributeValue;
   996         }
   998         /** Note: to be used only in detachNode method */
   999         public void clearNameAndValue() {
  1000             attributeName = null;
  1001             attributeValue = null;
  1004         private void reconcileAttribute() throws SOAPException {
  1005             if (attributeName != null) {
  1006                 removeAttribute(attributeName);
  1007                 if (attributeValue != null) {
  1008                     addAttribute(attributeName, attributeValue);
  1012         private void clearAttribute() {
  1013             if (attributeName != null) {
  1014                 removeAttribute(attributeName);
  1019     protected static org.w3c.dom.Attr getNamespaceAttrFrom(
  1020         Element element,
  1021         String prefix) {
  1022         NamespaceContextIterator eachNamespace =
  1023             new NamespaceContextIterator(element);
  1024         while (eachNamespace.hasNext()) {
  1025             org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
  1026             String declaredPrefix =
  1027                 NameImpl.getLocalNameFromTagName(namespaceDecl.getNodeName());
  1028             if (declaredPrefix.equals(prefix)) {
  1029                 return namespaceDecl;
  1032         return null;
  1035     protected static Iterator getAllAttributesFrom(final Element element) {
  1036         final NamedNodeMap attributes = element.getAttributes();
  1038         return new Iterator() {
  1039             int attributesLength = attributes.getLength();
  1040             int attributeIndex = 0;
  1041             String currentName;
  1043             public boolean hasNext() {
  1044                 return attributeIndex < attributesLength;
  1047             public Object next() {
  1048                 if (!hasNext()) {
  1049                     throw new NoSuchElementException();
  1051                 Node current = attributes.item(attributeIndex++);
  1052                 currentName = current.getNodeName();
  1054                 String prefix = NameImpl.getPrefixFromTagName(currentName);
  1055                 if (prefix.length() == 0) {
  1056                     return NameImpl.createFromUnqualifiedName(currentName);
  1057                 } else {
  1058                     Name attributeName =
  1059                         NameImpl.createFromQualifiedName(
  1060                             currentName,
  1061                             current.getNamespaceURI());
  1062                     return attributeName;
  1066             public void remove() {
  1067                 if (currentName == null) {
  1068                     throw new IllegalStateException();
  1070                 attributes.removeNamedItem(currentName);
  1072         };
  1075     protected static String getAttributeValueFrom(Element element, Name name) {
  1076       return getAttributeValueFrom(
  1077           element,
  1078           name.getURI(),
  1079           name.getLocalName(),
  1080           name.getPrefix(),
  1081           name.getQualifiedName());
  1084     private static String getAttributeValueFrom(
  1085         Element element,
  1086         String uri,
  1087         String localName,
  1088         String prefix,
  1089         String qualifiedName) {
  1091         String nonzeroLengthUri =
  1092             (uri == null || uri.length() == 0) ? null : uri;
  1094         boolean mustUseGetAttributeNodeNS =  (nonzeroLengthUri != null);
  1096         if (mustUseGetAttributeNodeNS) {
  1098             if (!element.hasAttributeNS(uri, localName)) {
  1099                 return null;
  1102             String attrValue =
  1103                 element.getAttributeNS(nonzeroLengthUri, localName);
  1105             return attrValue;
  1108         Attr attribute = null;
  1109         attribute = element.getAttributeNode(qualifiedName);
  1111         return attribute == null ? null : attribute.getValue();
  1114     protected static Iterator getChildElementsFrom(final Element element) {
  1115         return new Iterator() {
  1116             Node next = element.getFirstChild();
  1117             Node nextNext = null;
  1118             Node last = null;
  1120             public boolean hasNext() {
  1121                 if (next != null) {
  1122                     return true;
  1124                 if (next == null && nextNext != null) {
  1125                     next = nextNext;
  1128                 return next != null;
  1131             public Object next() {
  1132                 if (hasNext()) {
  1133                     last = next;
  1134                     next = null;
  1136                     if ((element instanceof ElementImpl)
  1137                         && (last instanceof Element)) {
  1138                         last =
  1139                             ((ElementImpl) element).convertToSoapElement(
  1140                                 (Element) last);
  1143                     nextNext = last.getNextSibling();
  1144                     return last;
  1146                 throw new NoSuchElementException();
  1149             public void remove() {
  1150                 if (last == null) {
  1151                     throw new IllegalStateException();
  1153                 Node target = last;
  1154                 last = null;
  1155                 element.removeChild(target);
  1157         };
  1160     public static String getQualifiedName(QName name) {
  1161         String prefix = name.getPrefix();
  1162         String localName = name.getLocalPart();
  1163         String qualifiedName = null;
  1165             if (prefix != null && prefix.length() > 0) {
  1166                 qualifiedName = prefix + ":" + localName;
  1167             } else {
  1168                 qualifiedName = localName;
  1170          return qualifiedName;
  1173     public static String getLocalPart(String qualifiedName) {
  1174         if (qualifiedName == null) {
  1175             // Log
  1176             throw new IllegalArgumentException("Cannot get local name for a \"null\" qualified name");
  1179         int index = qualifiedName.indexOf(':');
  1180         if (index < 0)
  1181             return qualifiedName;
  1182         else
  1183             return qualifiedName.substring(index + 1);
  1186     public static String getPrefix(String qualifiedName) {
  1187         if (qualifiedName == null) {
  1188             // Log
  1189             throw new IllegalArgumentException("Cannot get prefix for a  \"null\" qualified name");
  1192         int index = qualifiedName.indexOf(':');
  1193         if (index < 0)
  1194             return "";
  1195         else
  1196             return qualifiedName.substring(0, index);
  1199     protected boolean isNamespaceQualified(Name name) {
  1200         return !"".equals(name.getURI());
  1203     protected boolean isNamespaceQualified(QName name) {
  1204         return !"".equals(name.getNamespaceURI());
  1207     //TODO: This is a temporary SAAJ workaround for optimizing XWS
  1208     // should be removed once the corresponding JAXP bug is fixed
  1209     // It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe)
  1210     public void setAttributeNS(
  1211         String namespaceURI,String qualifiedName, String value) {
  1212         int index = qualifiedName.indexOf(':');
  1213         String localName;
  1214         if (index < 0)
  1215             localName = qualifiedName;
  1216         else
  1217             localName = qualifiedName.substring(index + 1);
  1219         // Workaround for bug 6467808 - This needs to be fixed in JAXP
  1221         // Rolling back this fix, this is a wrong fix, infact its causing other regressions in JAXWS tck and
  1222         // other tests, because of this change the namespace declarations on soapenv:Fault element are never
  1223         // picked up. The fix for bug 6467808 should be in JAXP.
  1224 //        if(elementQName.getLocalPart().equals("Fault") &&
  1225 //                (SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE.equals(value) ||
  1226 //                SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE.equals(value)))
  1227 //            return;
  1229         super.setAttributeNS(namespaceURI,qualifiedName,value);
  1230         //String tmpLocalName = this.getLocalName();
  1231         String tmpURI = this.getNamespaceURI();
  1232         boolean isIDNS = false;
  1233         if( tmpURI != null && (tmpURI.equals(DSIG_NS) || tmpURI.equals(XENC_NS))){
  1234             isIDNS = true;
  1236         //No need to check for Signature/encryption element
  1237         //just check for namespace.
  1238         if(localName.equals("Id")){
  1239             if(namespaceURI == null || namespaceURI.equals("")){
  1240                 setIdAttribute(localName,true);
  1241             }else if(isIDNS || WSU_NS.equals(namespaceURI)){
  1242                 setIdAttributeNS(namespaceURI,localName,true);

mercurial