0001: /*
0002: * $Id: ElementImpl.java,v 1.1.1.1 2006/01/27 13:10:57 kumarjayanti Exp $
0003: * $Revision: 1.1.1.1 $
0004: * $Date: 2006/01/27 13:10:57 $
0005: */
0006:
0007: /*
0008: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
0009: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0010: *
0011: * This code is free software; you can redistribute it and/or modify it
0012: * under the terms of the GNU General Public License version 2 only, as
0013: * published by the Free Software Foundation. Sun designates this
0014: * particular file as subject to the "Classpath" exception as provided
0015: * by Sun in the LICENSE file that accompanied this code.
0016: *
0017: * This code is distributed in the hope that it will be useful, but WITHOUT
0018: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0019: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0020: * version 2 for more details (a copy is included in the LICENSE file that
0021: * accompanied this code).
0022: *
0023: * You should have received a copy of the GNU General Public License version
0024: * 2 along with this work; if not, write to the Free Software Foundation,
0025: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0026: *
0027: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0028: * CA 95054 USA or visit www.sun.com if you need additional information or
0029: * have any questions.
0030: */
0031: package com.sun.xml.internal.messaging.saaj.soap.impl;
0032:
0033: import java.util.*;
0034: import java.util.logging.Level;
0035: import java.util.logging.Logger;
0036:
0037: import javax.xml.namespace.QName;
0038: import javax.xml.soap.*;
0039:
0040: import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
0041: import org.w3c.dom.*;
0042: import org.w3c.dom.Node;
0043:
0044: import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
0045: import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument;
0046: import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl;
0047: import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
0048: import com.sun.xml.internal.messaging.saaj.util.*;
0049:
0050: public class ElementImpl extends
0051: com.sun.org.apache.xerces.internal.dom.ElementNSImpl implements
0052: SOAPElement, SOAPBodyElement {
0053:
0054: public static final String DSIG_NS = "http://www.w3.org/2000/09/xmldsig#"
0055: .intern();
0056: public static final String XENC_NS = "http://www.w3.org/2001/04/xmlenc#"
0057: .intern();
0058: public static final String WSU_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
0059: .intern();
0060:
0061: private AttributeManager encodingStyleAttribute = new AttributeManager();
0062:
0063: protected QName elementQName;
0064:
0065: protected static Logger log = Logger
0066: .getLogger(LogDomainConstants.SOAP_IMPL_DOMAIN,
0067: "com.sun.xml.internal.messaging.saaj.soap.impl.LocalStrings");
0068:
0069: public ElementImpl(SOAPDocumentImpl ownerDoc, Name name) {
0070: super (ownerDoc, name.getURI(), name.getQualifiedName(), name
0071: .getLocalName());
0072: elementQName = NameImpl.convertToQName(name);
0073: }
0074:
0075: public ElementImpl(SOAPDocumentImpl ownerDoc, QName name) {
0076: super (ownerDoc, name.getNamespaceURI(), getQualifiedName(name),
0077: name.getLocalPart());
0078: elementQName = name;
0079: }
0080:
0081: public ElementImpl(SOAPDocumentImpl ownerDoc, String uri,
0082: String qualifiedName) {
0083:
0084: super (ownerDoc, uri, qualifiedName);
0085: elementQName = new QName(uri, getLocalPart(qualifiedName),
0086: getPrefix(qualifiedName));
0087: }
0088:
0089: public void ensureNamespaceIsDeclared(String prefix, String uri) {
0090: String alreadyDeclaredUri = getNamespaceURI(prefix);
0091: if (alreadyDeclaredUri == null
0092: || !alreadyDeclaredUri.equals(uri)) {
0093: try {
0094: addNamespaceDeclaration(prefix, uri);
0095: } catch (SOAPException e) { /*ignore*/
0096: }
0097: }
0098: }
0099:
0100: public Document getOwnerDocument() {
0101: SOAPDocument ownerSOAPDocument = ((SOAPDocument) super
0102: .getOwnerDocument());
0103: if (ownerSOAPDocument == null) {
0104: return null;
0105: }
0106: return ownerSOAPDocument.getDocument();
0107: }
0108:
0109: public SOAPElement addChildElement(Name name) throws SOAPException {
0110: return addElement(name);
0111: }
0112:
0113: public SOAPElement addChildElement(QName qname)
0114: throws SOAPException {
0115: return addElement(qname);
0116: }
0117:
0118: public SOAPElement addChildElement(String localName)
0119: throws SOAPException {
0120: return (SOAPElement) addChildElement(NameImpl
0121: .createFromUnqualifiedName(localName));
0122: }
0123:
0124: public SOAPElement addChildElement(String localName, String prefix)
0125: throws SOAPException {
0126: String uri = getNamespaceURI(prefix);
0127: if (uri == null) {
0128: log.log(Level.SEVERE,
0129: "SAAJ0101.impl.parent.of.body.elem.mustbe.body",
0130: new String[] { prefix });
0131: throw new SOAPExceptionImpl(
0132: "Unable to locate namespace for prefix " + prefix);
0133: }
0134: return addChildElement(localName, prefix, uri);
0135: }
0136:
0137: public String getNamespaceURI(String prefix) {
0138:
0139: if ("xmlns".equals(prefix)) {
0140: return NamespaceContext.XMLNS_URI;
0141: }
0142:
0143: if ("xml".equals(prefix)) {
0144: return NamespaceContext.XML_URI;
0145: }
0146:
0147: if ("".equals(prefix)) {
0148:
0149: org.w3c.dom.Node currentAncestor = this ;
0150: while (currentAncestor != null
0151: && !(currentAncestor instanceof Document)) {
0152:
0153: if (currentAncestor instanceof ElementImpl) {
0154: QName name = ((ElementImpl) currentAncestor)
0155: .getElementQName();
0156: /*
0157: if (prefix.equals(name.getPrefix())) {
0158: String uri = name.getNamespaceURI();
0159: if ("".equals(uri)) {
0160: return null;
0161: }
0162: else {
0163: return uri;
0164: }
0165: }*/
0166: if (((Element) currentAncestor).hasAttributeNS(
0167: NamespaceContext.XMLNS_URI, "xmlns")) {
0168:
0169: String uri = ((Element) currentAncestor)
0170: .getAttributeNS(
0171: NamespaceContext.XMLNS_URI,
0172: "xmlns");
0173: if ("".equals(uri))
0174: return null;
0175: else {
0176: return uri;
0177: }
0178: }
0179: }
0180: currentAncestor = currentAncestor.getParentNode();
0181: }
0182:
0183: } else if (prefix != null) {
0184: // Find if there's an ancester whose name contains this prefix
0185: org.w3c.dom.Node currentAncestor = this ;
0186: while (currentAncestor != null
0187: && !(currentAncestor instanceof Document)) {
0188: /*
0189: if (prefix.equals(currentAncestor.getPrefix())) {
0190: String uri = currentAncestor.getNamespaceURI();
0191: // this is because the javadoc says getNamespaceURI() is not a computed value
0192: // and URI for a non-empty prefix cannot be null
0193: if (uri != null)
0194: return uri;
0195: }*/
0196: if (((Element) currentAncestor).hasAttributeNS(
0197: NamespaceContext.XMLNS_URI, prefix)) {
0198: return ((Element) currentAncestor).getAttributeNS(
0199: NamespaceContext.XMLNS_URI, prefix);
0200: }
0201:
0202: currentAncestor = currentAncestor.getParentNode();
0203: }
0204: }
0205:
0206: return null;
0207: }
0208:
0209: public SOAPElement setElementQName(QName newName)
0210: throws SOAPException {
0211: ElementImpl copy = new ElementImpl(
0212: (SOAPDocumentImpl) getOwnerDocument(), newName);
0213: return replaceElementWithSOAPElement(this , copy);
0214: }
0215:
0216: public QName createQName(String localName, String prefix)
0217: throws SOAPException {
0218: String uri = getNamespaceURI(prefix);
0219: if (uri == null) {
0220: log.log(Level.SEVERE, "SAAJ0102.impl.cannot.locate.ns",
0221: new Object[] { prefix });
0222: throw new SOAPException(
0223: "Unable to locate namespace for prefix " + prefix);
0224: }
0225: return new QName(uri, localName, prefix);
0226: }
0227:
0228: public String getNamespacePrefix(String uri) {
0229:
0230: NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
0231: while (eachNamespace.hasNext()) {
0232: org.w3c.dom.Attr namespaceDecl = eachNamespace
0233: .nextNamespaceAttr();
0234: if (namespaceDecl.getNodeValue().equals(uri)) {
0235: String candidatePrefix = namespaceDecl.getLocalName();
0236: if ("xmlns".equals(candidatePrefix))
0237: return "";
0238: else
0239: return candidatePrefix;
0240: }
0241: }
0242:
0243: // Find if any of the ancestors' name has this uri
0244: org.w3c.dom.Node currentAncestor = this ;
0245: while (currentAncestor != null
0246: && !(currentAncestor instanceof Document)) {
0247:
0248: if (uri.equals(currentAncestor.getNamespaceURI()))
0249: return currentAncestor.getPrefix();
0250: currentAncestor = currentAncestor.getParentNode();
0251: }
0252:
0253: return null;
0254: }
0255:
0256: protected org.w3c.dom.Attr getNamespaceAttr(String prefix) {
0257: NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
0258: if (!"".equals(prefix))
0259: prefix = ":" + prefix;
0260: while (eachNamespace.hasNext()) {
0261: org.w3c.dom.Attr namespaceDecl = eachNamespace
0262: .nextNamespaceAttr();
0263: if (!"".equals(prefix)) {
0264: if (namespaceDecl.getNodeName().endsWith(prefix))
0265: return namespaceDecl;
0266: } else {
0267: if (namespaceDecl.getNodeName().equals("xmlns"))
0268: return namespaceDecl;
0269: }
0270: }
0271: return null;
0272: }
0273:
0274: public NamespaceContextIterator getNamespaceContextNodes() {
0275: return getNamespaceContextNodes(true);
0276: }
0277:
0278: public NamespaceContextIterator getNamespaceContextNodes(
0279: boolean traverseStack) {
0280: return new NamespaceContextIterator(this , traverseStack);
0281: }
0282:
0283: public SOAPElement addChildElement(String localName, String prefix,
0284: String uri) throws SOAPException {
0285:
0286: SOAPElement newElement = createElement(NameImpl.create(
0287: localName, prefix, uri));
0288: addNode(newElement);
0289: return convertToSoapElement(newElement);
0290: }
0291:
0292: public SOAPElement addChildElement(SOAPElement element)
0293: throws SOAPException {
0294:
0295: // check if Element falls in SOAP 1.1 or 1.2 namespace.
0296: String elementURI = element.getElementName().getURI();
0297: String localName = element.getLocalName();
0298:
0299: if ((SOAPConstants.URI_NS_SOAP_ENVELOPE).equals(elementURI)
0300: || (SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE)
0301: .equals(elementURI)) {
0302:
0303: if ("Envelope".equalsIgnoreCase(localName)
0304: || "Header".equalsIgnoreCase(localName)
0305: || "Body".equalsIgnoreCase(localName)) {
0306: log.severe("SAAJ0103.impl.cannot.add.fragements");
0307: throw new SOAPExceptionImpl(
0308: "Cannot add fragments which contain elements "
0309: + "which are in the SOAP namespace");
0310: }
0311:
0312: if ("Fault".equalsIgnoreCase(localName)
0313: && !"Body".equalsIgnoreCase(this .getLocalName())) {
0314: log.severe("SAAJ0154.impl.adding.fault.to.nonbody");
0315: throw new SOAPExceptionImpl(
0316: "Cannot add a SOAPFault as a child of "
0317: + this .getLocalName());
0318: }
0319:
0320: if ("Detail".equalsIgnoreCase(localName)
0321: && !"Fault".equalsIgnoreCase(this .getLocalName())) {
0322: log.severe("SAAJ0155.impl.adding.detail.nonfault");
0323: throw new SOAPExceptionImpl(
0324: "Cannot add a Detail as a child of "
0325: + this .getLocalName());
0326: }
0327:
0328: if ("Fault".equalsIgnoreCase(localName)) {
0329: // if body is not empty throw an exception
0330: if (!elementURI.equals(this .getElementName().getURI())) {
0331: log.severe("SAAJ0158.impl.version.mismatch.fault");
0332: throw new SOAPExceptionImpl(
0333: "SOAP Version mismatch encountered when trying to add SOAPFault to SOAPBody");
0334: }
0335: Iterator it = this .getChildElements();
0336: if (it.hasNext()) {
0337: log.severe("SAAJ0156.impl.adding.fault.error");
0338: throw new SOAPExceptionImpl(
0339: "Cannot add SOAPFault as a child of a non-Empty SOAPBody");
0340: }
0341: }
0342: }
0343:
0344: // preserve the encodingStyle attr as it may get lost in the import
0345: String encodingStyle = element.getEncodingStyle();
0346:
0347: ElementImpl importedElement = (ElementImpl) importElement(element);
0348: addNode(importedElement);
0349:
0350: if (encodingStyle != null)
0351: importedElement.setEncodingStyle(encodingStyle);
0352:
0353: return convertToSoapElement(importedElement);
0354: }
0355:
0356: protected Element importElement(Element element) {
0357: Document document = getOwnerDocument();
0358: Document oldDocument = element.getOwnerDocument();
0359: if (!oldDocument.equals(document)) {
0360: return (Element) document.importNode(element, true);
0361: } else {
0362: return element;
0363: }
0364: }
0365:
0366: protected SOAPElement addElement(Name name) throws SOAPException {
0367: SOAPElement newElement = createElement(name);
0368: addNode(newElement);
0369: return circumventBug5034339(newElement);
0370: }
0371:
0372: protected SOAPElement addElement(QName name) throws SOAPException {
0373: SOAPElement newElement = createElement(name);
0374: addNode(newElement);
0375: return circumventBug5034339(newElement);
0376: }
0377:
0378: protected SOAPElement createElement(Name name) {
0379:
0380: if (isNamespaceQualified(name)) {
0381: return (SOAPElement) getOwnerDocument().createElementNS(
0382: name.getURI(), name.getQualifiedName());
0383: } else {
0384: return (SOAPElement) getOwnerDocument().createElement(
0385: name.getQualifiedName());
0386: }
0387: }
0388:
0389: protected SOAPElement createElement(QName name) {
0390:
0391: if (isNamespaceQualified(name)) {
0392: return (SOAPElement) getOwnerDocument().createElementNS(
0393: name.getNamespaceURI(), getQualifiedName(name));
0394: } else {
0395: return (SOAPElement) getOwnerDocument().createElement(
0396: getQualifiedName(name));
0397: }
0398: }
0399:
0400: protected void addNode(org.w3c.dom.Node newElement)
0401: throws SOAPException {
0402: insertBefore(newElement, null);
0403:
0404: if (getOwnerDocument() instanceof DocumentFragment)
0405: return;
0406:
0407: if (newElement instanceof ElementImpl) {
0408: ElementImpl element = (ElementImpl) newElement;
0409: QName elementName = element.getElementQName();
0410: if (!"".equals(elementName.getNamespaceURI())) {
0411: element.ensureNamespaceIsDeclared(elementName
0412: .getPrefix(), elementName.getNamespaceURI());
0413: }
0414: }
0415:
0416: }
0417:
0418: protected SOAPElement findChild(NameImpl name) {
0419: Iterator eachChild = getChildElementNodes();
0420: while (eachChild.hasNext()) {
0421: SOAPElement child = (SOAPElement) eachChild.next();
0422: if (child.getElementName().equals(name)) {
0423: return child;
0424: }
0425: }
0426:
0427: return null;
0428: }
0429:
0430: public SOAPElement addTextNode(String text) throws SOAPException {
0431: if (text.startsWith(CDATAImpl.cdataUC)
0432: || text.startsWith(CDATAImpl.cdataLC))
0433: return addCDATA(text.substring(CDATAImpl.cdataUC.length(),
0434: text.length() - 3));
0435: return addText(text);
0436: }
0437:
0438: protected SOAPElement addCDATA(String text) throws SOAPException {
0439: org.w3c.dom.Text cdata = (org.w3c.dom.Text) getOwnerDocument()
0440: .createCDATASection(text);
0441: addNode(cdata);
0442: return this ;
0443: }
0444:
0445: protected SOAPElement addText(String text) throws SOAPException {
0446: org.w3c.dom.Text textNode = (org.w3c.dom.Text) getOwnerDocument()
0447: .createTextNode(text);
0448: addNode(textNode);
0449: return this ;
0450: }
0451:
0452: public SOAPElement addAttribute(Name name, String value)
0453: throws SOAPException {
0454: addAttributeBare(name, value);
0455: if (!"".equals(name.getURI())) {
0456: ensureNamespaceIsDeclared(name.getPrefix(), name.getURI());
0457: }
0458: return this ;
0459: }
0460:
0461: public SOAPElement addAttribute(QName qname, String value)
0462: throws SOAPException {
0463: addAttributeBare(qname, value);
0464: if (!"".equals(qname.getNamespaceURI())) {
0465: ensureNamespaceIsDeclared(qname.getPrefix(), qname
0466: .getNamespaceURI());
0467: }
0468: return this ;
0469: }
0470:
0471: private void addAttributeBare(Name name, String value) {
0472: addAttributeBare(name.getURI(), name.getPrefix(), name
0473: .getQualifiedName(), value);
0474: }
0475:
0476: private void addAttributeBare(QName name, String value) {
0477: addAttributeBare(name.getNamespaceURI(), name.getPrefix(),
0478: getQualifiedName(name), value);
0479: }
0480:
0481: private void addAttributeBare(String uri, String prefix,
0482: String qualifiedName, String value) {
0483:
0484: uri = uri.length() == 0 ? null : uri;
0485: if (qualifiedName.equals("xmlns")) {
0486: uri = NamespaceContext.XMLNS_URI;
0487: }
0488:
0489: if (uri == null) {
0490: setAttribute(qualifiedName, value);
0491: } else {
0492: setAttributeNS(uri, qualifiedName, value);
0493: }
0494: }
0495:
0496: public SOAPElement addNamespaceDeclaration(String prefix, String uri)
0497: throws SOAPException {
0498: if (prefix.length() > 0) {
0499: setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns:"
0500: + prefix, uri);
0501: } else {
0502: setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns", uri);
0503: }
0504: tryToFindEncodingStyleAttributeName();
0505: return this ;
0506: }
0507:
0508: public String getAttributeValue(Name name) {
0509: return getAttributeValueFrom(this , name);
0510: }
0511:
0512: public String getAttributeValue(QName qname) {
0513: return getAttributeValueFrom(this , qname.getNamespaceURI(),
0514: qname.getLocalPart(), qname.getPrefix(),
0515: getQualifiedName(qname));
0516: }
0517:
0518: public Iterator getAllAttributes() {
0519: Iterator i = getAllAttributesFrom(this );
0520: ArrayList list = new ArrayList();
0521: while (i.hasNext()) {
0522: Name name = (Name) i.next();
0523: if (!"xmlns".equalsIgnoreCase(name.getPrefix()))
0524: list.add(name);
0525: }
0526: return list.iterator();
0527: }
0528:
0529: public Iterator getAllAttributesAsQNames() {
0530: Iterator i = getAllAttributesFrom(this );
0531: ArrayList list = new ArrayList();
0532: while (i.hasNext()) {
0533: Name name = (Name) i.next();
0534: if (!"xmlns".equalsIgnoreCase(name.getPrefix())) {
0535: list.add(NameImpl.convertToQName(name));
0536: }
0537: }
0538: return list.iterator();
0539: }
0540:
0541: public Iterator getNamespacePrefixes() {
0542: return doGetNamespacePrefixes(false);
0543: }
0544:
0545: public Iterator getVisibleNamespacePrefixes() {
0546: return doGetNamespacePrefixes(true);
0547: }
0548:
0549: protected Iterator doGetNamespacePrefixes(final boolean deep) {
0550: return new Iterator() {
0551: String next = null;
0552: String last = null;
0553: NamespaceContextIterator eachNamespace = getNamespaceContextNodes(deep);
0554:
0555: void findNext() {
0556: while (next == null && eachNamespace.hasNext()) {
0557: String attributeKey = eachNamespace
0558: .nextNamespaceAttr().getNodeName();
0559: if (attributeKey.startsWith("xmlns:")) {
0560: next = attributeKey
0561: .substring("xmlns:".length());
0562: }
0563: }
0564: }
0565:
0566: public boolean hasNext() {
0567: findNext();
0568: return next != null;
0569: }
0570:
0571: public Object next() {
0572: findNext();
0573: if (next == null) {
0574: throw new NoSuchElementException();
0575: }
0576:
0577: last = next;
0578: next = null;
0579: return last;
0580: }
0581:
0582: public void remove() {
0583: if (last == null) {
0584: throw new IllegalStateException();
0585: }
0586: eachNamespace.remove();
0587: next = null;
0588: last = null;
0589: }
0590: };
0591: }
0592:
0593: public Name getElementName() {
0594: return NameImpl.convertToName(elementQName);
0595: }
0596:
0597: public QName getElementQName() {
0598: return elementQName;
0599: }
0600:
0601: public boolean removeAttribute(Name name) {
0602: return removeAttribute(name.getURI(), name.getLocalName());
0603: }
0604:
0605: public boolean removeAttribute(QName name) {
0606: return removeAttribute(name.getNamespaceURI(), name
0607: .getLocalPart());
0608: }
0609:
0610: private boolean removeAttribute(String uri, String localName) {
0611: String nonzeroLengthUri = (uri == null || uri.length() == 0) ? null
0612: : uri;
0613: org.w3c.dom.Attr attribute = getAttributeNodeNS(
0614: nonzeroLengthUri, localName);
0615: if (attribute == null) {
0616: return false;
0617: }
0618: removeAttributeNode(attribute);
0619: return true;
0620: }
0621:
0622: public boolean removeNamespaceDeclaration(String prefix) {
0623: org.w3c.dom.Attr declaration = getNamespaceAttr(prefix);
0624: if (declaration == null) {
0625: return false;
0626: }
0627: try {
0628: removeAttributeNode(declaration);
0629: } catch (DOMException de) {
0630: // ignore
0631: }
0632: return true;
0633: }
0634:
0635: public Iterator getChildElements() {
0636: return getChildElementsFrom(this );
0637: }
0638:
0639: protected SOAPElement convertToSoapElement(Element element) {
0640: if (element instanceof SOAPElement) {
0641: return (SOAPElement) element;
0642: } else {
0643: return replaceElementWithSOAPElement(element,
0644: (ElementImpl) createElement(NameImpl
0645: .copyElementName(element)));
0646: }
0647: }
0648:
0649: protected static SOAPElement replaceElementWithSOAPElement(
0650: Element element, ElementImpl copy) {
0651:
0652: Iterator eachAttribute = getAllAttributesFrom(element);
0653: while (eachAttribute.hasNext()) {
0654: Name name = (Name) eachAttribute.next();
0655: copy.addAttributeBare(name, getAttributeValueFrom(element,
0656: name));
0657: }
0658:
0659: Iterator eachChild = getChildElementsFrom(element);
0660: while (eachChild.hasNext()) {
0661: Node nextChild = (Node) eachChild.next();
0662: copy.insertBefore(nextChild, null);
0663: }
0664:
0665: Node parent = element.getParentNode();
0666: if (parent != null) {
0667: parent.replaceChild(copy, element);
0668: } // XXX else throw an exception?
0669:
0670: return copy;
0671: }
0672:
0673: protected Iterator getChildElementNodes() {
0674: return new Iterator() {
0675: Iterator eachNode = getChildElements();
0676: Node next = null;
0677: Node last = null;
0678:
0679: public boolean hasNext() {
0680: if (next == null) {
0681: while (eachNode.hasNext()) {
0682: Node node = (Node) eachNode.next();
0683: if (node instanceof SOAPElement) {
0684: next = node;
0685: break;
0686: }
0687: }
0688: }
0689: return next != null;
0690: }
0691:
0692: public Object next() {
0693: if (hasNext()) {
0694: last = next;
0695: next = null;
0696: return last;
0697: }
0698: throw new NoSuchElementException();
0699: }
0700:
0701: public void remove() {
0702: if (last == null) {
0703: throw new IllegalStateException();
0704: }
0705: Node target = last;
0706: last = null;
0707: removeChild(target);
0708: }
0709: };
0710: }
0711:
0712: public Iterator getChildElements(final Name name) {
0713: return getChildElements(name.getURI(), name.getLocalName());
0714: }
0715:
0716: public Iterator getChildElements(final QName qname) {
0717: return getChildElements(qname.getNamespaceURI(), qname
0718: .getLocalPart());
0719: }
0720:
0721: private Iterator getChildElements(final String nameUri,
0722: final String nameLocal) {
0723: return new Iterator() {
0724: Iterator eachElement = getChildElementNodes();
0725: Node next = null;
0726: Node last = null;
0727:
0728: public boolean hasNext() {
0729: if (next == null) {
0730: while (eachElement.hasNext()) {
0731: Node element = (Node) eachElement.next();
0732: String elementUri = element.getNamespaceURI();
0733: elementUri = elementUri == null ? ""
0734: : elementUri;
0735: String elementName = element.getLocalName();
0736: if (elementUri.equals(nameUri)
0737: && elementName.equals(nameLocal)) {
0738: next = element;
0739: break;
0740: }
0741: }
0742: }
0743: return next != null;
0744: }
0745:
0746: public Object next() {
0747: if (!hasNext()) {
0748: throw new NoSuchElementException();
0749: }
0750: last = next;
0751: next = null;
0752: return last;
0753: }
0754:
0755: public void remove() {
0756: if (last == null) {
0757: throw new IllegalStateException();
0758: }
0759: Node target = last;
0760: last = null;
0761: removeChild(target);
0762: }
0763: };
0764: }
0765:
0766: public void removeContents() {
0767: Node currentChild = getFirstChild();
0768:
0769: while (currentChild != null) {
0770: Node temp = currentChild.getNextSibling();
0771: if (currentChild instanceof javax.xml.soap.Node) {
0772: ((javax.xml.soap.Node) currentChild).detachNode();
0773: } else {
0774: Node parent = currentChild.getParentNode();
0775: if (parent != null) {
0776: parent.removeChild(currentChild);
0777: }
0778:
0779: }
0780: currentChild = temp;
0781: }
0782: }
0783:
0784: public void setEncodingStyle(String encodingStyle)
0785: throws SOAPException {
0786: if (!"".equals(encodingStyle)) {
0787: try {
0788: JaxmURI uri = new JaxmURI(encodingStyle);
0789: } catch (JaxmURI.MalformedURIException m) {
0790: log
0791: .log(
0792: Level.SEVERE,
0793: "SAAJ0105.impl.encoding.style.mustbe.valid.URI",
0794: new String[] { encodingStyle });
0795: throw new IllegalArgumentException("Encoding style ("
0796: + encodingStyle + ") should be a valid URI");
0797: }
0798: }
0799: encodingStyleAttribute.setValue(encodingStyle);
0800: tryToFindEncodingStyleAttributeName();
0801: }
0802:
0803: public String getEncodingStyle() {
0804: String encodingStyle = encodingStyleAttribute.getValue();
0805: if (encodingStyle != null)
0806: return encodingStyle;
0807: String soapNamespace = getSOAPNamespace();
0808: if (soapNamespace != null) {
0809: Attr attr = getAttributeNodeNS(soapNamespace,
0810: "encodingStyle");
0811: if (attr != null) {
0812: encodingStyle = attr.getValue();
0813: try {
0814: setEncodingStyle(encodingStyle);
0815: } catch (SOAPException se) {
0816: // has to be ignored
0817: }
0818: return encodingStyle;
0819: }
0820: }
0821: return null;
0822: }
0823:
0824: // Node methods
0825: public String getValue() {
0826: javax.xml.soap.Node valueNode = getValueNode();
0827: return valueNode == null ? null : valueNode.getValue();
0828: }
0829:
0830: public void setValue(String value) {
0831: Node valueNode = getValueNodeStrict();
0832: if (valueNode != null) {
0833: valueNode.setNodeValue(value);
0834: } else {
0835: try {
0836: addTextNode(value);
0837: } catch (SOAPException e) {
0838: throw new RuntimeException(e.getMessage());
0839: }
0840: }
0841: }
0842:
0843: protected Node getValueNodeStrict() {
0844: Node node = getFirstChild();
0845: if (node != null) {
0846: if (node.getNextSibling() == null
0847: && node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
0848: return node;
0849: } else {
0850: log.severe("SAAJ0107.impl.elem.child.not.single.text");
0851: throw new IllegalStateException();
0852: }
0853: }
0854:
0855: return null;
0856: }
0857:
0858: protected javax.xml.soap.Node getValueNode() {
0859: Iterator i = getChildElements();
0860: while (i.hasNext()) {
0861: javax.xml.soap.Node n = (javax.xml.soap.Node) i.next();
0862: if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE
0863: || n.getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) {
0864: // TODO: Hack to fix text node split into multiple lines.
0865: normalize();
0866: // Should remove the normalization step when this gets fixed in
0867: // DOM/Xerces.
0868: return (javax.xml.soap.Node) n;
0869: }
0870: }
0871: return null;
0872: }
0873:
0874: public void setParentElement(SOAPElement element)
0875: throws SOAPException {
0876: if (element == null) {
0877: log.severe("SAAJ0106.impl.no.null.to.parent.elem");
0878: throw new SOAPException(
0879: "Cannot pass NULL to setParentElement");
0880: }
0881: element.addChildElement(this );
0882: findEncodingStyleAttributeName();
0883: }
0884:
0885: protected void findEncodingStyleAttributeName()
0886: throws SOAPException {
0887: String soapNamespace = getSOAPNamespace();
0888: if (soapNamespace != null) {
0889: String soapNamespacePrefix = getNamespacePrefix(soapNamespace);
0890: if (soapNamespacePrefix != null) {
0891: setEncodingStyleNamespace(soapNamespace,
0892: soapNamespacePrefix);
0893: }
0894: }
0895: }
0896:
0897: protected void setEncodingStyleNamespace(String soapNamespace,
0898: String soapNamespacePrefix) throws SOAPException {
0899: Name encodingStyleAttributeName = NameImpl.create(
0900: "encodingStyle", soapNamespacePrefix, soapNamespace);
0901: encodingStyleAttribute.setName(encodingStyleAttributeName);
0902: }
0903:
0904: public SOAPElement getParentElement() {
0905: Node parentNode = getParentNode();
0906: if (parentNode instanceof SOAPDocument) {
0907: return null;
0908: }
0909: return (SOAPElement) parentNode;
0910: }
0911:
0912: protected String getSOAPNamespace() {
0913: String soapNamespace = null;
0914:
0915: SOAPElement antecedent = this ;
0916: while (antecedent != null) {
0917: Name antecedentName = antecedent.getElementName();
0918: String antecedentNamespace = antecedentName.getURI();
0919:
0920: if (NameImpl.SOAP11_NAMESPACE.equals(antecedentNamespace)
0921: || NameImpl.SOAP12_NAMESPACE
0922: .equals(antecedentNamespace)) {
0923:
0924: soapNamespace = antecedentNamespace;
0925: break;
0926: }
0927:
0928: antecedent = antecedent.getParentElement();
0929: }
0930:
0931: return soapNamespace;
0932: }
0933:
0934: public void detachNode() {
0935: Node parent = getParentNode();
0936: if (parent != null) {
0937: parent.removeChild(this );
0938: }
0939: encodingStyleAttribute.clearName();
0940: tryToFindEncodingStyleAttributeName();
0941: }
0942:
0943: public void tryToFindEncodingStyleAttributeName() {
0944: try {
0945: findEncodingStyleAttributeName();
0946: } catch (SOAPException e) { /*okay to fail*/
0947: }
0948: }
0949:
0950: public void recycleNode() {
0951: detachNode();
0952: // TBD
0953: // - add this to the factory so subsequent
0954: // creations can reuse this object.
0955: }
0956:
0957: class AttributeManager {
0958: Name attributeName = null;
0959: String attributeValue = null;
0960:
0961: public void setName(Name newName) throws SOAPException {
0962: clearAttribute();
0963: attributeName = newName;
0964: reconcileAttribute();
0965: }
0966:
0967: public void clearName() {
0968: clearAttribute();
0969: attributeName = null;
0970: }
0971:
0972: public void setValue(String value) throws SOAPException {
0973: attributeValue = value;
0974: reconcileAttribute();
0975: }
0976:
0977: public Name getName() {
0978: return attributeName;
0979: }
0980:
0981: public String getValue() {
0982: return attributeValue;
0983: }
0984:
0985: private void reconcileAttribute() throws SOAPException {
0986: if (attributeName != null) {
0987: removeAttribute(attributeName);
0988: if (attributeValue != null) {
0989: addAttribute(attributeName, attributeValue);
0990: }
0991: }
0992: }
0993:
0994: private void clearAttribute() {
0995: if (attributeName != null) {
0996: removeAttribute(attributeName);
0997: }
0998: }
0999: }
1000:
1001: protected static org.w3c.dom.Attr getNamespaceAttrFrom(
1002: Element element, String prefix) {
1003: NamespaceContextIterator eachNamespace = new NamespaceContextIterator(
1004: element);
1005: while (eachNamespace.hasNext()) {
1006: org.w3c.dom.Attr namespaceDecl = eachNamespace
1007: .nextNamespaceAttr();
1008: String declaredPrefix = NameImpl
1009: .getLocalNameFromTagName(namespaceDecl
1010: .getNodeName());
1011: if (declaredPrefix.equals(prefix)) {
1012: return namespaceDecl;
1013: }
1014: }
1015: return null;
1016: }
1017:
1018: protected static Iterator getAllAttributesFrom(final Element element) {
1019: final NamedNodeMap attributes = element.getAttributes();
1020:
1021: return new Iterator() {
1022: int attributesLength = attributes.getLength();
1023: int attributeIndex = 0;
1024: String currentName;
1025:
1026: public boolean hasNext() {
1027: return attributeIndex < attributesLength;
1028: }
1029:
1030: public Object next() {
1031: if (!hasNext()) {
1032: throw new NoSuchElementException();
1033: }
1034: Node current = attributes.item(attributeIndex++);
1035: currentName = current.getNodeName();
1036:
1037: String prefix = NameImpl
1038: .getPrefixFromTagName(currentName);
1039: if (prefix.length() == 0) {
1040: return NameImpl
1041: .createFromUnqualifiedName(currentName);
1042: } else {
1043: Name attributeName = NameImpl
1044: .createFromQualifiedName(currentName,
1045: current.getNamespaceURI());
1046: return attributeName;
1047: }
1048: }
1049:
1050: public void remove() {
1051: if (currentName == null) {
1052: throw new IllegalStateException();
1053: }
1054: attributes.removeNamedItem(currentName);
1055: }
1056: };
1057: }
1058:
1059: protected static String getAttributeValueFrom(Element element,
1060: Name name) {
1061: return getAttributeValueFrom(element, name.getURI(), name
1062: .getLocalName(), name.getPrefix(), name
1063: .getQualifiedName());
1064: }
1065:
1066: private static String getAttributeValueFrom(Element element,
1067: String uri, String localName, String prefix,
1068: String qualifiedName) {
1069:
1070: String nonzeroLengthUri = (uri == null || uri.length() == 0) ? null
1071: : uri;
1072:
1073: boolean mustUseGetAttributeNodeNS = (nonzeroLengthUri != null);
1074:
1075: if (mustUseGetAttributeNodeNS) {
1076:
1077: if (!element.hasAttributeNS(uri, localName)) {
1078: return null;
1079: }
1080:
1081: String attrValue = element.getAttributeNS(nonzeroLengthUri,
1082: localName);
1083:
1084: return attrValue;
1085: }
1086:
1087: Attr attribute = null;
1088: attribute = element.getAttributeNode(qualifiedName);
1089:
1090: return attribute == null ? null : attribute.getValue();
1091: }
1092:
1093: protected static Iterator getChildElementsFrom(final Element element) {
1094: return new Iterator() {
1095: Node next = element.getFirstChild();
1096: Node nextNext = null;
1097: Node last = null;
1098:
1099: public boolean hasNext() {
1100: if (next != null) {
1101: return true;
1102: }
1103: if (next == null && nextNext != null) {
1104: next = nextNext;
1105: }
1106:
1107: return next != null;
1108: }
1109:
1110: public Object next() {
1111: if (hasNext()) {
1112: last = next;
1113: next = null;
1114:
1115: if ((element instanceof ElementImpl)
1116: && (last instanceof Element)) {
1117: last = ((ElementImpl) element)
1118: .convertToSoapElement((Element) last);
1119: }
1120:
1121: nextNext = last.getNextSibling();
1122: return last;
1123: }
1124: throw new NoSuchElementException();
1125: }
1126:
1127: public void remove() {
1128: if (last == null) {
1129: throw new IllegalStateException();
1130: }
1131: Node target = last;
1132: last = null;
1133: element.removeChild(target);
1134: }
1135: };
1136: }
1137:
1138: public static String getQualifiedName(QName name) {
1139: String prefix = name.getPrefix();
1140: String localName = name.getLocalPart();
1141: String qualifiedName = null;
1142:
1143: if (prefix != null && prefix.length() > 0) {
1144: qualifiedName = prefix + ":" + localName;
1145: } else {
1146: qualifiedName = localName;
1147: }
1148: return qualifiedName;
1149: }
1150:
1151: public static String getLocalPart(String qualifiedName) {
1152: if (qualifiedName == null) {
1153: // Log
1154: throw new IllegalArgumentException(
1155: "Cannot get local name for a \"null\" qualified name");
1156: }
1157:
1158: int index = qualifiedName.indexOf(':');
1159: if (index < 0)
1160: return qualifiedName;
1161: else
1162: return qualifiedName.substring(index + 1);
1163: }
1164:
1165: public static String getPrefix(String qualifiedName) {
1166: if (qualifiedName == null) {
1167: // Log
1168: throw new IllegalArgumentException(
1169: "Cannot get prefix for a \"null\" qualified name");
1170: }
1171:
1172: int index = qualifiedName.indexOf(':');
1173: if (index < 0)
1174: return "";
1175: else
1176: return qualifiedName.substring(0, index);
1177: }
1178:
1179: protected boolean isNamespaceQualified(Name name) {
1180: return !"".equals(name.getURI());
1181: }
1182:
1183: protected boolean isNamespaceQualified(QName name) {
1184: return !"".equals(name.getNamespaceURI());
1185: }
1186:
1187: protected SOAPElement circumventBug5034339(SOAPElement element) {
1188:
1189: Name elementName = element.getElementName();
1190: if (!isNamespaceQualified(elementName)) {
1191: String prefix = elementName.getPrefix();
1192: String defaultNamespace = getNamespaceURI(prefix);
1193: if (defaultNamespace != null) {
1194: Name newElementName = NameImpl.create(elementName
1195: .getLocalName(), elementName.getPrefix(),
1196: defaultNamespace);
1197: SOAPElement newElement = createElement(newElementName);
1198: replaceChild(newElement, element);
1199: return newElement;
1200: }
1201: }
1202: return element;
1203: }
1204:
1205: //TODO: This is a temporary SAAJ workaround for optimizing XWS
1206: // should be removed once the corresponding JAXP bug is fixed
1207: // It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe)
1208: public void setAttributeNS(String namespaceURI,
1209: String qualifiedName, String value) {
1210: int index = qualifiedName.indexOf(':');
1211: String prefix, localName;
1212: if (index < 0) {
1213: prefix = null;
1214: localName = qualifiedName;
1215: } else {
1216: prefix = qualifiedName.substring(0, index);
1217: localName = qualifiedName.substring(index + 1);
1218: }
1219: super .setAttributeNS(namespaceURI, qualifiedName, value);
1220: //String tmpLocalName = this.getLocalName();
1221: String tmpURI = this .getNamespaceURI();
1222: boolean isIDNS = false;
1223: if (tmpURI != null
1224: && (tmpURI.equals(DSIG_NS) || tmpURI.equals(XENC_NS))) {
1225: isIDNS = true;
1226: }
1227: //No need to check for Signature/encryption element
1228: //just check for namespace.
1229: if (localName.equals("Id")) {
1230: if (namespaceURI == null || namespaceURI.equals("")) {
1231: setIdAttribute(localName, true);
1232: } else if (isIDNS || WSU_NS.equals(namespaceURI)) {
1233: setIdAttributeNS(namespaceURI, localName, true);
1234: }
1235: }
1236:
1237: }
1238:
1239: }
|