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);
223 }
224
225 @Override
226 public String getNamespaceURI() {
227 return element.getNamespaceURI();
228 }
229
230 @Override
231 public String getPrefix() {
232 return element.getPrefix();
237 element.setPrefix(prefix);
238 }
239
240 @Override
241 public String getLocalName() {
242 return element.getLocalName();
243 }
244
245 @Override
246 public boolean hasAttributes() {
247 return element.hasAttributes();
248 }
249
250 @Override
251 public String getBaseURI() {
252 return element.getBaseURI();
253 }
254
255 @Override
256 public short compareDocumentPosition(Node other) throws DOMException {
257 return element.compareDocumentPosition(other);
258 }
259
260 @Override
261 public String getTextContent() throws DOMException {
262 return element.getTextContent();
263 }
264
265 @Override
266 public void setTextContent(String textContent) throws DOMException {
267 element.setTextContent(textContent);
268 }
269
270 @Override
271 public boolean isSameNode(Node other) {
272 return element.isSameNode(other);
273 }
274
275 @Override
276 public String lookupPrefix(String namespaceURI) {
277 return element.lookupPrefix(namespaceURI);
278 }
279
280 @Override
281 public boolean isDefaultNamespace(String namespaceURI) {
282 return element.isDefaultNamespace(namespaceURI);
283 }
284
285 @Override
286 public String lookupNamespaceURI(String prefix) {
287 return element.lookupNamespaceURI(prefix);
288 }
289
290 @Override
291 public boolean isEqualNode(Node arg) {
292 return element.isEqualNode(arg);
293 }
294
295 @Override
296 public Object getFeature(String feature, String version) {
297 return element.getFeature(feature, version);
298 }
299
300 @Override
301 public Object setUserData(String key, Object data, UserDataHandler handler) {
302 return element.setUserData(key, data, handler);
303 }
304
305 @Override
306 public Object getUserData(String key) {
307 return element.getUserData(key);
308 }
309
310 public SOAPElement addChildElement(Name name) throws SOAPException {
311 return addElement(name);
312 }
313
314 public SOAPElement addChildElement(QName qname) throws SOAPException {
315 return addElement(qname);
316 }
317
318 public SOAPElement addChildElement(String localName) throws SOAPException {
319 String nsUri = getNamespaceURI("");
320 Name name = (nsUri == null || nsUri.isEmpty())
321 ? NameImpl.createFromUnqualifiedName(localName)
322 : NameImpl.createFromQualifiedName(localName, nsUri);
323 return addChildElement(name);
324 }
325
326 public SOAPElement addChildElement(String localName, String prefix)
327 throws SOAPException {
328 String uri = getNamespaceURI(prefix);
329 if (uri == null) {
330 log.log(
331 Level.SEVERE,
332 "SAAJ0101.impl.parent.of.body.elem.mustbe.body",
333 new String[] { prefix });
334 throw new SOAPExceptionImpl(
335 "Unable to locate namespace for prefix " + prefix);
336 }
337 return addChildElement(localName, prefix, uri);
338 }
339
340 public String getNamespaceURI(String prefix) {
341
342 if ("xmlns".equals(prefix)) {
343 return XMLNS_URI;
344 }
345
346 if("xml".equals(prefix)) {
347 return XML_URI;
348 }
349
350 if ("".equals(prefix)) {
351
352 org.w3c.dom.Node currentAncestor = this;
353 while (currentAncestor != null &&
354 !(currentAncestor instanceof Document)) {
355
356 if (currentAncestor instanceof ElementImpl) {
357 /*
358 QName name = ((ElementImpl) currentAncestor).getElementQName();
359 if (prefix.equals(name.getPrefix())) {
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;
555 }
556
557 protected Element importElement(Element element) {
558 Document document = getOwnerDocument();
559 Document oldDocument = element.getOwnerDocument();
560 if (!oldDocument.equals(document)) {
561 return (Element) document.importNode(element, true);
562 } else {
563 return element;
564 }
565 }
566
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 Node elementNSNode = element.cloneNode(deep);
230 soapDocument.registerChildNodes(elementNSNode, deep);
231 return soapDocument.findIfPresent(soapDocument.getDomNode(elementNSNode));
232 }
233
234 @Override
235 public void normalize() {
236 element.normalize();
237 }
238
239 @Override
240 public boolean isSupported(String feature, String version) {
241 return element.isSupported(feature, version);
242 }
243
244 @Override
245 public String getNamespaceURI() {
246 return element.getNamespaceURI();
247 }
248
249 @Override
250 public String getPrefix() {
251 return element.getPrefix();
256 element.setPrefix(prefix);
257 }
258
259 @Override
260 public String getLocalName() {
261 return element.getLocalName();
262 }
263
264 @Override
265 public boolean hasAttributes() {
266 return element.hasAttributes();
267 }
268
269 @Override
270 public String getBaseURI() {
271 return element.getBaseURI();
272 }
273
274 @Override
275 public short compareDocumentPosition(Node other) throws DOMException {
276 return element.compareDocumentPosition(soapDocument.getDomNode(other));
277 }
278
279 @Override
280 public String getTextContent() throws DOMException {
281 return element.getTextContent();
282 }
283
284 @Override
285 public void setTextContent(String textContent) throws DOMException {
286 element.setTextContent(textContent);
287 }
288
289 @Override
290 public boolean isSameNode(Node other) {
291 return element.isSameNode(soapDocument.getDomNode(other));
292 }
293
294 @Override
295 public String lookupPrefix(String namespaceURI) {
296 return element.lookupPrefix(namespaceURI);
297 }
298
299 @Override
300 public boolean isDefaultNamespace(String namespaceURI) {
301 return element.isDefaultNamespace(namespaceURI);
302 }
303
304 @Override
305 public String lookupNamespaceURI(String prefix) {
306 return element.lookupNamespaceURI(prefix);
307 }
308
309 @Override
310 public boolean isEqualNode(Node arg) {
311 return element.isEqualNode(soapDocument.getDomNode(arg));
312 }
313
314 @Override
315 public Object getFeature(String feature, String version) {
316 return element.getFeature(feature, version);
317 }
318
319 @Override
320 public Object setUserData(String key, Object data, UserDataHandler handler) {
321 return element.setUserData(key, data, handler);
322 }
323
324 @Override
325 public Object getUserData(String key) {
326 return element.getUserData(key);
327 }
328
329 @Override
330 public SOAPElement addChildElement(Name name) throws SOAPException {
331 return addElement(name);
332 }
333
334 @Override
335 public SOAPElement addChildElement(QName qname) throws SOAPException {
336 return addElement(qname);
337 }
338
339 @Override
340 public SOAPElement addChildElement(String localName) throws SOAPException {
341 String nsUri = getNamespaceURI("");
342 Name name = (nsUri == null || nsUri.isEmpty())
343 ? NameImpl.createFromUnqualifiedName(localName)
344 : NameImpl.createFromQualifiedName(localName, nsUri);
345 return addChildElement(name);
346 }
347
348 @Override
349 public SOAPElement addChildElement(String localName, String prefix)
350 throws SOAPException {
351 String uri = getNamespaceURI(prefix);
352 if (uri == null) {
353 log.log(
354 Level.SEVERE,
355 "SAAJ0101.impl.parent.of.body.elem.mustbe.body",
356 new String[] { prefix });
357 throw new SOAPExceptionImpl(
358 "Unable to locate namespace for prefix " + prefix);
359 }
360 return addChildElement(localName, prefix, uri);
361 }
362
363 @Override
364 public String getNamespaceURI(String prefix) {
365
366 if ("xmlns".equals(prefix)) {
367 return XMLNS_URI;
368 }
369
370 if("xml".equals(prefix)) {
371 return XML_URI;
372 }
373
374 if ("".equals(prefix)) {
375
376 org.w3c.dom.Node currentAncestor = this;
377 while (currentAncestor != null &&
378 !(currentAncestor instanceof Document)) {
379
380 if (currentAncestor instanceof ElementImpl) {
381 /*
382 QName name = ((ElementImpl) currentAncestor).getElementQName();
383 if (prefix.equals(name.getPrefix())) {
422 return uri;
423 }*/
424 //String uri = currentAncestor.lookupNamespaceURI(prefix);
425 //if (uri != null) {
426 // return uri;
427 //}
428
429 if (((Element) currentAncestor).hasAttributeNS(
430 XMLNS_URI, prefix)) {
431 return ((Element) currentAncestor).getAttributeNS(
432 XMLNS_URI, prefix);
433 }
434
435 currentAncestor = currentAncestor.getParentNode();
436 }
437 }
438
439 return null;
440 }
441
442 @Override
443 public SOAPElement setElementQName(QName newName) throws SOAPException {
444 ElementImpl copy =
445 new ElementImpl((SOAPDocumentImpl) getOwnerDocument(), newName);
446 return replaceElementWithSOAPElement(this,copy);
447 }
448
449 @Override
450 public QName createQName(String localName, String prefix)
451 throws SOAPException {
452 String uri = getNamespaceURI(prefix);
453 if (uri == null) {
454 log.log(Level.SEVERE, "SAAJ0102.impl.cannot.locate.ns",
455 new Object[] {prefix});
456 throw new SOAPException("Unable to locate namespace for prefix "
457 + prefix);
458 }
459 return new QName(uri, localName, prefix);
460 }
461
462 public String getNamespacePrefix(String uri) {
463
464 NamespaceContextIterator eachNamespace = getNamespaceContextNodes();
465 while (eachNamespace.hasNext()) {
466 org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
467 if (namespaceDecl.getNodeValue().equals(uri)) {
468 String candidatePrefix = namespaceDecl.getLocalName();
469 if ("xmlns".equals(candidatePrefix))
494 org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
495 if (!"".equals(prefix)) {
496 if (namespaceDecl.getNodeName().endsWith(prefix))
497 return namespaceDecl;
498 } else {
499 if (namespaceDecl.getNodeName().equals("xmlns"))
500 return namespaceDecl;
501 }
502 }
503 return null;
504 }
505
506 public NamespaceContextIterator getNamespaceContextNodes() {
507 return getNamespaceContextNodes(true);
508 }
509
510 public NamespaceContextIterator getNamespaceContextNodes(boolean traverseStack) {
511 return new NamespaceContextIterator(this, traverseStack);
512 }
513
514 @Override
515 public SOAPElement addChildElement(
516 String localName,
517 String prefix,
518 String uri)
519 throws SOAPException {
520
521 SOAPElement newElement = createElement(NameImpl.create(localName, prefix, uri));
522 addNode(newElement);
523 return convertToSoapElement(newElement);
524 }
525
526 @Override
527 public SOAPElement addChildElement(SOAPElement element)
528 throws SOAPException {
529
530 // check if Element falls in SOAP 1.1 or 1.2 namespace.
531 String elementURI = element.getElementName().getURI();
532 String localName = element.getLocalName();
533
534 if ((SOAPConstants.URI_NS_SOAP_ENVELOPE).equals(elementURI)
535 || (SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE).equals(elementURI)) {
536
537
538 if ("Envelope".equalsIgnoreCase(localName) ||
539 "Header".equalsIgnoreCase(localName) || "Body".equalsIgnoreCase(localName)) {
540 log.severe("SAAJ0103.impl.cannot.add.fragements");
541 throw new SOAPExceptionImpl(
542 "Cannot add fragments which contain elements "
543 + "which are in the SOAP namespace");
544 }
545
546 if ("Fault".equalsIgnoreCase(localName) && !"Body".equalsIgnoreCase(this.getLocalName())) {
547 log.severe("SAAJ0154.impl.adding.fault.to.nonbody");
548 throw new SOAPExceptionImpl("Cannot add a SOAPFault as a child of " + this.getLocalName());
549 }
550
551 if ("Detail".equalsIgnoreCase(localName) && !"Fault".equalsIgnoreCase(this.getLocalName())) {
552 log.severe("SAAJ0155.impl.adding.detail.nonfault");
553 throw new SOAPExceptionImpl("Cannot add a Detail as a child of " + this.getLocalName());
554 }
555
556 if ("Fault".equalsIgnoreCase(localName)) {
557 // if body is not empty throw an exception
558 if (!elementURI.equals(this.getElementName().getURI())) {
559 log.severe("SAAJ0158.impl.version.mismatch.fault");
560 throw new SOAPExceptionImpl("SOAP Version mismatch encountered when trying to add SOAPFault to SOAPBody");
561 }
562 Iterator<javax.xml.soap.Node> it = this.getChildElements();
563 if (it.hasNext()) {
564 log.severe("SAAJ0156.impl.adding.fault.error");
565 throw new SOAPExceptionImpl("Cannot add SOAPFault as a child of a non-Empty SOAPBody");
566 }
567 }
568 }
569
570 // preserve the encodingStyle attr as it may get lost in the import
571 String encodingStyle = element.getEncodingStyle();
572
573 final Element importedElement = importElement(element);
574 addNode(importedElement);
575
576 final SOAPElement converted = convertToSoapElement(importedElement);
577
578 if (encodingStyle != null)
579 converted.setEncodingStyle(encodingStyle);
580
581 return converted;
582 }
583
584 protected Element importElement(Element element) {
585 Document document = getOwnerDocument();
586 Document oldDocument = element.getOwnerDocument();
587 if (!oldDocument.equals(document)) {
588 return (Element) document.importNode(element, true);
589 } else {
590 return element;
591 }
592 }
593
613 } else {
614 return (SOAPElement)
615 getOwnerDocument().createElement(name.getQualifiedName());
616 }
617 }
618
619 protected SOAPElement createElement(QName name) {
620
621 if (isNamespaceQualified(name)) {
622 return (SOAPElement)
623 getOwnerDocument().createElementNS(
624 name.getNamespaceURI(),
625 getQualifiedName(name));
626 } else {
627 return (SOAPElement)
628 getOwnerDocument().createElement(getQualifiedName(name));
629 }
630 }
631
632 protected void addNode(org.w3c.dom.Node newElement) throws SOAPException {
633 insertBefore(soapDocument.getDomNode(newElement), null);
634
635 if (getOwnerDocument() instanceof DocumentFragment)
636 return;
637
638 if (newElement instanceof ElementImpl) {
639 ElementImpl element = (ElementImpl) newElement;
640 QName elementName = element.getElementQName();
641 if (!"".equals(elementName.getNamespaceURI())) {
642 element.ensureNamespaceIsDeclared(
643 elementName.getPrefix(), elementName.getNamespaceURI());
644 }
645 }
646
647 }
648
649 Element getFirstChildElement() {
650 Node child = getFirstChild();
651 while (child != null) {
652 if (child instanceof Element) {
653 return (Element) soapDocument.find(child);
654 }
655 child = child.getNextSibling();
656 }
657 return null;
658 }
659
660 protected SOAPElement findChild(NameImpl name) {
661 Node eachChild = getFirstChild();
662 while (eachChild != null) {
663 if (eachChild instanceof Element) {
664 SOAPElement eachChildSoap = (SOAPElement) soapDocument.find(eachChild);
665 if (eachChildSoap != null) {
666 if (eachChildSoap.getElementName().equals(name)) {
667 return eachChildSoap;
668 }
669 }
670 }
671 eachChild = eachChild.getNextSibling();
672 }
673 return null;
674 }
675
676 protected SOAPElement findAndConvertChildElement(NameImpl name) {
677 Iterator<Node> eachChild = getChildElementNodes();
678 while (eachChild.hasNext()) {
679 SOAPElement child = (SOAPElement) eachChild.next();
680 if (child.getElementName().equals(name)) {
681 return child;
682 }
683 }
684
685 return null;
686 }
687
688 @Override
689 public SOAPElement addTextNode(String text) throws SOAPException {
690 if (text.startsWith(CDATAImpl.cdataUC)
691 || text.startsWith(CDATAImpl.cdataLC))
692 return addCDATA(
693 text.substring(CDATAImpl.cdataUC.length(), text.length() - 3));
694 return addText(text);
695 }
696
697 protected SOAPElement addCDATA(String text) throws SOAPException {
698 org.w3c.dom.Text cdata =
699 getOwnerDocument().createCDATASection(text);
700 addNode(cdata);
701 return this;
702 }
703
704 protected SOAPElement addText(String text) throws SOAPException {
705 org.w3c.dom.Text textNode =
706 getOwnerDocument().createTextNode(text);
707 addNode(textNode);
708 return this;
709 }
710
711 @Override
712 public SOAPElement addAttribute(Name name, String value)
713 throws SOAPException {
714 addAttributeBare(name, value);
715 if (!"".equals(name.getURI())) {
716 ensureNamespaceIsDeclared(name.getPrefix(), name.getURI());
717 }
718 return this;
719 }
720
721 @Override
722 public SOAPElement addAttribute(QName qname, String value)
723 throws SOAPException {
724 addAttributeBare(qname, value);
725 if (!"".equals(qname.getNamespaceURI())) {
726 ensureNamespaceIsDeclared(qname.getPrefix(), qname.getNamespaceURI());
727 }
728 return this;
729 }
730
731 private void addAttributeBare(Name name, String value) {
732 addAttributeBare(
733 name.getURI(),
734 name.getPrefix(),
735 name.getQualifiedName(),
736 value);
737 }
738 private void addAttributeBare(QName name, String value) {
739 addAttributeBare(
740 name.getNamespaceURI(),
741 name.getPrefix(),
744 }
745
746 private void addAttributeBare(
747 String uri,
748 String prefix,
749 String qualifiedName,
750 String value) {
751
752 uri = uri.length() == 0 ? null : uri;
753 if (qualifiedName.equals("xmlns")) {
754 uri = XMLNS_URI;
755 }
756
757 if (uri == null) {
758 setAttribute(qualifiedName, value);
759 } else {
760 setAttributeNS(uri, qualifiedName, value);
761 }
762 }
763
764 @Override
765 public SOAPElement addNamespaceDeclaration(String prefix, String uri)
766 throws SOAPException {
767 if (prefix.length() > 0) {
768 setAttributeNS(XMLNS_URI, "xmlns:" + prefix, uri);
769 } else {
770 setAttributeNS(XMLNS_URI, "xmlns", uri);
771 }
772 //Fix for CR:6474641
773 //tryToFindEncodingStyleAttributeName();
774 return this;
775 }
776
777 @Override
778 public String getAttributeValue(Name name) {
779 return getAttributeValueFrom(this, name);
780 }
781
782 @Override
783 public String getAttributeValue(QName qname) {
784 return getAttributeValueFrom(
785 this,
786 qname.getNamespaceURI(),
787 qname.getLocalPart(),
788 qname.getPrefix(),
789 getQualifiedName(qname));
790 }
791
792 @Override
793 public Iterator<Name> getAllAttributes() {
794 Iterator<Name> i = getAllAttributesFrom(this);
795 ArrayList<Name> list = new ArrayList<>();
796 while (i.hasNext()) {
797 Name name = i.next();
798 if (!"xmlns".equalsIgnoreCase(name.getPrefix()))
799 list.add(name);
800 }
801 return list.iterator();
802 }
803
804 @Override
805 public Iterator<QName> getAllAttributesAsQNames() {
806 Iterator<Name> i = getAllAttributesFrom(this);
807 ArrayList<QName> list = new ArrayList<>();
808 while (i.hasNext()) {
809 Name name = i.next();
810 if (!"xmlns".equalsIgnoreCase(name.getPrefix())) {
811 list.add(NameImpl.convertToQName(name));
812 }
813 }
814 return list.iterator();
815 }
816
817
818 @Override
819 public Iterator<String> getNamespacePrefixes() {
820 return doGetNamespacePrefixes(false);
821 }
822
823 @Override
824 public Iterator<String> getVisibleNamespacePrefixes() {
825 return doGetNamespacePrefixes(true);
826 }
827
828 protected Iterator<String> doGetNamespacePrefixes(final boolean deep) {
829 return new Iterator<String>() {
830 String next = null;
831 String last = null;
832 NamespaceContextIterator eachNamespace =
833 getNamespaceContextNodes(deep);
834
835 void findNext() {
836 while (next == null && eachNamespace.hasNext()) {
837 String attributeKey =
838 eachNamespace.nextNamespaceAttr().getNodeName();
839 if (attributeKey.startsWith("xmlns:")) {
840 next = attributeKey.substring("xmlns:".length());
841 }
842 }
843 }
844
845 @Override
846 public boolean hasNext() {
847 findNext();
848 return next != null;
849 }
850
851 @Override
852 public String next() {
853 findNext();
854 if (next == null) {
855 throw new NoSuchElementException();
856 }
857
858 last = next;
859 next = null;
860 return last;
861 }
862
863 @Override
864 public void remove() {
865 if (last == null) {
866 throw new IllegalStateException();
867 }
868 eachNamespace.remove();
869 next = null;
870 last = null;
871 }
872 };
873 }
874
875 @Override
876 public Name getElementName() {
877 return NameImpl.convertToName(elementQName);
878 }
879
880 @Override
881 public QName getElementQName() {
882 return elementQName;
883 }
884
885 @Override
886 public boolean removeAttribute(Name name) {
887 return removeAttribute(name.getURI(), name.getLocalName());
888 }
889
890 @Override
891 public boolean removeAttribute(QName name) {
892 return removeAttribute(name.getNamespaceURI(), name.getLocalPart());
893 }
894
895 private boolean removeAttribute(String uri, String localName) {
896 String nonzeroLengthUri =
897 (uri == null || uri.length() == 0) ? null : uri;
898 org.w3c.dom.Attr attribute =
899 getAttributeNodeNS(nonzeroLengthUri, localName);
900 if (attribute == null) {
901 return false;
902 }
903 removeAttributeNode(attribute);
904 return true;
905 }
906
907 @Override
908 public boolean removeNamespaceDeclaration(String prefix) {
909 org.w3c.dom.Attr declaration = getNamespaceAttr(prefix);
910 if (declaration == null) {
911 return false;
912 }
913 try {
914 removeAttributeNode(declaration);
915 } catch (DOMException de) {
916 // ignore
917 }
918 return true;
919 }
920
921 @Override
922 public Iterator<javax.xml.soap.Node> getChildElements() {
923 return getChildElementsFrom(this);
924 }
925
926 protected SOAPElement convertToSoapElement(Element element) {
927 final Node soapNode = soapDocument.findIfPresent(element);
928 if (soapNode instanceof SOAPElement) {
929 return (SOAPElement) soapNode;
930 } else {
931 return replaceElementWithSOAPElement(
932 element,
933 (ElementImpl) createElement(NameImpl.copyElementName(element)));
934 }
935 }
936
937 protected TextImpl convertToSoapText(CharacterData characterData) {
938 final Node soapNode = getSoapDocument().findIfPresent(characterData);
939 if (soapNode instanceof TextImpl) {
940 return (TextImpl) soapNode;
941 } else {
942 TextImpl t = null;
943 switch (characterData.getNodeType()) {
944 case CDATA_SECTION_NODE:
945 t = new CDATAImpl(getSoapDocument(), characterData.getData());
946 break;
947 case COMMENT_NODE:
948 t = new SOAPCommentImpl(getSoapDocument(), characterData.getData());
949 break;
950 case TEXT_NODE:
951 t = new SOAPTextImpl(getSoapDocument(), characterData.getData());
952 break;
953 }
954 Node parent = getSoapDocument().find(characterData.getParentNode());
955 if (parent != null) {
956 parent.replaceChild(t, characterData);
957 } // XXX else throw an exception?
958
959 return t;
960
961 // return replaceElementWithSOAPElement(
962 // element,
963 // (ElementImpl) createElement(NameImpl.copyElementName(element)));
964 }
965 }
966
967 protected SOAPElement replaceElementWithSOAPElement(
968 Element element,
969 ElementImpl copy) {
970
971 Iterator<Name> eachAttribute = getAllAttributesFrom(element);
972 while (eachAttribute.hasNext()) {
973 Name name = eachAttribute.next();
974 copy.addAttributeBare(name, getAttributeValueFrom(element, name));
975 }
976
977 Iterator<Node> eachChild = getChildElementsFromDOM(element);
978 while (eachChild.hasNext()) {
979 Node nextChild = eachChild.next();
980 copy.insertBefore(nextChild, null);
981 }
982
983 Node parent = soapDocument.find(element.getParentNode());
984 if (parent != null) {
985 parent.replaceChild(copy, element);
986 } // XXX else throw an exception?
987
988 return copy;
989 }
990
991 private Iterator<Node> getChildElementsFromDOM(final Element el) {
992 return new Iterator<Node>() {
993 Node next = el.getFirstChild();
994 Node nextNext = null;
995 Node last = null;
996 Node soapElement = getSoapDocument().findIfPresent(el);
997
998 @Override
999 public boolean hasNext() {
1000 if (next != null) {
1001 return true;
1002 }
1003 if (nextNext != null) {
1004 next = nextNext;
1005 }
1006
1007 return next != null;
1008 }
1009
1010 public Node next() {
1011 if (hasNext()) {
1012 last = next;
1013 next = null;
1014
1015 if ((soapElement instanceof ElementImpl)
1016 && (last instanceof Element)) {
1017 last =
1018 ((ElementImpl) soapElement).convertToSoapElement(
1019 (Element) last);
1020 } else if ((soapElement instanceof ElementImpl) && (last instanceof CharacterData)) {
1021 last = ((ElementImpl) soapElement).convertToSoapText(
1022 (CharacterData) last);
1023 }
1024
1025 nextNext = last.getNextSibling();
1026 return last;
1027 }
1028 throw new NoSuchElementException();
1029 }
1030
1031 @Override
1032 public void remove() {
1033 if (last == null) {
1034 throw new IllegalStateException();
1035 }
1036 Node target = last;
1037 last = null;
1038 el.removeChild(target);
1039 }
1040 };
1041 }
1042
1043 protected Iterator<Node> getChildElementNodes() {
1044 return new Iterator<Node>() {
1045 Iterator<javax.xml.soap.Node> eachNode = getChildElements();
1046 Node next = null;
1047 Node last = null;
1048
1049 @Override
1050 public boolean hasNext() {
1051 if (next == null) {
1052 while (eachNode.hasNext()) {
1053 Node node = eachNode.next();
1054 if (node instanceof Element) {
1055 next = soapDocument.findIfPresent(node);
1056 break;
1057 }
1058 }
1059 }
1060 return next != null;
1061 }
1062
1063 @Override
1064 public javax.xml.soap.Node next() {
1065 if (hasNext()) {
1066 last = next;
1067 next = null;
1068 return (javax.xml.soap.Node) last;
1069 }
1070 throw new NoSuchElementException();
1071 }
1072
1073 @Override
1074 public void remove() {
1075 if (last == null) {
1076 throw new IllegalStateException();
1077 }
1078 Node target = last;
1079 last = null;
1080 removeChild(target);
1081 }
1082 };
1083 }
1084
1085 @Override
1086 public Iterator<javax.xml.soap.Node> getChildElements(final Name name) {
1087 return getChildElements(name.getURI(), name.getLocalName());
1088 }
1089
1090 @Override
1091 public Iterator<javax.xml.soap.Node> getChildElements(final QName qname) {
1092 return getChildElements(qname.getNamespaceURI(), qname.getLocalPart());
1093 }
1094
1095 private Iterator<javax.xml.soap.Node> getChildElements(final String nameUri, final String nameLocal) {
1096 return new Iterator<javax.xml.soap.Node>() {
1097 Iterator<Node> eachElement = getChildElementNodes();
1098 Node next = null;
1099 Node last = null;
1100
1101 @Override
1102 public boolean hasNext() {
1103 if (next == null) {
1104 while (eachElement.hasNext()) {
1105 Node element = eachElement.next();
1106 String elementUri = element.getNamespaceURI();
1107 elementUri = elementUri == null ? "" : elementUri;
1108 String elementName = element.getLocalName();
1109 if (elementUri.equals(nameUri)
1110 && elementName.equals(nameLocal)) {
1111 next = element;
1112 break;
1113 }
1114 }
1115 }
1116 return next != null;
1117 }
1118
1119 @Override
1120 public javax.xml.soap.Node next() {
1121 if (!hasNext()) {
1122 throw new NoSuchElementException();
1123 }
1124 last = next;
1125 next = null;
1126 return (javax.xml.soap.Node) last;
1127 }
1128
1129 @Override
1130 public void remove() {
1131 if (last == null) {
1132 throw new IllegalStateException();
1133 }
1134 Node target = last;
1135 last = null;
1136 removeChild(target);
1137 }
1138 };
1139 }
1140
1141 @Override
1142 public void removeContents() {
1143 Node currentChild = getFirstChild();
1144
1145 while (currentChild != null) {
1146 Node temp = currentChild.getNextSibling();
1147 if (currentChild instanceof javax.xml.soap.Node) {
1148 ((javax.xml.soap.Node) currentChild).detachNode();
1149 } else {
1150 Node parent = currentChild.getParentNode();
1151 if (parent != null) {
1152 parent.removeChild(currentChild);
1153 }
1154
1155 }
1156 currentChild = temp;
1157 }
1158 }
1159
1160 @Override
1161 public void setEncodingStyle(String encodingStyle) throws SOAPException {
1162 if (!"".equals(encodingStyle)) {
1163 try {
1164 new URI(encodingStyle);
1165 } catch (URISyntaxException m) {
1166 log.log(
1167 Level.SEVERE,
1168 "SAAJ0105.impl.encoding.style.mustbe.valid.URI",
1169 new String[] { encodingStyle });
1170 throw new IllegalArgumentException(
1171 "Encoding style (" + encodingStyle + ") should be a valid URI");
1172 }
1173 }
1174 encodingStyleAttribute.setValue(encodingStyle);
1175 tryToFindEncodingStyleAttributeName();
1176 }
1177
1178 @Override
1179 public String getEncodingStyle() {
1180 String encodingStyle = encodingStyleAttribute.getValue();
1181 if (encodingStyle != null)
1182 return encodingStyle;
1183 String soapNamespace = getSOAPNamespace();
1184 if (soapNamespace != null) {
1185 Attr attr = getAttributeNodeNS(soapNamespace, "encodingStyle");
1186 if (attr != null) {
1187 encodingStyle = attr.getValue();
1188 try {
1189 setEncodingStyle(encodingStyle);
1190 } catch (SOAPException se) {
1191 // has to be ignored
1192 }
1193 return encodingStyle;
1194 }
1195 }
1196 return null;
1197 }
1198
1199 // Node methods
1200 @Override
1201 public String getValue() {
1202 javax.xml.soap.Node valueNode = getValueNode();
1203 return valueNode == null ? null : valueNode.getValue();
1204 }
1205
1206 @Override
1207 public void setValue(String value) {
1208 Node valueNode = getValueNodeStrict();
1209 if (valueNode != null) {
1210 valueNode.setNodeValue(value);
1211 } else {
1212 try {
1213 addTextNode(value);
1214 } catch (SOAPException e) {
1215 throw new RuntimeException(e.getMessage());
1216 }
1217 }
1218 }
1219
1220 protected Node getValueNodeStrict() {
1221 Node node = getFirstChild();
1222 if (node != null) {
1223 if (node.getNextSibling() == null
1224 && node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
1225 return node;
1226 } else {
1227 log.severe("SAAJ0107.impl.elem.child.not.single.text");
1228 throw new IllegalStateException();
1229 }
1230 }
1231
1232 return null;
1233 }
1234
1235 protected javax.xml.soap.Node getValueNode() {
1236 Iterator<javax.xml.soap.Node> i = getChildElements();
1237 while (i.hasNext()) {
1238 Node n = i.next();
1239 if (n.getNodeType() == org.w3c.dom.Node.TEXT_NODE ||
1240 n.getNodeType() == org.w3c.dom.Node.CDATA_SECTION_NODE) {
1241 // TODO: Hack to fix text node split into multiple lines.
1242 normalize();
1243 // Should remove the normalization step when this gets fixed in
1244 // DOM/Xerces.
1245 return soapDocument.find(n);
1246 }
1247 }
1248 return null;
1249 }
1250
1251 @Override
1252 public void setParentElement(SOAPElement element) throws SOAPException {
1253 if (element == null) {
1254 log.severe("SAAJ0106.impl.no.null.to.parent.elem");
1255 throw new SOAPException("Cannot pass NULL to setParentElement");
1256 }
1257 element.addChildElement(this);
1258 findEncodingStyleAttributeName();
1259 }
1260
1261 protected void findEncodingStyleAttributeName() throws SOAPException {
1262 String soapNamespace = getSOAPNamespace();
1263 if (soapNamespace != null) {
1264 String soapNamespacePrefix = getNamespacePrefix(soapNamespace);
1265 if (soapNamespacePrefix != null) {
1266 setEncodingStyleNamespace(soapNamespace, soapNamespacePrefix);
1267 }
1268 }
1269 }
1270
1271 protected void setEncodingStyleNamespace(
1272 String soapNamespace,
1273 String soapNamespacePrefix)
1274 throws SOAPException {
1275 Name encodingStyleAttributeName =
1276 NameImpl.create(
1277 "encodingStyle",
1278 soapNamespacePrefix,
1279 soapNamespace);
1280 encodingStyleAttribute.setName(encodingStyleAttributeName);
1281 }
1282
1283 @Override
1284 public SOAPElement getParentElement() {
1285 Node parentNode = getParentNode();
1286 if (parentNode instanceof SOAPDocument) {
1287 return null;
1288 }
1289 return (SOAPElement) soapDocument.find(parentNode);
1290 }
1291
1292 protected String getSOAPNamespace() {
1293 String soapNamespace = null;
1294
1295 SOAPElement antecedent = this;
1296 while (antecedent != null) {
1297 Name antecedentName = antecedent.getElementName();
1298 String antecedentNamespace = antecedentName.getURI();
1299
1300 if (NameImpl.SOAP11_NAMESPACE.equals(antecedentNamespace)
1301 || NameImpl.SOAP12_NAMESPACE.equals(antecedentNamespace)) {
1302
1303 soapNamespace = antecedentNamespace;
1304 break;
1305 }
1306
1307 antecedent = antecedent.getParentElement();
1308 }
1309
1310 return soapNamespace;
1311 }
1312
1313 @Override
1314 public void detachNode() {
1315 Node parent = getParentNode();
1316 if (parent != null) {
1317 parent.removeChild(element);
1318 }
1319 encodingStyleAttribute.clearNameAndValue();
1320 // Fix for CR: 6474641
1321 //tryToFindEncodingStyleAttributeName();
1322 }
1323
1324 public void tryToFindEncodingStyleAttributeName() {
1325 try {
1326 findEncodingStyleAttributeName();
1327 } catch (SOAPException e) { /*okay to fail*/
1328 }
1329 }
1330
1331 @Override
1332 public void recycleNode() {
1333 detachNode();
1334 // TBD
1335 // - add this to the factory so subsequent
1336 // creations can reuse this object.
1337 }
1338
1339 class AttributeManager {
1340 Name attributeName = null;
1341 String attributeValue = null;
1342
1343 public void setName(Name newName) throws SOAPException {
1344 clearAttribute();
1345 attributeName = newName;
1346 reconcileAttribute();
1347 }
1348 public void clearName() {
1349 clearAttribute();
1350 attributeName = null;
1351 }
1388 new NamespaceContextIterator(element);
1389 while (eachNamespace.hasNext()) {
1390 org.w3c.dom.Attr namespaceDecl = eachNamespace.nextNamespaceAttr();
1391 String declaredPrefix =
1392 NameImpl.getLocalNameFromTagName(namespaceDecl.getNodeName());
1393 if (declaredPrefix.equals(prefix)) {
1394 return namespaceDecl;
1395 }
1396 }
1397 return null;
1398 }
1399
1400 protected static Iterator<Name> getAllAttributesFrom(final Element element) {
1401 final NamedNodeMap attributes = element.getAttributes();
1402
1403 return new Iterator<Name>() {
1404 int attributesLength = attributes.getLength();
1405 int attributeIndex = 0;
1406 String currentName;
1407
1408 @Override
1409 public boolean hasNext() {
1410 return attributeIndex < attributesLength;
1411 }
1412
1413 @Override
1414 public Name next() {
1415 if (!hasNext()) {
1416 throw new NoSuchElementException();
1417 }
1418 Node current = attributes.item(attributeIndex++);
1419 currentName = current.getNodeName();
1420
1421 String prefix = NameImpl.getPrefixFromTagName(currentName);
1422 if (prefix.length() == 0) {
1423 return NameImpl.createFromUnqualifiedName(currentName);
1424 } else {
1425 Name attributeName =
1426 NameImpl.createFromQualifiedName(
1427 currentName,
1428 current.getNamespaceURI());
1429 return attributeName;
1430 }
1431 }
1432
1433 @Override
1434 public void remove() {
1435 if (currentName == null) {
1436 throw new IllegalStateException();
1437 }
1438 attributes.removeNamedItem(currentName);
1439 }
1440 };
1441 }
1442
1443 protected static String getAttributeValueFrom(Element element, Name name) {
1444 return getAttributeValueFrom(
1445 element,
1446 name.getURI(),
1447 name.getLocalName(),
1448 name.getPrefix(),
1449 name.getQualifiedName());
1450 }
1451
1452 private static String getAttributeValueFrom(
1453 Element element,
1462 boolean mustUseGetAttributeNodeNS = (nonzeroLengthUri != null);
1463
1464 if (mustUseGetAttributeNodeNS) {
1465
1466 if (!element.hasAttributeNS(uri, localName)) {
1467 return null;
1468 }
1469
1470 String attrValue =
1471 element.getAttributeNS(nonzeroLengthUri, localName);
1472
1473 return attrValue;
1474 }
1475
1476 Attr attribute = null;
1477 attribute = element.getAttributeNode(qualifiedName);
1478
1479 return attribute == null ? null : attribute.getValue();
1480 }
1481
1482 protected Iterator<javax.xml.soap.Node> getChildElementsFrom(final Element element) {
1483 return new Iterator<javax.xml.soap.Node>() {
1484 Node next = element.getFirstChild();
1485 Node nextNext = null;
1486 Node last = null;
1487 Node soapElement = soapDocument.findIfPresent(element);
1488
1489 @Override
1490 public boolean hasNext() {
1491 if (next != null) {
1492 return true;
1493 }
1494 if (nextNext != null) {
1495 next = nextNext;
1496 }
1497
1498 return next != null;
1499 }
1500
1501 @Override
1502 public javax.xml.soap.Node next() {
1503 if (hasNext()) {
1504 last = next;
1505 next = null;
1506
1507 if ((soapElement instanceof ElementImpl)
1508 && (last instanceof Element)) {
1509 last =
1510 ((ElementImpl) soapElement).convertToSoapElement(
1511 (Element) last);
1512 }
1513
1514 nextNext = last.getNextSibling();
1515 return (javax.xml.soap.Node) soapDocument.findIfPresent(last);
1516 }
1517 throw new NoSuchElementException();
1518 }
1519
1520 @Override
1521 public void remove() {
1522 if (last == null) {
1523 throw new IllegalStateException();
1524 }
1525 Node target = last;
1526 last = null;
1527 element.removeChild(target);
1528 }
1529 };
1530 }
1531
1532 public static String getQualifiedName(QName name) {
1533 String prefix = name.getPrefix();
1534 String localName = name.getLocalPart();
1535 String qualifiedName = null;
1536
1537 if (prefix != null && prefix.length() > 0) {
1538 qualifiedName = prefix + ":" + localName;
1539 } else {
1540 qualifiedName = localName;
1562 }
1563
1564 int index = qualifiedName.indexOf(':');
1565 if (index < 0)
1566 return "";
1567 else
1568 return qualifiedName.substring(0, index);
1569 }
1570
1571 protected boolean isNamespaceQualified(Name name) {
1572 return !"".equals(name.getURI());
1573 }
1574
1575 protected boolean isNamespaceQualified(QName name) {
1576 return !"".equals(name.getNamespaceURI());
1577 }
1578
1579 //TODO: This is a temporary SAAJ workaround for optimizing XWS
1580 // should be removed once the corresponding JAXP bug is fixed
1581 // It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe)
1582 @Override
1583 public void setAttributeNS(
1584 String namespaceURI,String qualifiedName, String value) {
1585 int index = qualifiedName.indexOf(':');
1586 String localName;
1587 if (index < 0)
1588 localName = qualifiedName;
1589 else
1590 localName = qualifiedName.substring(index + 1);
1591
1592 // Workaround for bug 6467808 - This needs to be fixed in JAXP
1593
1594 // Rolling back this fix, this is a wrong fix, infact its causing other regressions in JAXWS tck and
1595 // other tests, because of this change the namespace declarations on soapenv:Fault element are never
1596 // picked up. The fix for bug 6467808 should be in JAXP.
1597 // if(elementQName.getLocalPart().equals("Fault") &&
1598 // (SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE.equals(value) ||
1599 // SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE.equals(value)))
1600 // return;
1601
1602 element.setAttributeNS(namespaceURI,qualifiedName,value);
1618
1619 }
1620
1621 @Override
1622 public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
1623 element.removeAttributeNS(namespaceURI, localName);
1624 }
1625
1626 @Override
1627 public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException {
1628 return element.getAttributeNodeNS(namespaceURI, localName);
1629 }
1630
1631 @Override
1632 public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
1633 return element.setAttributeNodeNS(newAttr);
1634 }
1635
1636 @Override
1637 public NodeList getElementsByTagNameNS(String namespaceURI, String localName) throws DOMException {
1638 return new NodeListImpl(soapDocument, element.getElementsByTagNameNS(namespaceURI, localName));
1639 }
1640
1641 @Override
1642 public boolean hasAttribute(String name) {
1643 return element.hasAttribute(name);
1644 }
1645
1646 @Override
1647 public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException {
1648 return element.hasAttributeNS(namespaceURI, localName);
1649 }
1650
1651 @Override
1652 public TypeInfo getSchemaTypeInfo() {
1653 return element.getSchemaTypeInfo();
1654 }
1655
1656 @Override
1657 public void setIdAttribute(String name, boolean isId) throws DOMException {
1658 element.setIdAttribute(name, isId);
1673 return element.getNodeName();
1674 }
1675
1676 @Override
1677 public String getNodeValue() throws DOMException {
1678 return element.getNodeValue();
1679 }
1680
1681 @Override
1682 public void setNodeValue(String nodeValue) throws DOMException {
1683 element.setNodeValue(nodeValue);
1684 }
1685
1686 @Override
1687 public short getNodeType() {
1688 return element.getNodeType();
1689 }
1690
1691 @Override
1692 public Node getParentNode() {
1693 return soapDocument.find(element.getParentNode());
1694 }
1695
1696 @Override
1697 public NodeList getChildNodes() {
1698 return new NodeListImpl(soapDocument, element.getChildNodes());
1699 }
1700
1701 @Override
1702 public Node getFirstChild() {
1703 return soapDocument.findIfPresent(element.getFirstChild());
1704 }
1705
1706 @Override
1707 public Node getLastChild() {
1708 return soapDocument.findIfPresent(element.getLastChild());
1709 }
1710
1711 @Override
1712 public Node getPreviousSibling() {
1713 return soapDocument.findIfPresent(element.getPreviousSibling());
1714 }
1715
1716 @Override
1717 public Node getNextSibling() {
1718 return soapDocument.findIfPresent(element.getNextSibling());
1719 }
1720
1721 @Override
1722 public NamedNodeMap getAttributes() {
1723 return new NamedNodeMapImpl(element.getAttributes(), soapDocument);
1724 }
1725
1726 public Element getDomElement() {
1727 return element;
1728 }
1729
1730 public SOAPDocumentImpl getSoapDocument() {
1731 return soapDocument;
1732 }
1733 }
|