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

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

mercurial