1 /*
2 * Copyright (c) 1997, 2013, 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
33 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
34 import com.sun.xml.internal.stream.buffer.XMLStreamBufferMark;
35 import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator;
36 import com.sun.xml.internal.ws.api.SOAPVersion;
37 import com.sun.xml.internal.ws.api.message.AttachmentSet;
38 import com.sun.xml.internal.ws.api.message.Header;
39 import com.sun.xml.internal.ws.api.message.HeaderList;
40 import com.sun.xml.internal.ws.api.message.Message;
41 import com.sun.xml.internal.ws.api.message.MessageHeaders;
42 import com.sun.xml.internal.ws.api.message.StreamingSOAP;
43 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
44 import com.sun.xml.internal.ws.encoding.TagInfoset;
45 import com.sun.xml.internal.ws.message.AbstractMessageImpl;
46 import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
47 import com.sun.xml.internal.ws.protocol.soap.VersionMismatchException;
48 import com.sun.xml.internal.ws.spi.db.XMLBridge;
49 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
50 import com.sun.xml.internal.ws.util.xml.DummyLocation;
51 import com.sun.xml.internal.ws.util.xml.StAXSource;
52 import com.sun.xml.internal.ws.util.xml.XMLReaderComposite;
53 import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter;
54 import com.sun.xml.internal.ws.util.xml.XMLReaderComposite.ElemInfo;
55
56 import org.xml.sax.ContentHandler;
57 import org.xml.sax.ErrorHandler;
58 import org.xml.sax.SAXException;
59 import org.xml.sax.SAXParseException;
60 import org.xml.sax.helpers.NamespaceSupport;
61
62 import javax.xml.bind.JAXBException;
63 import javax.xml.bind.Unmarshaller;
64 import javax.xml.stream.*;
65
66 import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT;
67 import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
68 import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
69 import javax.xml.transform.Source;
70 import javax.xml.ws.WebServiceException;
71 import java.util.ArrayList;
72 import java.util.Enumeration;
73 import java.util.HashMap;
74 import java.util.List;
75 import java.util.Map;
76
77 /**
78 * {@link Message} implementation backed by {@link XMLStreamReader}.
79 *
80 * TODO: we need another message class that keeps {@link XMLStreamReader} that points
81 * at the start of the envelope element.
82 */
83 public class StreamMessage extends AbstractMessageImpl implements StreamingSOAP {
398 } else {
399 // payload opening element: copy payload to writer
400 conv.bridge(reader,writer);
401 }
402 }
403
404 XMLStreamReaderUtil.readRest(reader);
405 XMLStreamReaderUtil.close(reader);
406 XMLStreamReaderFactory.recycle(reader);
407 }
408
409 private boolean isBodyElement(String name, String nsUri) {
410 return name.equals("Body") && nsUri.equals(soapVersion.nsUri);
411 }
412
413 public void writeTo(XMLStreamWriter sw) throws XMLStreamException{
414 if ( envelopeReader != null ) readEnvelope(this);
415 writeEnvelope(sw);
416 }
417
418 /**
419 * This method should be called when the StreamMessage is created with a payload
420 * @param writer
421 */
422 private void writeEnvelope(XMLStreamWriter writer) throws XMLStreamException {
423 if ( envelopeReader != null ) readEnvelope(this);
424 writer.writeStartDocument();
425 envelopeTag.writeStart(writer);
426
427 //write headers
428 MessageHeaders hl = getHeaders();
429 if (hl.hasHeaders() && headerTag == null) headerTag = new TagInfoset(envelopeTag.nsUri,"Header",envelopeTag.prefix,EMPTY_ATTS);
430 if (headerTag != null) {
431 headerTag.writeStart(writer);
432 if (hl.hasHeaders()){
433 for(Header h : hl.asList()){
434 h.writeTo(writer);
435 }
436 }
437 writer.writeEndElement();
438 }
439 bodyTag.writeStart(writer);
440 if(hasPayload())
441 writePayloadTo(writer);
442 writer.writeEndElement();
443 writer.writeEndElement();
444 writer.writeEndDocument();
445 }
446
447 public void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
448 if ( envelopeReader != null ) readEnvelope(this);
449 assert unconsumed();
450
451 try {
452 if(payloadLocalName==null)
453 return; // no body
454
455 if (bodyPrologue != null) {
456 char[] chars = bodyPrologue.toCharArray();
457 contentHandler.characters(chars, 0, chars.length);
458 }
459
533 // (we are interested only in the last one?)
534 bodyEpilogue = null;
535 }
536 }
537 }
538 c.storeEndElement(); // create structure element for </Body>
539 c.storeEndElement(); // create structure element for </Envelope>
540 c.storeEndElement(); // create structure element for END_DOCUMENT
541
542 XMLStreamReaderUtil.readRest(reader);
543 XMLStreamReaderUtil.close(reader);
544 XMLStreamReaderFactory.recycle(reader);
545
546 reader = xsb.readAsXMLStreamReader();
547 XMLStreamReader clone = xsb.readAsXMLStreamReader();
548
549 // advance to the start tag of the <Body> first child element
550 proceedToRootElement(reader);
551 proceedToRootElement(clone);
552
553 return new StreamMessage(envelopeTag, headerTag, attachmentSet, HeaderList.copy(headers), bodyPrologue, bodyTag, bodyEpilogue, clone, soapVersion);
554 } catch (XMLStreamException e) {
555 throw new WebServiceException("Failed to copy a message",e);
556 }
557 }
558
559 private void proceedToRootElement(XMLStreamReader xsr) throws XMLStreamException {
560 assert xsr.getEventType()==START_DOCUMENT;
561 xsr.nextTag();
562 xsr.nextTag();
563 xsr.nextTag();
564 assert xsr.getEventType()==START_ELEMENT || xsr.getEventType()==END_ELEMENT;
565 }
566
567 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler ) throws SAXException {
568 if ( envelopeReader != null ) readEnvelope(this);
569 contentHandler.setDocumentLocator(NULL_LOCATOR);
570 contentHandler.startDocument();
571 envelopeTag.writeStart(contentHandler);
572 if (hasHeaders() && headerTag == null) headerTag = new TagInfoset(envelopeTag.nsUri,"Header",envelopeTag.prefix,EMPTY_ATTS);
573 if (headerTag != null) {
746 // Cache the header block
747 // After caching Reader will be positioned at next header block or
748 // the end of the </soap:header>
749 creator.createElementFragment(reader, false);
750 if (reader.getEventType() != XMLStreamConstants.START_ELEMENT &&
751 reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
752 XMLStreamReaderUtil.nextElementContent(reader);
753 }
754 }
755
756 return buffer;
757 }
758
759 private static MutableXMLStreamBuffer createXMLStreamBuffer() {
760 // TODO: Decode should own one MutableXMLStreamBuffer for reuse
761 // since it is more efficient. ISSUE: possible issue with
762 // lifetime of information in the buffer if accessed beyond
763 // the pipe line.
764 return new MutableXMLStreamBuffer();
765 }
766 }
|
1 /*
2 * Copyright (c) 1997, 2014, 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
33 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
34 import com.sun.xml.internal.stream.buffer.XMLStreamBufferMark;
35 import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator;
36 import com.sun.xml.internal.ws.api.SOAPVersion;
37 import com.sun.xml.internal.ws.api.message.AttachmentSet;
38 import com.sun.xml.internal.ws.api.message.Header;
39 import com.sun.xml.internal.ws.api.message.HeaderList;
40 import com.sun.xml.internal.ws.api.message.Message;
41 import com.sun.xml.internal.ws.api.message.MessageHeaders;
42 import com.sun.xml.internal.ws.api.message.StreamingSOAP;
43 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
44 import com.sun.xml.internal.ws.encoding.TagInfoset;
45 import com.sun.xml.internal.ws.message.AbstractMessageImpl;
46 import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
47 import com.sun.xml.internal.ws.protocol.soap.VersionMismatchException;
48 import com.sun.xml.internal.ws.spi.db.XMLBridge;
49 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
50 import com.sun.xml.internal.ws.util.xml.DummyLocation;
51 import com.sun.xml.internal.ws.util.xml.StAXSource;
52 import com.sun.xml.internal.ws.util.xml.XMLReaderComposite;
53 import com.sun.xml.internal.org.jvnet.staxex.util.XMLStreamReaderToXMLStreamWriter;
54 import com.sun.xml.internal.ws.util.xml.XMLReaderComposite.ElemInfo;
55
56 import org.xml.sax.ContentHandler;
57 import org.xml.sax.ErrorHandler;
58 import org.xml.sax.SAXException;
59 import org.xml.sax.SAXParseException;
60 import org.xml.sax.helpers.NamespaceSupport;
61
62 import javax.xml.bind.JAXBException;
63 import javax.xml.bind.Unmarshaller;
64 import javax.xml.namespace.QName;
65 import javax.xml.stream.*;
66
67 import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT;
68 import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
69 import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
70 import javax.xml.transform.Source;
71 import javax.xml.ws.WebServiceException;
72 import java.util.ArrayList;
73 import java.util.Enumeration;
74 import java.util.HashMap;
75 import java.util.List;
76 import java.util.Map;
77
78 /**
79 * {@link Message} implementation backed by {@link XMLStreamReader}.
80 *
81 * TODO: we need another message class that keeps {@link XMLStreamReader} that points
82 * at the start of the envelope element.
83 */
84 public class StreamMessage extends AbstractMessageImpl implements StreamingSOAP {
399 } else {
400 // payload opening element: copy payload to writer
401 conv.bridge(reader,writer);
402 }
403 }
404
405 XMLStreamReaderUtil.readRest(reader);
406 XMLStreamReaderUtil.close(reader);
407 XMLStreamReaderFactory.recycle(reader);
408 }
409
410 private boolean isBodyElement(String name, String nsUri) {
411 return name.equals("Body") && nsUri.equals(soapVersion.nsUri);
412 }
413
414 public void writeTo(XMLStreamWriter sw) throws XMLStreamException{
415 if ( envelopeReader != null ) readEnvelope(this);
416 writeEnvelope(sw);
417 }
418
419 public void writeToBodyStart(XMLStreamWriter writer) throws XMLStreamException {
420 if ( envelopeReader != null ) readEnvelope(this);
421 writer.writeStartDocument();
422 envelopeTag.writeStart(writer);
423
424 //write headers
425 MessageHeaders hl = getHeaders();
426 if (hl.hasHeaders() && headerTag == null) headerTag = new TagInfoset(envelopeTag.nsUri,"Header",envelopeTag.prefix,EMPTY_ATTS);
427 if (headerTag != null) {
428 headerTag.writeStart(writer);
429 if (hl.hasHeaders()){
430 for(Header h : hl.asList()){
431 h.writeTo(writer);
432 }
433 }
434 writer.writeEndElement();
435 }
436 bodyTag.writeStart(writer);
437
438 }
439
440 /**
441 * This method should be called when the StreamMessage is created with a payload
442 * @param writer
443 */
444 private void writeEnvelope(XMLStreamWriter writer) throws XMLStreamException {
445 writeToBodyStart(writer);
446 if(hasPayload())
447 writePayloadTo(writer);
448 writer.writeEndElement();
449 writer.writeEndElement();
450 writer.writeEndDocument();
451 }
452
453 public void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
454 if ( envelopeReader != null ) readEnvelope(this);
455 assert unconsumed();
456
457 try {
458 if(payloadLocalName==null)
459 return; // no body
460
461 if (bodyPrologue != null) {
462 char[] chars = bodyPrologue.toCharArray();
463 contentHandler.characters(chars, 0, chars.length);
464 }
465
539 // (we are interested only in the last one?)
540 bodyEpilogue = null;
541 }
542 }
543 }
544 c.storeEndElement(); // create structure element for </Body>
545 c.storeEndElement(); // create structure element for </Envelope>
546 c.storeEndElement(); // create structure element for END_DOCUMENT
547
548 XMLStreamReaderUtil.readRest(reader);
549 XMLStreamReaderUtil.close(reader);
550 XMLStreamReaderFactory.recycle(reader);
551
552 reader = xsb.readAsXMLStreamReader();
553 XMLStreamReader clone = xsb.readAsXMLStreamReader();
554
555 // advance to the start tag of the <Body> first child element
556 proceedToRootElement(reader);
557 proceedToRootElement(clone);
558
559 return new StreamMessage(envelopeTag, headerTag, attachmentSet, HeaderList.copy(headers), bodyPrologue, bodyTag, bodyEpilogue, clone, soapVersion).copyFrom(this);
560 } catch (XMLStreamException e) {
561 throw new WebServiceException("Failed to copy a message",e);
562 }
563 }
564
565 private void proceedToRootElement(XMLStreamReader xsr) throws XMLStreamException {
566 assert xsr.getEventType()==START_DOCUMENT;
567 xsr.nextTag();
568 xsr.nextTag();
569 xsr.nextTag();
570 assert xsr.getEventType()==START_ELEMENT || xsr.getEventType()==END_ELEMENT;
571 }
572
573 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler ) throws SAXException {
574 if ( envelopeReader != null ) readEnvelope(this);
575 contentHandler.setDocumentLocator(NULL_LOCATOR);
576 contentHandler.startDocument();
577 envelopeTag.writeStart(contentHandler);
578 if (hasHeaders() && headerTag == null) headerTag = new TagInfoset(envelopeTag.nsUri,"Header",envelopeTag.prefix,EMPTY_ATTS);
579 if (headerTag != null) {
752 // Cache the header block
753 // After caching Reader will be positioned at next header block or
754 // the end of the </soap:header>
755 creator.createElementFragment(reader, false);
756 if (reader.getEventType() != XMLStreamConstants.START_ELEMENT &&
757 reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
758 XMLStreamReaderUtil.nextElementContent(reader);
759 }
760 }
761
762 return buffer;
763 }
764
765 private static MutableXMLStreamBuffer createXMLStreamBuffer() {
766 // TODO: Decode should own one MutableXMLStreamBuffer for reuse
767 // since it is more efficient. ISSUE: possible issue with
768 // lifetime of information in the buffer if accessed beyond
769 // the pipe line.
770 return new MutableXMLStreamBuffer();
771 }
772
773 public boolean isPayloadStreamReader() { return true; }
774
775 public QName getPayloadQName() {
776 return this.hasPayload() ? new QName(payloadNamespaceURI, payloadLocalName) : null;
777 }
778
779 public XMLStreamReader readToBodyStarTag() {
780 if ( envelopeReader != null ) readEnvelope(this);
781 List<XMLStreamReader> hReaders = new java.util.ArrayList<XMLStreamReader>();
782 ElemInfo envElem = new ElemInfo(envelopeTag, null);
783 ElemInfo hdrElem = (headerTag != null) ? new ElemInfo(headerTag, envElem) : null;
784 ElemInfo bdyElem = new ElemInfo(bodyTag, envElem);
785 for (Header h : getHeaders().asList()) {
786 try {
787 hReaders.add(h.readHeader());
788 } catch (XMLStreamException e) {
789 throw new RuntimeException(e);
790 }
791 }
792 XMLStreamReader soapHeader = (hdrElem != null) ? new XMLReaderComposite(hdrElem, hReaders.toArray(new XMLStreamReader[hReaders.size()])) : null;
793 XMLStreamReader[] payload = {};
794 XMLStreamReader soapBody = new XMLReaderComposite(bdyElem, payload);
795 XMLStreamReader[] soapContent = (soapHeader != null) ? new XMLStreamReader[]{soapHeader, soapBody} : new XMLStreamReader[]{soapBody};
796 return new XMLReaderComposite(envElem, soapContent);
797 }
798 }
|