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

Mon, 04 May 2009 21:10:41 -0700

author
tbell
date
Mon, 04 May 2009 21:10:41 -0700
changeset 50
42dfec6871f6
parent 45
31822b475baa
child 78
860b95cc8d1d
permissions
-rw-r--r--

6658158: Mutable statics in SAAJ (findbugs)
6658163: txw2.DatatypeWriter.BUILDIN is a mutable static (findbugs)
Reviewed-by: darcy

     1 /*
     2  * Copyright 2005-2006 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    25 /*
    26  *
    27  *
    28  *
    29  */
    32 package com.sun.xml.internal.messaging.saaj.soap.impl;
    34 import java.util.*;
    35 import java.util.logging.Level;
    36 import java.util.logging.Logger;
    38 import javax.xml.namespace.QName;
    39 import javax.xml.soap.*;
    41 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
    42 import org.w3c.dom.*;
    43 import org.w3c.dom.Node;
    45 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
    46 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument;
    47 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl;
    48 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
    49 import com.sun.xml.internal.messaging.saaj.util.*;
    51 public class ElementImpl
    52     extends com.sun.org.apache.xerces.internal.dom.ElementNSImpl
    53     implements SOAPElement, SOAPBodyElement {
    55     public static final String DSIG_NS = "http://www.w3.org/2000/09/xmldsig#".intern();
    56     public static final String XENC_NS = "http://www.w3.org/2001/04/xmlenc#".intern();
    57     public static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd".intern();
    59     private AttributeManager encodingStyleAttribute = new AttributeManager();
    61     protected QName elementQName;
    63     protected static final Logger log =
    64         Logger.getLogger(LogDomainConstants.SOAP_IMPL_DOMAIN,
    65                          "com.sun.xml.internal.messaging.saaj.soap.impl.LocalStrings");
    67     public ElementImpl(SOAPDocumentImpl ownerDoc, Name name) {
    68         super(
    69             ownerDoc,
    70             name.getURI(),
    71             name.getQualifiedName(),
    72             name.getLocalName());
    73         elementQName = NameImpl.convertToQName(name);
    74     }
    76     public ElementImpl(SOAPDocumentImpl ownerDoc, QName name) {
    77         super(
    78             ownerDoc,
    79             name.getNamespaceURI(),
    80             getQualifiedName(name),
    81             name.getLocalPart());
    82         elementQName = name;
    83     }
    85     public ElementImpl(
    86         SOAPDocumentImpl ownerDoc,
    87         String uri,
    88         String qualifiedName) {
    90         super(ownerDoc, uri, qualifiedName);
    91         elementQName =
    92             new QName(uri, getLocalPart(qualifiedName), getPrefix(qualifiedName));
    93     }
    95     public void ensureNamespaceIsDeclared(String prefix, String uri) {
    96         String alreadyDeclaredUri = getNamespaceURI(prefix);
    97         if (alreadyDeclaredUri == null || !alreadyDeclaredUri.equals(uri)) {
    98             try {
    99                 addNamespaceDeclaration(prefix, uri);
   100             } catch (SOAPException e) { /*ignore*/
   101             }
   102         }
   103     }
   105     public Document getOwnerDocument() {
   106         SOAPDocument ownerSOAPDocument =
   107             ((SOAPDocument) super.getOwnerDocument());
   108         if (ownerSOAPDocument == null) {
   109             return null;
   110         }
   111         return ownerSOAPDocument.getDocument();
   112     }
   114     public SOAPElement addChildElement(Name name) throws SOAPException {
   115         return  addElement(name);
   116     }
   118     public SOAPElement addChildElement(QName qname) throws SOAPException {
   119         return  addElement(qname);
   120     }
   122     public SOAPElement addChildElement(String localName) throws SOAPException {
   123         return (SOAPElement) addChildElement(
   124             NameImpl.createFromUnqualifiedName(localName));
   125     }
   127     public SOAPElement addChildElement(String localName, String prefix)
   128         throws SOAPException {
   129         String uri = getNamespaceURI(prefix);
   130         if (uri == null) {
   131             log.log(
   132                 Level.SEVERE,
   133                 "SAAJ0101.impl.parent.of.body.elem.mustbe.body",
   134                 new String[] { prefix });
   135             throw new SOAPExceptionImpl(
   136                 "Unable to locate namespace for prefix " + prefix);
   137         }
   138         return addChildElement(localName, prefix, uri);
   139     }
   141     public String getNamespaceURI(String prefix) {
   143         if ("xmlns".equals(prefix)) {
   144             return NamespaceContext.XMLNS_URI;
   145         }
   147         if("xml".equals(prefix)) {
   148             return NamespaceContext.XML_URI;
   149         }
   151         if ("".equals(prefix)) {
   153             org.w3c.dom.Node currentAncestor = this;
   154             while (currentAncestor != null &&
   155                    !(currentAncestor instanceof Document)) {
   157                 if (currentAncestor instanceof ElementImpl) {
   158                     QName name = ((ElementImpl) currentAncestor).getElementQName();
   159                     /*
   160                     if (prefix.equals(name.getPrefix())) {
   161                         String uri = name.getNamespaceURI();
   162                         if ("".equals(uri)) {
   163                             return null;
   164                         }
   165                         else {
   166                             return uri;
   167                         }
   168                     }*/
   169                     if (((Element) currentAncestor).hasAttributeNS(
   170                             NamespaceContext.XMLNS_URI, "xmlns")) {
   172                         String uri =
   173                             ((Element) currentAncestor).getAttributeNS(
   174                                 NamespaceContext.XMLNS_URI, "xmlns");
   175                         if ("".equals(uri))
   176                             return null;
   177                         else {
   178                             return uri;
   179                         }
   180                     }
   181                 }
   182                 currentAncestor = currentAncestor.getParentNode();
   183             }
   185         } else if (prefix != null) {
   186             // Find if there's an ancester whose name contains this prefix
   187             org.w3c.dom.Node currentAncestor = this;
   189 //            String uri = currentAncestor.lookupNamespaceURI(prefix);
   190 //            return uri;
   191             while (currentAncestor != null &&
   192                    !(currentAncestor instanceof Document)) {
   194                /* if (prefix.equals(currentAncestor.getPrefix())) {
   195                     String uri = currentAncestor.getNamespaceURI();
   196                     // this is because the javadoc says getNamespaceURI() is not a computed value
   197                     // and URI for a non-empty prefix cannot be null
   198                     if (uri != null)
   199                         return uri;
   200                 }*/
   201                 //String uri = currentAncestor.lookupNamespaceURI(prefix);
   202                 //if (uri != null) {
   203                 //    return uri;
   204                 //}
   206                 if (((Element) currentAncestor).hasAttributeNS(
   207                         NamespaceContext.XMLNS_URI, prefix)) {
   208                     return ((Element) currentAncestor).getAttributeNS(
   209                                NamespaceContext.XMLNS_URI, prefix);
   210                 }
   212                 currentAncestor = currentAncestor.getParentNode();
   213             }
   214         }
   216         return null;
   217     }
   219     public SOAPElement setElementQName(QName newName) throws SOAPException {
   220         ElementImpl copy =
   221             new ElementImpl((SOAPDocumentImpl) getOwnerDocument(), newName);
   222         return replaceElementWithSOAPElement(this,copy);
   223     }
   225     public QName createQName(String localName, String prefix)
   226         throws SOAPException {
   227         String uri = getNamespaceURI(prefix);
   228         if (uri == null) {
   229             log.log(Level.SEVERE, "SAAJ0102.impl.cannot.locate.ns",
   230                     new Object[] {prefix});
   231             throw new SOAPException("Unable to locate namespace for prefix "
   232                                     + prefix);
   233         }
   234         return new QName(uri, localName, prefix);
   235     }
   237     public String getNamespacePrefix(String uri) {
   239         NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
   240         while (eachNamespace.hasNext()) {
   241             org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
   242             if (namespaceDecl.getNodeValue().equals(uri)) {
   243                 String candidatePrefix = namespaceDecl.getLocalName();
   244                 if ("xmlns".equals(candidatePrefix))
   245                     return "";
   246                 else
   247                     return candidatePrefix;
   248             }
   249         }
   251         // Find if any of the ancestors' name has this uri
   252         org.w3c.dom.Node currentAncestor = this;
   253         while (currentAncestor != null &&
   254                !(currentAncestor instanceof Document)) {
   256             if (uri.equals(currentAncestor.getNamespaceURI()))
   257                 return currentAncestor.getPrefix();
   258             currentAncestor = currentAncestor.getParentNode();
   259         }
   261         return null;
   262     }
   264     protected org.w3c.dom.Attr getNamespaceAttr(String prefix) {
   265         NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
   266         if (!"".equals(prefix))
   267             prefix = ":"+prefix;
   268         while (eachNamespace.hasNext()) {
   269             org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
   270             if (!"".equals(prefix)) {
   271                 if (namespaceDecl.getNodeName().endsWith(prefix))
   272                     return namespaceDecl;
   273             } else {
   274                 if (namespaceDecl.getNodeName().equals("xmlns"))
   275                     return namespaceDecl;
   276             }
   277         }
   278         return null;
   279     }
   281     public NamespaceContextIterator getNamespaceContextNodes() {
   282         return getNamespaceContextNodes(true);
   283     }
   285     public NamespaceContextIterator getNamespaceContextNodes(boolean traverseStack) {
   286         return new NamespaceContextIterator(this, traverseStack);
   287     }
   289     public SOAPElement addChildElement(
   290         String localName,
   291         String prefix,
   292         String uri)
   293         throws SOAPException {
   295         SOAPElement newElement = createElement(NameImpl.create(localName, prefix, uri));
   296         addNode(newElement);
   297         return convertToSoapElement(newElement);
   298     }
   300     public SOAPElement addChildElement(SOAPElement element)
   301         throws SOAPException {
   303         // check if Element falls in SOAP 1.1 or 1.2 namespace.
   304         String elementURI = element.getElementName().getURI();
   305         String localName = element.getLocalName();
   307         if ((SOAPConstants.URI_NS_SOAP_ENVELOPE).equals(elementURI)
   308             || (SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE).equals(elementURI)) {
   311             if ("Envelope".equalsIgnoreCase(localName) ||
   312                 "Header".equalsIgnoreCase(localName) || "Body".equalsIgnoreCase(localName)) {
   313                 log.severe("SAAJ0103.impl.cannot.add.fragements");
   314                 throw new SOAPExceptionImpl(
   315                     "Cannot add fragments which contain elements "
   316                         + "which are in the SOAP namespace");
   317             }
   319             if ("Fault".equalsIgnoreCase(localName) && !"Body".equalsIgnoreCase(this.getLocalName())) {
   320                 log.severe("SAAJ0154.impl.adding.fault.to.nonbody");
   321                 throw new SOAPExceptionImpl("Cannot add a SOAPFault as a child of " + this.getLocalName());
   322             }
   324             if ("Detail".equalsIgnoreCase(localName) && !"Fault".equalsIgnoreCase(this.getLocalName())) {
   325                 log.severe("SAAJ0155.impl.adding.detail.nonfault");
   326                 throw new SOAPExceptionImpl("Cannot add a Detail as a child of " + this.getLocalName());
   327             }
   329             if ("Fault".equalsIgnoreCase(localName)) {
   330                // if body is not empty throw an exception
   331                if (!elementURI.equals(this.getElementName().getURI())) {
   332                    log.severe("SAAJ0158.impl.version.mismatch.fault");
   333                    throw new SOAPExceptionImpl("SOAP Version mismatch encountered when trying to add SOAPFault to SOAPBody");
   334                }
   335                Iterator it = this.getChildElements();
   336                if (it.hasNext()) {
   337                    log.severe("SAAJ0156.impl.adding.fault.error");
   338                    throw new SOAPExceptionImpl("Cannot add SOAPFault as a child of a non-Empty SOAPBody");
   339                }
   340             }
   341         }
   343         // preserve the encodingStyle attr as it may get lost in the import
   344         String encodingStyle = element.getEncodingStyle();
   346         ElementImpl importedElement = (ElementImpl) importElement(element);
   347         addNode(importedElement);
   349         if (encodingStyle != null)
   350             importedElement.setEncodingStyle(encodingStyle);
   352         return convertToSoapElement(importedElement);
   353     }
   355     protected Element importElement(Element element) {
   356         Document document = getOwnerDocument();
   357         Document oldDocument = element.getOwnerDocument();
   358         if (!oldDocument.equals(document)) {
   359             return (Element) document.importNode(element, true);
   360         } else {
   361             return element;
   362         }
   363     }
   365     protected SOAPElement addElement(Name name) throws SOAPException {
   366         SOAPElement newElement = createElement(name);
   367         addNode(newElement);
   368         return circumventBug5034339(newElement);
   369     }
   371     protected SOAPElement addElement(QName name) throws SOAPException {
   372         SOAPElement newElement = createElement(name);
   373         addNode(newElement);
   374         return circumventBug5034339(newElement);
   375     }
   377     protected SOAPElement createElement(Name name) {
   379         if (isNamespaceQualified(name)) {
   380             return (SOAPElement)
   381                 getOwnerDocument().createElementNS(
   382                                        name.getURI(),
   383                                        name.getQualifiedName());
   384         } else {
   385             return (SOAPElement)
   386                 getOwnerDocument().createElement(name.getQualifiedName());
   387         }
   388     }
   390     protected SOAPElement createElement(QName name) {
   392         if (isNamespaceQualified(name)) {
   393             return (SOAPElement)
   394                 getOwnerDocument().createElementNS(
   395                                        name.getNamespaceURI(),
   396                                        getQualifiedName(name));
   397         } else {
   398             return (SOAPElement)
   399                 getOwnerDocument().createElement(getQualifiedName(name));
   400         }
   401     }
   403     protected void addNode(org.w3c.dom.Node newElement) throws SOAPException {
   404         insertBefore(newElement, null);
   406         if (getOwnerDocument() instanceof DocumentFragment)
   407             return;
   409         if (newElement instanceof ElementImpl) {
   410             ElementImpl element = (ElementImpl) newElement;
   411             QName elementName = element.getElementQName();
   412             if (!"".equals(elementName.getNamespaceURI())) {
   413                 element.ensureNamespaceIsDeclared(
   414                     elementName.getPrefix(), elementName.getNamespaceURI());
   415             }
   416         }
   418     }
   420     protected SOAPElement findChild(NameImpl name) {
   421         Iterator eachChild = getChildElementNodes();
   422         while (eachChild.hasNext()) {
   423             SOAPElement child = (SOAPElement) eachChild.next();
   424             if (child.getElementName().equals(name)) {
   425                 return child;
   426             }
   427         }
   429         return null;
   430     }
   432     public SOAPElement addTextNode(String text) throws SOAPException {
   433         if (text.startsWith(CDATAImpl.cdataUC)
   434             || text.startsWith(CDATAImpl.cdataLC))
   435             return addCDATA(
   436                 text.substring(CDATAImpl.cdataUC.length(), text.length() - 3));
   437         return addText(text);
   438     }
   440     protected SOAPElement addCDATA(String text) throws SOAPException {
   441         org.w3c.dom.Text cdata =
   442             (org.w3c.dom.Text) getOwnerDocument().createCDATASection(text);
   443         addNode(cdata);
   444         return this;
   445     }
   447     protected SOAPElement addText(String text) throws SOAPException {
   448         org.w3c.dom.Text textNode =
   449             (org.w3c.dom.Text) getOwnerDocument().createTextNode(text);
   450         addNode(textNode);
   451         return this;
   452     }
   454     public SOAPElement addAttribute(Name name, String value)
   455         throws SOAPException {
   456         addAttributeBare(name, value);
   457         if (!"".equals(name.getURI())) {
   458             ensureNamespaceIsDeclared(name.getPrefix(), name.getURI());
   459         }
   460         return this;
   461     }
   463     public SOAPElement addAttribute(QName qname, String value)
   464         throws SOAPException {
   465         addAttributeBare(qname, value);
   466         if (!"".equals(qname.getNamespaceURI())) {
   467             ensureNamespaceIsDeclared(qname.getPrefix(), qname.getNamespaceURI());
   468         }
   469         return this;
   470     }
   472     private void addAttributeBare(Name name, String value) {
   473         addAttributeBare(
   474             name.getURI(),
   475             name.getPrefix(),
   476             name.getQualifiedName(),
   477             value);
   478     }
   479     private void addAttributeBare(QName name, String value) {
   480         addAttributeBare(
   481             name.getNamespaceURI(),
   482             name.getPrefix(),
   483             getQualifiedName(name),
   484             value);
   485     }
   487     private void addAttributeBare(
   488         String uri,
   489         String prefix,
   490         String qualifiedName,
   491         String value) {
   493         uri = uri.length() == 0 ? null : uri;
   494         if (qualifiedName.equals("xmlns")) {
   495             uri = NamespaceContext.XMLNS_URI;
   496         }
   498         if (uri == null) {
   499             setAttribute(qualifiedName, value);
   500         } else {
   501             setAttributeNS(uri, qualifiedName, value);
   502         }
   503     }
   505     public SOAPElement addNamespaceDeclaration(String prefix, String uri)
   506         throws SOAPException {
   507         if (prefix.length() > 0) {
   508             setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns:" + prefix, uri);
   509         } else {
   510             setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns", uri);
   511         }
   512         //Fix for CR:6474641
   513         //tryToFindEncodingStyleAttributeName();
   514         return this;
   515     }
   517     public String getAttributeValue(Name name) {
   518         return getAttributeValueFrom(this, name);
   519     }
   521     public String getAttributeValue(QName qname) {
   522         return getAttributeValueFrom(
   523                    this,
   524                    qname.getNamespaceURI(),
   525                    qname.getLocalPart(),
   526                    qname.getPrefix(),
   527                    getQualifiedName(qname));
   528     }
   530     public Iterator getAllAttributes() {
   531         Iterator i = getAllAttributesFrom(this);
   532         ArrayList list = new ArrayList();
   533         while (i.hasNext()) {
   534             Name name = (Name) i.next();
   535             if (!"xmlns".equalsIgnoreCase(name.getPrefix()))
   536                 list.add(name);
   537         }
   538         return list.iterator();
   539     }
   541     public Iterator getAllAttributesAsQNames() {
   542         Iterator i = getAllAttributesFrom(this);
   543         ArrayList list = new ArrayList();
   544         while (i.hasNext()) {
   545             Name name = (Name) i.next();
   546             if (!"xmlns".equalsIgnoreCase(name.getPrefix())) {
   547                 list.add(NameImpl.convertToQName(name));
   548             }
   549         }
   550         return list.iterator();
   551     }
   554     public Iterator getNamespacePrefixes() {
   555         return doGetNamespacePrefixes(false);
   556     }
   558     public Iterator getVisibleNamespacePrefixes() {
   559         return doGetNamespacePrefixes(true);
   560     }
   562     protected Iterator doGetNamespacePrefixes(final boolean deep) {
   563         return new Iterator() {
   564             String next = null;
   565             String last = null;
   566             NamespaceContextIterator eachNamespace =
   567                 getNamespaceContextNodes(deep);
   569             void findNext() {
   570                 while (next == null && eachNamespace.hasNext()) {
   571                     String attributeKey =
   572                         eachNamespace.nextNamespaceAttr().getNodeName();
   573                     if (attributeKey.startsWith("xmlns:")) {
   574                         next = attributeKey.substring("xmlns:".length());
   575                     }
   576                 }
   577             }
   579             public boolean hasNext() {
   580                 findNext();
   581                 return next != null;
   582             }
   584             public Object next() {
   585                 findNext();
   586                 if (next == null) {
   587                     throw new NoSuchElementException();
   588                 }
   590                 last = next;
   591                 next = null;
   592                 return last;
   593             }
   595             public void remove() {
   596                 if (last == null) {
   597                     throw new IllegalStateException();
   598                 }
   599                 eachNamespace.remove();
   600                 next = null;
   601                 last = null;
   602             }
   603         };
   604     }
   606     public Name getElementName() {
   607         return NameImpl.convertToName(elementQName);
   608     }
   610     public QName getElementQName() {
   611         return elementQName;
   612     }
   614     public boolean removeAttribute(Name name) {
   615         return removeAttribute(name.getURI(), name.getLocalName());
   616     }
   618     public boolean removeAttribute(QName name) {
   619         return removeAttribute(name.getNamespaceURI(), name.getLocalPart());
   620     }
   622     private boolean removeAttribute(String uri, String localName) {
   623         String nonzeroLengthUri =
   624             (uri == null || uri.length() == 0) ? null : uri;
   625         org.w3c.dom.Attr attribute =
   626             getAttributeNodeNS(nonzeroLengthUri, localName);
   627         if (attribute == null) {
   628             return false;
   629         }
   630         removeAttributeNode(attribute);
   631         return true;
   632     }
   634     public boolean removeNamespaceDeclaration(String prefix) {
   635         org.w3c.dom.Attr declaration = getNamespaceAttr(prefix);
   636         if (declaration == null) {
   637             return false;
   638         }
   639         try {
   640             removeAttributeNode(declaration);
   641         } catch (DOMException de) {
   642             // ignore
   643         }
   644         return true;
   645     }
   647     public Iterator getChildElements() {
   648         return getChildElementsFrom(this);
   649     }
   651     protected SOAPElement convertToSoapElement(Element element) {
   652         if (element instanceof SOAPElement) {
   653             return (SOAPElement) element;
   654         } else {
   655             return replaceElementWithSOAPElement(
   656                 element,
   657                 (ElementImpl) createElement(NameImpl.copyElementName(element)));
   658         }
   659     }
   661     protected static SOAPElement replaceElementWithSOAPElement(
   662         Element element,
   663         ElementImpl copy) {
   665         Iterator eachAttribute = getAllAttributesFrom(element);
   666         while (eachAttribute.hasNext()) {
   667             Name name = (Name) eachAttribute.next();
   668             copy.addAttributeBare(name, getAttributeValueFrom(element, name));
   669         }
   671         Iterator eachChild = getChildElementsFrom(element);
   672         while (eachChild.hasNext()) {
   673             Node nextChild = (Node) eachChild.next();
   674             copy.insertBefore(nextChild, null);
   675         }
   677         Node parent = element.getParentNode();
   678         if (parent != null) {
   679             parent.replaceChild(copy, element);
   680         } // XXX else throw an exception?
   682         return copy;
   683     }
   685     protected Iterator getChildElementNodes() {
   686         return new Iterator() {
   687             Iterator eachNode = getChildElements();
   688             Node next = null;
   689             Node last = null;
   691             public boolean hasNext() {
   692                 if (next == null) {
   693                     while (eachNode.hasNext()) {
   694                         Node node = (Node) eachNode.next();
   695                         if (node instanceof SOAPElement) {
   696                             next = node;
   697                             break;
   698                         }
   699                     }
   700                 }
   701                 return next != null;
   702             }
   704             public Object next() {
   705                 if (hasNext()) {
   706                     last = next;
   707                     next = null;
   708                     return last;
   709                 }
   710                 throw new NoSuchElementException();
   711             }
   713             public void remove() {
   714                 if (last == null) {
   715                     throw new IllegalStateException();
   716                 }
   717                 Node target = last;
   718                 last = null;
   719                 removeChild(target);
   720             }
   721         };
   722     }
   724     public Iterator getChildElements(final Name name) {
   725        return getChildElements(name.getURI(), name.getLocalName());
   726     }
   728     public Iterator getChildElements(final QName qname) {
   729         return getChildElements(qname.getNamespaceURI(), qname.getLocalPart());
   730     }
   732     private Iterator getChildElements(final String nameUri, final String nameLocal) {
   733         return new Iterator() {
   734             Iterator eachElement = getChildElementNodes();
   735             Node next = null;
   736             Node last = null;
   738             public boolean hasNext() {
   739                 if (next == null) {
   740                     while (eachElement.hasNext()) {
   741                         Node element = (Node) eachElement.next();
   742                         String elementUri = element.getNamespaceURI();
   743                         elementUri = elementUri == null ? "" : elementUri;
   744                         String elementName = element.getLocalName();
   745                         if (elementUri.equals(nameUri)
   746                             && elementName.equals(nameLocal)) {
   747                             next = element;
   748                             break;
   749                         }
   750                     }
   751                 }
   752                 return next != null;
   753             }
   755             public Object next() {
   756                 if (!hasNext()) {
   757                     throw new NoSuchElementException();
   758                 }
   759                 last = next;
   760                 next = null;
   761                 return last;
   762             }
   764             public void remove() {
   765                 if (last == null) {
   766                     throw new IllegalStateException();
   767                 }
   768                 Node target = last;
   769                 last = null;
   770                 removeChild(target);
   771             }
   772         };
   773     }
   775     public void removeContents() {
   776         Node currentChild = getFirstChild();
   778         while (currentChild != null) {
   779             Node temp = currentChild.getNextSibling();
   780             if (currentChild instanceof javax.xml.soap.Node) {
   781                 ((javax.xml.soap.Node) currentChild).detachNode();
   782             } else {
   783                 Node parent = currentChild.getParentNode();
   784                 if (parent != null) {
   785                     parent.removeChild(currentChild);
   786                 }
   788             }
   789             currentChild = temp;
   790         }
   791     }
   793     public void setEncodingStyle(String encodingStyle) throws SOAPException {
   794         if (!"".equals(encodingStyle)) {
   795             try {
   796                 JaxmURI uri = new JaxmURI(encodingStyle);
   797             } catch (JaxmURI.MalformedURIException m) {
   798                 log.log(
   799                     Level.SEVERE,
   800                     "SAAJ0105.impl.encoding.style.mustbe.valid.URI",
   801                     new String[] { encodingStyle });
   802                 throw new IllegalArgumentException(
   803                     "Encoding style (" + encodingStyle + ") should be a valid URI");
   804             }
   805         }
   806         encodingStyleAttribute.setValue(encodingStyle);
   807         tryToFindEncodingStyleAttributeName();
   808     }
   810     public String getEncodingStyle() {
   811         String encodingStyle = encodingStyleAttribute.getValue();
   812         if (encodingStyle != null)
   813             return encodingStyle;
   814         String soapNamespace = getSOAPNamespace();
   815         if (soapNamespace != null) {
   816             Attr attr = getAttributeNodeNS(soapNamespace, "encodingStyle");
   817             if (attr != null) {
   818                 encodingStyle = attr.getValue();
   819                 try {
   820                     setEncodingStyle(encodingStyle);
   821                 } catch (SOAPException se) {
   822                     // has to be ignored
   823                 }
   824                 return encodingStyle;
   825             }
   826         }
   827         return null;
   828     }
   830     // Node methods
   831     public String getValue() {
   832         javax.xml.soap.Node valueNode = getValueNode();
   833         return valueNode == null ? null : valueNode.getValue();
   834     }
   836     public void setValue(String value) {
   837         Node valueNode = getValueNodeStrict();
   838         if (valueNode != null) {
   839             valueNode.setNodeValue(value);
   840         } else {
   841             try {
   842                 addTextNode(value);
   843             } catch (SOAPException e) {
   844                 throw new RuntimeException(e.getMessage());
   845             }
   846         }
   847     }
   849     protected Node getValueNodeStrict() {
   850         Node node = getFirstChild();
   851         if (node != null) {
   852             if (node.getNextSibling() == null
   853                 && node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
   854                 return node;
   855             } else {
   856                 log.severe("SAAJ0107.impl.elem.child.not.single.text");
   857                 throw new IllegalStateException();
   858             }
   859         }
   861         return null;
   862     }
   864     protected javax.xml.soap.Node getValueNode() {
   865         Iterator i = getChildElements();
   866         while (i.hasNext()) {
   867             javax.xml.soap.Node n = (javax.xml.soap.Node) i.next();
   868             if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE ||
   869                 n.getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) {
   870                 // TODO: Hack to fix text node split into multiple lines.
   871                 normalize();
   872                 // Should remove the normalization step when this gets fixed in
   873                 // DOM/Xerces.
   874                 return (javax.xml.soap.Node) n;
   875             }
   876         }
   877         return null;
   878     }
   880     public void setParentElement(SOAPElement element) throws SOAPException {
   881         if (element == null) {
   882             log.severe("SAAJ0106.impl.no.null.to.parent.elem");
   883             throw new SOAPException("Cannot pass NULL to setParentElement");
   884         }
   885         element.addChildElement(this);
   886         findEncodingStyleAttributeName();
   887     }
   889     protected void findEncodingStyleAttributeName() throws SOAPException {
   890         String soapNamespace = getSOAPNamespace();
   891         if (soapNamespace != null) {
   892             String soapNamespacePrefix = getNamespacePrefix(soapNamespace);
   893             if (soapNamespacePrefix != null) {
   894                 setEncodingStyleNamespace(soapNamespace, soapNamespacePrefix);
   895             }
   896         }
   897     }
   899     protected void setEncodingStyleNamespace(
   900         String soapNamespace,
   901         String soapNamespacePrefix)
   902         throws SOAPException {
   903         Name encodingStyleAttributeName =
   904             NameImpl.create(
   905                 "encodingStyle",
   906                 soapNamespacePrefix,
   907                 soapNamespace);
   908         encodingStyleAttribute.setName(encodingStyleAttributeName);
   909     }
   911     public SOAPElement getParentElement() {
   912         Node parentNode = getParentNode();
   913         if (parentNode instanceof SOAPDocument) {
   914             return null;
   915         }
   916         return (SOAPElement) parentNode;
   917     }
   919     protected String getSOAPNamespace() {
   920         String soapNamespace = null;
   922         SOAPElement antecedent = this;
   923         while (antecedent != null) {
   924             Name antecedentName = antecedent.getElementName();
   925             String antecedentNamespace = antecedentName.getURI();
   927             if (NameImpl.SOAP11_NAMESPACE.equals(antecedentNamespace)
   928                 || NameImpl.SOAP12_NAMESPACE.equals(antecedentNamespace)) {
   930                 soapNamespace = antecedentNamespace;
   931                 break;
   932             }
   934             antecedent = antecedent.getParentElement();
   935         }
   937         return soapNamespace;
   938     }
   940     public void detachNode() {
   941         Node parent = getParentNode();
   942         if (parent != null) {
   943             parent.removeChild(this);
   944         }
   945         encodingStyleAttribute.clearNameAndValue();
   946         // Fix for CR: 6474641
   947         //tryToFindEncodingStyleAttributeName();
   948     }
   950     public void tryToFindEncodingStyleAttributeName() {
   951         try {
   952             findEncodingStyleAttributeName();
   953         } catch (SOAPException e) { /*okay to fail*/
   954         }
   955     }
   957     public void recycleNode() {
   958         detachNode();
   959         // TBD
   960         //  - add this to the factory so subsequent
   961         //    creations can reuse this object.
   962     }
   964     class AttributeManager {
   965         Name attributeName = null;
   966         String attributeValue = null;
   968         public void setName(Name newName) throws SOAPException {
   969             clearAttribute();
   970             attributeName = newName;
   971             reconcileAttribute();
   972         }
   973         public void clearName() {
   974             clearAttribute();
   975             attributeName = null;
   976         }
   977         public void setValue(String value) throws SOAPException {
   978             attributeValue = value;
   979             reconcileAttribute();
   980         }
   981         public Name getName() {
   982             return attributeName;
   983         }
   984         public String getValue() {
   985             return attributeValue;
   986         }
   988         /** Note: to be used only in detachNode method */
   989         public void clearNameAndValue() {
   990             attributeName = null;
   991             attributeValue = null;
   992         }
   994         private void reconcileAttribute() throws SOAPException {
   995             if (attributeName != null) {
   996                 removeAttribute(attributeName);
   997                 if (attributeValue != null) {
   998                     addAttribute(attributeName, attributeValue);
   999                 }
  1002         private void clearAttribute() {
  1003             if (attributeName != null) {
  1004                 removeAttribute(attributeName);
  1009     protected static org.w3c.dom.Attr getNamespaceAttrFrom(
  1010         Element element,
  1011         String prefix) {
  1012         NamespaceContextIterator eachNamespace =
  1013             new NamespaceContextIterator(element);
  1014         while (eachNamespace.hasNext()) {
  1015             org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
  1016             String declaredPrefix =
  1017                 NameImpl.getLocalNameFromTagName(namespaceDecl.getNodeName());
  1018             if (declaredPrefix.equals(prefix)) {
  1019                 return namespaceDecl;
  1022         return null;
  1025     protected static Iterator getAllAttributesFrom(final Element element) {
  1026         final NamedNodeMap attributes = element.getAttributes();
  1028         return new Iterator() {
  1029             int attributesLength = attributes.getLength();
  1030             int attributeIndex = 0;
  1031             String currentName;
  1033             public boolean hasNext() {
  1034                 return attributeIndex < attributesLength;
  1037             public Object next() {
  1038                 if (!hasNext()) {
  1039                     throw new NoSuchElementException();
  1041                 Node current = attributes.item(attributeIndex++);
  1042                 currentName = current.getNodeName();
  1044                 String prefix = NameImpl.getPrefixFromTagName(currentName);
  1045                 if (prefix.length() == 0) {
  1046                     return NameImpl.createFromUnqualifiedName(currentName);
  1047                 } else {
  1048                     Name attributeName =
  1049                         NameImpl.createFromQualifiedName(
  1050                             currentName,
  1051                             current.getNamespaceURI());
  1052                     return attributeName;
  1056             public void remove() {
  1057                 if (currentName == null) {
  1058                     throw new IllegalStateException();
  1060                 attributes.removeNamedItem(currentName);
  1062         };
  1065     protected static String getAttributeValueFrom(Element element, Name name) {
  1066       return getAttributeValueFrom(
  1067           element,
  1068           name.getURI(),
  1069           name.getLocalName(),
  1070           name.getPrefix(),
  1071           name.getQualifiedName());
  1074     private static String getAttributeValueFrom(
  1075         Element element,
  1076         String uri,
  1077         String localName,
  1078         String prefix,
  1079         String qualifiedName) {
  1081         String nonzeroLengthUri =
  1082             (uri == null || uri.length() == 0) ? null : uri;
  1084         boolean mustUseGetAttributeNodeNS =  (nonzeroLengthUri != null);
  1086         if (mustUseGetAttributeNodeNS) {
  1088             if (!element.hasAttributeNS(uri, localName)) {
  1089                 return null;
  1092             String attrValue =
  1093                 element.getAttributeNS(nonzeroLengthUri, localName);
  1095             return attrValue;
  1098         Attr attribute = null;
  1099         attribute = element.getAttributeNode(qualifiedName);
  1101         return attribute == null ? null : attribute.getValue();
  1104     protected static Iterator getChildElementsFrom(final Element element) {
  1105         return new Iterator() {
  1106             Node next = element.getFirstChild();
  1107             Node nextNext = null;
  1108             Node last = null;
  1110             public boolean hasNext() {
  1111                 if (next != null) {
  1112                     return true;
  1114                 if (next == null && nextNext != null) {
  1115                     next = nextNext;
  1118                 return next != null;
  1121             public Object next() {
  1122                 if (hasNext()) {
  1123                     last = next;
  1124                     next = null;
  1126                     if ((element instanceof ElementImpl)
  1127                         && (last instanceof Element)) {
  1128                         last =
  1129                             ((ElementImpl) element).convertToSoapElement(
  1130                                 (Element) last);
  1133                     nextNext = last.getNextSibling();
  1134                     return last;
  1136                 throw new NoSuchElementException();
  1139             public void remove() {
  1140                 if (last == null) {
  1141                     throw new IllegalStateException();
  1143                 Node target = last;
  1144                 last = null;
  1145                 element.removeChild(target);
  1147         };
  1150     public static String getQualifiedName(QName name) {
  1151         String prefix = name.getPrefix();
  1152         String localName = name.getLocalPart();
  1153         String qualifiedName = null;
  1155             if (prefix != null && prefix.length() > 0) {
  1156                 qualifiedName = prefix + ":" + localName;
  1157             } else {
  1158                 qualifiedName = localName;
  1160          return qualifiedName;
  1163     public static String getLocalPart(String qualifiedName) {
  1164         if (qualifiedName == null) {
  1165             // Log
  1166             throw new IllegalArgumentException("Cannot get local name for a \"null\" qualified name");
  1169         int index = qualifiedName.indexOf(':');
  1170         if (index < 0)
  1171             return qualifiedName;
  1172         else
  1173             return qualifiedName.substring(index + 1);
  1176     public static String getPrefix(String qualifiedName) {
  1177         if (qualifiedName == null) {
  1178             // Log
  1179             throw new IllegalArgumentException("Cannot get prefix for a  \"null\" qualified name");
  1182         int index = qualifiedName.indexOf(':');
  1183         if (index < 0)
  1184             return "";
  1185         else
  1186             return qualifiedName.substring(0, index);
  1189     protected boolean isNamespaceQualified(Name name) {
  1190         return !"".equals(name.getURI());
  1193     protected boolean isNamespaceQualified(QName name) {
  1194         return !"".equals(name.getNamespaceURI());
  1197     protected SOAPElement circumventBug5034339(SOAPElement element) {
  1199         Name elementName = element.getElementName();
  1200         if (!isNamespaceQualified(elementName)) {
  1201             String prefix = elementName.getPrefix();
  1202             String defaultNamespace = getNamespaceURI(prefix);
  1203             if (defaultNamespace != null) {
  1204                 Name newElementName =
  1205                     NameImpl.create(
  1206                         elementName.getLocalName(),
  1207                         elementName.getPrefix(),
  1208                         defaultNamespace);
  1209                 SOAPElement newElement = createElement(newElementName);
  1210                 replaceChild(newElement, element);
  1211                 return newElement;
  1214         return element;
  1217     //TODO: This is a temporary SAAJ workaround for optimizing XWS
  1218     // should be removed once the corresponding JAXP bug is fixed
  1219     // It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe)
  1220     public void setAttributeNS(
  1221         String namespaceURI,String qualifiedName, String value) {
  1222         int index = qualifiedName.indexOf(':');
  1223         String prefix, localName;
  1224         if (index < 0) {
  1225             prefix = null;
  1226             localName = qualifiedName;
  1228         else {
  1229             prefix = qualifiedName.substring(0, index);
  1230             localName = qualifiedName.substring(index + 1);
  1233         // Workaround for bug 6467808 - This needs to be fixed in JAXP
  1235         // Rolling back this fix, this is a wrong fix, infact its causing other regressions in JAXWS tck and
  1236         // other tests, because of this change the namespace declarations on soapenv:Fault element are never
  1237         // picked up. The fix for bug 6467808 should be in JAXP.
  1238 //        if(elementQName.getLocalPart().equals("Fault") &&
  1239 //                (SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE.equals(value) ||
  1240 //                SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE.equals(value)))
  1241 //            return;
  1243         super.setAttributeNS(namespaceURI,qualifiedName,value);
  1244         //String tmpLocalName = this.getLocalName();
  1245         String tmpURI = this.getNamespaceURI();
  1246         boolean isIDNS = false;
  1247         if( tmpURI != null && (tmpURI.equals(DSIG_NS) || tmpURI.equals(XENC_NS))){
  1248             isIDNS = true;
  1250         //No need to check for Signature/encryption element
  1251         //just check for namespace.
  1252         if(localName.equals("Id")){
  1253             if(namespaceURI == null || namespaceURI.equals("")){
  1254                 setIdAttribute(localName,true);
  1255             }else if(isIDNS || WSU_NS.equals(namespaceURI)){
  1256                 setIdAttributeNS(namespaceURI,localName,true);

mercurial