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

changeset 1
0961a4a21176
child 45
31822b475baa
equal deleted inserted replaced
-1:000000000000 1:0961a4a21176
1 /*
2 * $Id: SOAPPartImpl.java,v 1.1.1.1 2006/01/27 13:10:55 kumarjayanti Exp $
3 * $Revision: 1.1.1.1 $
4 * $Date: 2006/01/27 13:10:55 $
5 */
6
7 /*
8 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Sun designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Sun in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
28 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * have any questions.
30 */
31 package com.sun.xml.internal.messaging.saaj.soap;
32
33 import java.io.*;
34 import java.util.Iterator;
35 import java.util.logging.Logger;
36 import java.util.logging.Level;
37
38 import javax.activation.DataHandler;
39 import javax.activation.DataSource;
40 import javax.xml.soap.*;
41 import javax.xml.transform.Source;
42 import javax.xml.transform.stream.StreamSource;
43
44 import org.w3c.dom.*;
45
46 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeBodyPart;
47
48 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
49 import com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl;
50 import com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl;
51 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
52 import com.sun.xml.internal.messaging.saaj.util.*;
53 import javax.xml.transform.sax.SAXSource;
54
55 /**
56 * SOAPPartImpl is the first attachment. This contains the XML/SOAP document.
57 *
58 * @author Anil Vijendran (anil@sun.com)
59 */
60 public abstract class SOAPPartImpl extends SOAPPart implements SOAPDocument {
61 protected static Logger log =
62 Logger.getLogger(LogDomainConstants.SOAP_DOMAIN,
63 "com.sun.xml.internal.messaging.saaj.soap.LocalStrings");
64
65 protected MimeHeaders headers;
66 protected Envelope envelope;
67 protected Source source;
68 protected SOAPDocumentImpl document;
69
70 //flag to indicate if a setContent happened.
71 private boolean sourceWasSet = false;
72
73 // Records whether the input source had an xml decl or not.
74 protected boolean omitXmlDecl = true;
75
76 // Records the charset encoding of the input stream source if provided.
77 protected String sourceCharsetEncoding = null;
78
79 /**
80 * Reference to containing message (may be null)
81 */
82 protected MessageImpl message;
83
84 protected SOAPPartImpl() {
85 this(null);
86 }
87
88 protected SOAPPartImpl(MessageImpl message) {
89 document = new SOAPDocumentImpl(this);
90 headers = new MimeHeaders();
91 this.message = message;
92 headers.setHeader("Content-Type", getContentType());
93 }
94
95 protected abstract String getContentType();
96 protected abstract Envelope createEnvelopeFromSource()
97 throws SOAPException;
98 protected abstract Envelope createEmptyEnvelope(String prefix)
99 throws SOAPException;
100 protected abstract SOAPPartImpl duplicateType();
101
102 protected String getContentTypeString() {
103 return getContentType();
104 }
105
106 public boolean isFastInfoset() {
107 return (message != null) ? message.isFastInfoset() : false;
108 }
109
110 public SOAPEnvelope getEnvelope() throws SOAPException {
111
112 // If there is no SOAP envelope already created, then create
113 // one from a source if one exists. If there is a newer source
114 // then use that source.
115
116 if (sourceWasSet)
117 sourceWasSet = false;
118
119 lookForEnvelope();
120 if (envelope != null) {
121 if (source != null) { // there's a newer source, use it
122 document.removeChild(envelope);
123 envelope = createEnvelopeFromSource();
124 }
125 } else if (source != null) {
126 envelope = createEnvelopeFromSource();
127 } else {
128 envelope = createEmptyEnvelope(null);
129 document.insertBefore(envelope, null);
130 }
131 return envelope;
132 }
133
134 protected void lookForEnvelope() throws SOAPException {
135 Element envelopeChildElement = document.doGetDocumentElement();
136 if (envelopeChildElement == null || envelopeChildElement instanceof Envelope) {
137 envelope = (EnvelopeImpl) envelopeChildElement;
138 } else if (!(envelopeChildElement instanceof ElementImpl)) {
139 log.severe("SAAJ0512.soap.incorrect.factory.used");
140 throw new SOAPExceptionImpl("Unable to create envelope: incorrect factory used during tree construction");
141 } else {
142 ElementImpl soapElement = (ElementImpl) envelopeChildElement;
143 if (soapElement.getLocalName().equalsIgnoreCase("Envelope")) {
144 String prefix = soapElement.getPrefix();
145 String uri = (prefix == null) ? soapElement.getNamespaceURI() : soapElement.getNamespaceURI(prefix);
146 if(!uri.equals(NameImpl.SOAP11_NAMESPACE) && !uri.equals(NameImpl.SOAP12_NAMESPACE)) {
147 log.severe("SAAJ0513.soap.unknown.ns");
148 throw new SOAPVersionMismatchException("Unable to create envelope from given source because the namespace was not recognized");
149 }
150 } else {
151 log.severe("SAAJ0514.soap.root.elem.not.named.envelope");
152 throw new SOAPExceptionImpl(
153 "Unable to create envelope from given source because the root element is not named \"Envelope\"");
154 }
155 }
156 }
157
158 public void removeAllMimeHeaders() {
159 headers.removeAllHeaders();
160 }
161
162 public void removeMimeHeader(String header) {
163 headers.removeHeader(header);
164 }
165
166 public String[] getMimeHeader(String name) {
167 return headers.getHeader(name);
168 }
169
170 public void setMimeHeader(String name, String value) {
171 headers.setHeader(name, value);
172 }
173
174 public void addMimeHeader(String name, String value) {
175 headers.addHeader(name, value);
176 }
177
178 public Iterator getAllMimeHeaders() {
179 return headers.getAllHeaders();
180 }
181
182 public Iterator getMatchingMimeHeaders(String[] names) {
183 return headers.getMatchingHeaders(names);
184 }
185
186 public Iterator getNonMatchingMimeHeaders(String[] names) {
187 return headers.getNonMatchingHeaders(names);
188 }
189
190 public Source getContent() throws SOAPException {
191 if (source != null) {
192 InputStream bis = null;
193 if (source instanceof JAXMStreamSource) {
194 StreamSource streamSource = (StreamSource)source;
195 bis = streamSource.getInputStream();
196 } else if (FastInfosetReflection.isFastInfosetSource(source)) {
197 // FastInfosetSource inherits from SAXSource
198 SAXSource saxSource = (SAXSource)source;
199 bis = saxSource.getInputSource().getByteStream();
200 }
201
202 if (bis != null) {
203 try {
204 bis.reset();
205 } catch (IOException e) {
206 /* This exception will never be thrown.
207 *
208 * The setContent method will modify the source
209 * if StreamSource to JAXMStreamSource, that uses
210 * a ByteInputStream, and for a FastInfosetSource will
211 * replace the InputStream with a ByteInputStream.
212 */
213 }
214 }
215 return source;
216 }
217
218 return ((Envelope) getEnvelope()).getContent();
219 }
220
221 public void setContent(Source source) throws SOAPException {
222 try {
223 if (source instanceof StreamSource) {
224 InputStream is = ((StreamSource) source).getInputStream();
225 Reader rdr = ((StreamSource) source).getReader();
226
227 if (is != null) {
228 this.source = new JAXMStreamSource(is);
229 } else if (rdr != null) {
230 this.source = new JAXMStreamSource(rdr);
231 } else {
232 log.severe("SAAJ0544.soap.no.valid.reader.for.src");
233 throw new SOAPExceptionImpl("Source does not have a valid Reader or InputStream");
234 }
235 }
236 else if (FastInfosetReflection.isFastInfosetSource(source)) {
237 // InputStream is = source.getInputStream()
238 InputStream is = FastInfosetReflection.FastInfosetSource_getInputStream(source);
239
240 /*
241 * Underlying stream must be ByteInputStream for getContentAsStream(). We pay the
242 * cost of copying the underlying bytes here to avoid multiple copies every time
243 * getBytes() is called on a ByteInputStream.
244 */
245 if (!(is instanceof ByteInputStream)) {
246 ByteOutputStream bout = new ByteOutputStream();
247 bout.write(is);
248
249 // source.setInputStream(new ByteInputStream(...))
250 FastInfosetReflection.FastInfosetSource_setInputStream(
251 source, bout.newInputStream());
252 }
253 this.source = source;
254 }
255 else {
256 this.source = source;
257 }
258 sourceWasSet = true;
259 }
260 catch (Exception ex) {
261 ex.printStackTrace();
262
263 log.severe("SAAJ0545.soap.cannot.set.src.for.part");
264 throw new SOAPExceptionImpl(
265 "Error setting the source for SOAPPart: " + ex.getMessage());
266 }
267 }
268
269 public ByteInputStream getContentAsStream() throws IOException {
270 if (source != null) {
271 InputStream is = null;
272
273 // Allow message to be transcode if so requested
274 if (source instanceof StreamSource && !isFastInfoset()) {
275 is = ((StreamSource) source).getInputStream();
276 }
277 else if (FastInfosetReflection.isFastInfosetSource(source) &&
278 isFastInfoset())
279 {
280 try {
281 // InputStream is = source.getInputStream()
282 is = FastInfosetReflection.FastInfosetSource_getInputStream(source);
283 }
284 catch (Exception e) {
285 throw new IOException(e.toString());
286 }
287 }
288
289 if (is != null) {
290 if (!(is instanceof ByteInputStream)) {
291 log.severe("SAAJ0546.soap.stream.incorrect.type");
292 throw new IOException("Internal error: stream not of the right type");
293 }
294 return (ByteInputStream) is;
295 }
296 // need to do something here for reader...
297 // for now we'll see if we can fallback...
298 }
299
300 ByteOutputStream b = new ByteOutputStream();
301
302 Envelope env = null;
303
304 try {
305 env = (Envelope) getEnvelope();
306 env.output(b, isFastInfoset());
307 }
308 catch (SOAPException soapException) {
309 log.severe("SAAJ0547.soap.cannot.externalize");
310 throw new SOAPIOException(
311 "SOAP exception while trying to externalize: ",
312 soapException);
313 }
314
315 return b.newInputStream();
316 }
317
318 MimeBodyPart getMimePart() throws SOAPException {
319 try {
320 MimeBodyPart headerEnvelope = new MimeBodyPart();
321
322 headerEnvelope.setDataHandler(getDataHandler());
323 AttachmentPartImpl.copyMimeHeaders(headers, headerEnvelope);
324
325 return headerEnvelope;
326 } catch (SOAPException ex) {
327 throw ex;
328 } catch (Exception ex) {
329 log.severe("SAAJ0548.soap.cannot.externalize.hdr");
330 throw new SOAPExceptionImpl("Unable to externalize header", ex);
331 }
332 }
333
334 MimeHeaders getMimeHeaders() {
335 return headers;
336 }
337
338 DataHandler getDataHandler() {
339 DataSource ds = new DataSource() {
340 public OutputStream getOutputStream() throws IOException {
341 throw new IOException("Illegal Operation");
342 }
343
344 public String getContentType() {
345 return getContentTypeString();
346 }
347
348 public String getName() {
349 return getContentId();
350 }
351
352 public InputStream getInputStream() throws IOException {
353 return getContentAsStream();
354 }
355 };
356 return new DataHandler(ds);
357 }
358
359 public SOAPDocumentImpl getDocument() {
360 handleNewSource();
361 return document;
362 }
363
364 public SOAPPartImpl getSOAPPart() {
365 return this;
366 }
367
368 public DocumentType getDoctype() {
369 return document.getDoctype();
370 }
371
372 // Forward all of these calls to the document to ensure that they work the
373 // same way whether they are called from here or directly from the document.
374 // If the document needs any help from this SOAPPart then
375 // Make it use a call-back as in doGetDocumentElement() below
376 public DOMImplementation getImplementation() {
377 return document.getImplementation();
378 }
379
380 public Element getDocumentElement() {
381 // If there is no SOAP envelope already created, then create
382 // one from a source if one exists. If there is a newer source
383 // then use that source.
384 try {
385 getEnvelope();
386 } catch (SOAPException e) {
387 }
388 return document.getDocumentElement();
389 }
390
391 protected void doGetDocumentElement() {
392 handleNewSource();
393 try {
394 lookForEnvelope();
395 } catch (SOAPException e) {
396 }
397 }
398
399 public Element createElement(String tagName) throws DOMException {
400 return document.createElement(tagName);
401 }
402
403 public DocumentFragment createDocumentFragment() {
404 return document.createDocumentFragment();
405 }
406
407 public org.w3c.dom.Text createTextNode(String data) {
408 return document.createTextNode(data);
409 }
410
411 public Comment createComment(String data) {
412 return document.createComment(data);
413 }
414
415 public CDATASection createCDATASection(String data) throws DOMException {
416 return document.createCDATASection(data);
417 }
418
419 public ProcessingInstruction createProcessingInstruction(
420 String target,
421 String data)
422 throws DOMException {
423 return document.createProcessingInstruction(target, data);
424 }
425
426 public Attr createAttribute(String name) throws DOMException {
427 return document.createAttribute(name);
428 }
429
430 public EntityReference createEntityReference(String name)
431 throws DOMException {
432 return document.createEntityReference(name);
433 }
434
435 public NodeList getElementsByTagName(String tagname) {
436 handleNewSource();
437 return document.getElementsByTagName(tagname);
438 }
439
440 public org.w3c.dom.Node importNode(
441 org.w3c.dom.Node importedNode,
442 boolean deep)
443 throws DOMException {
444 handleNewSource();
445 return document.importNode(importedNode, deep);
446 }
447
448 public Element createElementNS(String namespaceURI, String qualifiedName)
449 throws DOMException {
450 return document.createElementNS(namespaceURI, qualifiedName);
451 }
452
453 public Attr createAttributeNS(String namespaceURI, String qualifiedName)
454 throws DOMException {
455 return document.createAttributeNS(namespaceURI, qualifiedName);
456 }
457
458 public NodeList getElementsByTagNameNS(
459 String namespaceURI,
460 String localName) {
461 handleNewSource();
462 return document.getElementsByTagNameNS(namespaceURI, localName);
463 }
464
465 public Element getElementById(String elementId) {
466 handleNewSource();
467 return document.getElementById(elementId);
468 }
469 public org.w3c.dom.Node appendChild(org.w3c.dom.Node newChild)
470 throws DOMException {
471 handleNewSource();
472 return document.appendChild(newChild);
473 }
474
475 public org.w3c.dom.Node cloneNode(boolean deep) {
476 handleNewSource();
477 return document.cloneNode(deep);
478 }
479
480 protected SOAPPartImpl doCloneNode() {
481 handleNewSource();
482 SOAPPartImpl newSoapPart = duplicateType();
483
484 newSoapPart.headers = MimeHeadersUtil.copy(this.headers);
485 newSoapPart.source = this.source;
486 return newSoapPart;
487 }
488
489 public NamedNodeMap getAttributes() {
490 return document.getAttributes();
491 }
492
493 public NodeList getChildNodes() {
494 handleNewSource();
495 return document.getChildNodes();
496 }
497
498 public org.w3c.dom.Node getFirstChild() {
499 handleNewSource();
500 return document.getFirstChild();
501 }
502
503 public org.w3c.dom.Node getLastChild() {
504 handleNewSource();
505 return document.getLastChild();
506 }
507
508 public String getLocalName() {
509 return document.getLocalName();
510 }
511
512 public String getNamespaceURI() {
513 return document.getNamespaceURI();
514 }
515
516 public org.w3c.dom.Node getNextSibling() {
517 handleNewSource();
518 return document.getNextSibling();
519 }
520
521 public String getNodeName() {
522 return document.getNodeName();
523 }
524
525 public short getNodeType() {
526 return document.getNodeType();
527 }
528
529 public String getNodeValue() throws DOMException {
530 return document.getNodeValue();
531 }
532
533 public Document getOwnerDocument() {
534 return document.getOwnerDocument();
535 }
536
537 public org.w3c.dom.Node getParentNode() {
538 return document.getParentNode();
539 }
540
541 public String getPrefix() {
542 return document.getPrefix();
543 }
544
545 public org.w3c.dom.Node getPreviousSibling() {
546 return document.getPreviousSibling();
547 }
548
549 public boolean hasAttributes() {
550 return document.hasAttributes();
551 }
552
553 public boolean hasChildNodes() {
554 handleNewSource();
555 return document.hasChildNodes();
556 }
557
558 public org.w3c.dom.Node insertBefore(
559 org.w3c.dom.Node arg0,
560 org.w3c.dom.Node arg1)
561 throws DOMException {
562 handleNewSource();
563 return document.insertBefore(arg0, arg1);
564 }
565
566 public boolean isSupported(String arg0, String arg1) {
567 return document.isSupported(arg0, arg1);
568 }
569
570 public void normalize() {
571 handleNewSource();
572 document.normalize();
573 }
574
575 public org.w3c.dom.Node removeChild(org.w3c.dom.Node arg0)
576 throws DOMException {
577 handleNewSource();
578 return document.removeChild(arg0);
579 }
580
581 public org.w3c.dom.Node replaceChild(
582 org.w3c.dom.Node arg0,
583 org.w3c.dom.Node arg1)
584 throws DOMException {
585 handleNewSource();
586 return document.replaceChild(arg0, arg1);
587 }
588
589 public void setNodeValue(String arg0) throws DOMException {
590 document.setNodeValue(arg0);
591 }
592
593 public void setPrefix(String arg0) throws DOMException {
594 document.setPrefix(arg0);
595 }
596
597 private void handleNewSource() {
598 if (sourceWasSet) {
599 // There is a newer source use that source.
600 try {
601 getEnvelope();
602 } catch (SOAPException e) {
603 }
604 }
605 }
606
607 protected XMLDeclarationParser lookForXmlDecl() throws SOAPException {
608 if ((source != null) && (source instanceof StreamSource)) {
609
610 Reader reader = null;
611
612 InputStream inputStream = ((StreamSource) source).getInputStream();
613 if (inputStream != null) {
614 if (sourceCharsetEncoding == null) {
615 reader = new InputStreamReader(inputStream);
616 } else {
617 try {
618 reader =
619 new InputStreamReader(
620 inputStream, sourceCharsetEncoding);
621 } catch (UnsupportedEncodingException uee) {
622 log.log(
623 Level.SEVERE,
624 "SAAJ0551.soap.unsupported.encoding",
625 new Object[] {sourceCharsetEncoding});
626 throw new SOAPExceptionImpl(
627 "Unsupported encoding " + sourceCharsetEncoding,
628 uee);
629 }
630 }
631 } else {
632 reader = ((StreamSource) source).getReader();
633 }
634 if (reader != null) {
635 PushbackReader pushbackReader =
636 new PushbackReader(reader, 4096); //some size to unread <?xml ....?>
637 XMLDeclarationParser ev =
638 new XMLDeclarationParser(pushbackReader);
639 try {
640 ev.parse();
641 } catch (Exception e) {
642 log.log(
643 Level.SEVERE,
644 "SAAJ0552.soap.xml.decl.parsing.failed");
645 throw new SOAPExceptionImpl(
646 "XML declaration parsing failed", e);
647 }
648 String xmlDecl = ev.getXmlDeclaration();
649 if ((xmlDecl != null) && (xmlDecl.length() > 0))
650 this.omitXmlDecl = false;
651 return ev;
652 }
653 }
654 return null;
655 }
656
657 public void setSourceCharsetEncoding(String charset) {
658 this.sourceCharsetEncoding = charset;
659 }
660
661 public org.w3c.dom.Node renameNode(org.w3c.dom.Node n, String namespaceURI, String qualifiedName)
662 throws DOMException {
663 handleNewSource();
664 return document.renameNode(n, namespaceURI, qualifiedName);
665 }
666
667 public void normalizeDocument() {
668 document.normalizeDocument();
669 }
670
671 public DOMConfiguration getDomConfig() {
672 return document.getDomConfig();
673 }
674
675 public org.w3c.dom.Node adoptNode(org.w3c.dom.Node source) throws DOMException {
676 handleNewSource();
677 return document.adoptNode(source);
678 }
679
680 public void setDocumentURI(String documentURI) {
681 document.setDocumentURI(documentURI);
682 }
683
684 public String getDocumentURI() {
685 return document.getDocumentURI();
686 }
687
688 public void setStrictErrorChecking(boolean strictErrorChecking) {
689 document.setStrictErrorChecking(strictErrorChecking);
690 }
691
692 public String getInputEncoding() {
693 return document.getInputEncoding();
694 }
695
696 public String getXmlEncoding() {
697 return document.getXmlEncoding();
698 }
699
700 public boolean getXmlStandalone() {
701 return document.getXmlStandalone();
702 }
703
704 public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
705 document.setXmlStandalone(xmlStandalone);
706 }
707
708 public String getXmlVersion() {
709 return document.getXmlVersion();
710 }
711
712 public void setXmlVersion(String xmlVersion) throws DOMException {
713 document.setXmlVersion(xmlVersion);
714 }
715
716 public boolean getStrictErrorChecking() {
717 return document.getStrictErrorChecking();
718 }
719
720 // DOM L3 methods from org.w3c.dom.Node
721 public String getBaseURI() {
722 return document.getBaseURI();
723 }
724
725 public short compareDocumentPosition(org.w3c.dom.Node other)
726 throws DOMException {
727 return document.compareDocumentPosition(other);
728 }
729
730 public String getTextContent()
731 throws DOMException {
732 return document.getTextContent();
733 }
734
735 public void setTextContent(String textContent) throws DOMException {
736 document.setTextContent(textContent);
737 }
738
739 public boolean isSameNode(org.w3c.dom.Node other) {
740 return document.isSameNode(other);
741 }
742
743 public String lookupPrefix(String namespaceURI) {
744 return document.lookupPrefix(namespaceURI);
745 }
746
747 public boolean isDefaultNamespace(String namespaceURI) {
748 return document.isDefaultNamespace(namespaceURI);
749 }
750
751 public String lookupNamespaceURI(String prefix) {
752 return document.lookupNamespaceURI(prefix);
753 }
754
755 public boolean isEqualNode(org.w3c.dom.Node arg) {
756 return document.isEqualNode(arg);
757 }
758
759 public Object getFeature(String feature,
760 String version) {
761 return document.getFeature(feature,version);
762 }
763
764 public Object setUserData(String key,
765 Object data,
766 UserDataHandler handler) {
767 return document.setUserData(key, data, handler);
768 }
769
770 public Object getUserData(String key) {
771 return document.getUserData(key);
772 }
773
774 public void recycleNode() {
775 // Nothing seems to be required to be done here
776 }
777
778 public String getValue() {
779 return null;
780 }
781
782 public void setValue(String value) {
783 log.severe("SAAJ0571.soappart.setValue.not.defined");
784 throw new IllegalStateException("Setting value of a soap part is not defined");
785 }
786
787 public void setParentElement(SOAPElement parent) throws SOAPException {
788 log.severe("SAAJ0570.soappart.parent.element.not.defined");
789 throw new SOAPExceptionImpl("The parent element of a soap part is not defined");
790 }
791
792 public SOAPElement getParentElement() {
793 return null;
794 }
795
796 public void detachNode() {
797 // Nothing seems to be required to be done here
798 }
799 }

mercurial