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