src/share/jaxws_classes/com/sun/xml/internal/ws/message/stream/StreamMessage.java

changeset 397
b99d7e355d4b
parent 384
8f2986ff0235
child 637
9c07ef4934dd
equal deleted inserted replaced
393:6cdc6ed98780 397:b99d7e355d4b
28 import com.sun.istack.internal.NotNull; 28 import com.sun.istack.internal.NotNull;
29 import com.sun.istack.internal.Nullable; 29 import com.sun.istack.internal.Nullable;
30 import com.sun.istack.internal.XMLStreamReaderToContentHandler; 30 import com.sun.istack.internal.XMLStreamReaderToContentHandler;
31 import com.sun.xml.internal.bind.api.Bridge; 31 import com.sun.xml.internal.bind.api.Bridge;
32 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer; 32 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
33 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
34 import com.sun.xml.internal.stream.buffer.XMLStreamBufferMark;
33 import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator; 35 import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator;
34 import com.sun.xml.internal.ws.api.SOAPVersion; 36 import com.sun.xml.internal.ws.api.SOAPVersion;
35 import com.sun.xml.internal.ws.api.message.AttachmentSet; 37 import com.sun.xml.internal.ws.api.message.AttachmentSet;
36 import com.sun.xml.internal.ws.api.message.Header; 38 import com.sun.xml.internal.ws.api.message.Header;
37 import com.sun.xml.internal.ws.api.message.HeaderList; 39 import com.sun.xml.internal.ws.api.message.HeaderList;
38 import com.sun.xml.internal.ws.api.message.Message; 40 import com.sun.xml.internal.ws.api.message.Message;
39 import com.sun.xml.internal.ws.api.message.MessageHeaders; 41 import com.sun.xml.internal.ws.api.message.MessageHeaders;
42 import com.sun.xml.internal.ws.api.message.StreamingSOAP;
40 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; 43 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
41 import com.sun.xml.internal.ws.encoding.TagInfoset; 44 import com.sun.xml.internal.ws.encoding.TagInfoset;
42 import com.sun.xml.internal.ws.message.AbstractMessageImpl; 45 import com.sun.xml.internal.ws.message.AbstractMessageImpl;
43 import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl; 46 import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
47 import com.sun.xml.internal.ws.protocol.soap.VersionMismatchException;
44 import com.sun.xml.internal.ws.spi.db.XMLBridge; 48 import com.sun.xml.internal.ws.spi.db.XMLBridge;
45 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil; 49 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
46 import com.sun.xml.internal.ws.util.xml.DummyLocation; 50 import com.sun.xml.internal.ws.util.xml.DummyLocation;
47 import com.sun.xml.internal.ws.util.xml.StAXSource; 51 import com.sun.xml.internal.ws.util.xml.StAXSource;
52 import com.sun.xml.internal.ws.util.xml.XMLReaderComposite;
48 import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter; 53 import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter;
54 import com.sun.xml.internal.ws.util.xml.XMLReaderComposite.ElemInfo;
55
49 import org.xml.sax.ContentHandler; 56 import org.xml.sax.ContentHandler;
50 import org.xml.sax.ErrorHandler; 57 import org.xml.sax.ErrorHandler;
51 import org.xml.sax.SAXException; 58 import org.xml.sax.SAXException;
52 import org.xml.sax.SAXParseException; 59 import org.xml.sax.SAXParseException;
53 import org.xml.sax.helpers.NamespaceSupport; 60 import org.xml.sax.helpers.NamespaceSupport;
54 61
55 import javax.xml.bind.JAXBException; 62 import javax.xml.bind.JAXBException;
56 import javax.xml.bind.Unmarshaller; 63 import javax.xml.bind.Unmarshaller;
57 import javax.xml.stream.*; 64 import javax.xml.stream.*;
65
58 import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT; 66 import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT;
59 import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; 67 import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
60 import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; 68 import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
61 import javax.xml.transform.Source; 69 import javax.xml.transform.Source;
62 import javax.xml.ws.WebServiceException; 70 import javax.xml.ws.WebServiceException;
63 import java.util.ArrayList; 71 import java.util.ArrayList;
64 import java.util.Enumeration; 72 import java.util.Enumeration;
73 import java.util.HashMap;
65 import java.util.List; 74 import java.util.List;
75 import java.util.Map;
66 76
67 /** 77 /**
68 * {@link Message} implementation backed by {@link XMLStreamReader}. 78 * {@link Message} implementation backed by {@link XMLStreamReader}.
69 * 79 *
70 * TODO: we need another message class that keeps {@link XMLStreamReader} that points 80 * TODO: we need another message class that keeps {@link XMLStreamReader} that points
71 * at the start of the envelope element. 81 * at the start of the envelope element.
72 */ 82 */
73 public class StreamMessage extends AbstractMessageImpl { 83 public class StreamMessage extends AbstractMessageImpl implements StreamingSOAP {
74 /** 84 /**
75 * The reader will be positioned at 85 * The reader will be positioned at
76 * the first child of the SOAP body 86 * the first child of the SOAP body
77 */ 87 */
78 private @NotNull XMLStreamReader reader; 88 private @NotNull XMLStreamReader reader;
91 /** 101 /**
92 * instantiated after writing message to XMLStreamWriter 102 * instantiated after writing message to XMLStreamWriter
93 */ 103 */
94 private String bodyEpilogue = null; 104 private String bodyEpilogue = null;
95 105
96 private final String payloadLocalName; 106 private String payloadLocalName;
97 107
98 private final String payloadNamespaceURI; 108 private String payloadNamespaceURI;
99
100 /**
101 * infoset about the SOAP envelope, header, and body.
102 *
103 * <p>
104 * If the creater of this object didn't care about those,
105 * we use stock values.
106 */
107 private @NotNull TagInfoset envelopeTag;
108 private @NotNull TagInfoset headerTag;
109 private @NotNull TagInfoset bodyTag;
110 109
111 /** 110 /**
112 * Used only for debugging. This records where the message was consumed. 111 * Used only for debugging. This records where the message was consumed.
113 */ 112 */
114 private Throwable consumedAt; 113 private Throwable consumedAt;
115 114
116 /** 115 private XMLStreamReader envelopeReader;
117 * Default s:Envelope, s:Header, and s:Body tag infoset definitions.
118 *
119 * We need 3 for SOAP 1.1, 3 for SOAP 1.2.
120 */
121 private static final TagInfoset[] DEFAULT_TAGS;
122
123 static {
124 DEFAULT_TAGS = new TagInfoset[6];
125 create(SOAPVersion.SOAP_11);
126 create(SOAPVersion.SOAP_12);
127 }
128 116
129 public StreamMessage(SOAPVersion v) { 117 public StreamMessage(SOAPVersion v) {
130 super(v); 118 super(v);
131 payloadLocalName = null; 119 payloadLocalName = null;
132 payloadNamespaceURI = null; 120 payloadNamespaceURI = null;
133 } 121 }
122
123 public StreamMessage(SOAPVersion v, @NotNull XMLStreamReader envelope, @NotNull AttachmentSet attachments) {
124 super(v);
125 envelopeReader = envelope;
126 attachmentSet = attachments;
127 }
128
129 public XMLStreamReader readEnvelope() {
130 if (envelopeReader == null) {
131 List<XMLStreamReader> hReaders = new java.util.ArrayList<XMLStreamReader>();
132 ElemInfo envElem = new ElemInfo(envelopeTag, null);
133 ElemInfo hdrElem = (headerTag != null) ? new ElemInfo(headerTag, envElem) : null;
134 ElemInfo bdyElem = new ElemInfo(bodyTag, envElem);
135 for (Header h : getHeaders().asList()) {
136 try {
137 hReaders.add(h.readHeader());
138 } catch (XMLStreamException e) {
139 throw new RuntimeException(e);
140 }
141 }
142 XMLStreamReader soapHeader = (hdrElem != null) ? new XMLReaderComposite(hdrElem, hReaders.toArray(new XMLStreamReader[hReaders.size()])) : null;
143 XMLStreamReader[] payload = {readPayload()};
144 XMLStreamReader soapBody = new XMLReaderComposite(bdyElem, payload);
145 XMLStreamReader[] soapContent = (soapHeader != null) ? new XMLStreamReader[]{soapHeader, soapBody} : new XMLStreamReader[]{soapBody};
146 return new XMLReaderComposite(envElem, soapContent);
147 }
148 return envelopeReader;
149 }
150
134 /** 151 /**
135 * Creates a {@link StreamMessage} from a {@link XMLStreamReader} 152 * Creates a {@link StreamMessage} from a {@link XMLStreamReader}
136 * that points at the start element of the payload, and headers. 153 * that points at the start element of the payload, and headers.
137 * 154 *
138 * <p> 155 * <p>
145 * points at the start element/document of the payload (or the end element of the &lt;s:Body> 162 * points at the start element/document of the payload (or the end element of the &lt;s:Body>
146 * if there's no payload) 163 * if there's no payload)
147 */ 164 */
148 public StreamMessage(@Nullable MessageHeaders headers, @NotNull AttachmentSet attachmentSet, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) { 165 public StreamMessage(@Nullable MessageHeaders headers, @NotNull AttachmentSet attachmentSet, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) {
149 super(soapVersion); 166 super(soapVersion);
167 init(headers, attachmentSet, reader, soapVersion);
168 }
169
170 private void init(@Nullable MessageHeaders headers, @NotNull AttachmentSet attachmentSet, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) {
150 this.headers = headers; 171 this.headers = headers;
151 this.attachmentSet = attachmentSet; 172 this.attachmentSet = attachmentSet;
152 this.reader = reader; 173 this.reader = reader;
153 174
154 if(reader.getEventType()== START_DOCUMENT) 175 if(reader.getEventType()== START_DOCUMENT)
173 this.payloadNamespaceURI = reader.getNamespaceURI(); 194 this.payloadNamespaceURI = reader.getNamespaceURI();
174 } 195 }
175 196
176 // use the default infoset representation for headers 197 // use the default infoset representation for headers
177 int base = soapVersion.ordinal()*3; 198 int base = soapVersion.ordinal()*3;
178 this.envelopeTag = DEFAULT_TAGS[base]; 199 this.envelopeTag = DEFAULT_TAGS.get(base);
179 this.headerTag = DEFAULT_TAGS[base+1]; 200 this.headerTag = DEFAULT_TAGS.get(base+1);
180 this.bodyTag = DEFAULT_TAGS[base+2]; 201 this.bodyTag = DEFAULT_TAGS.get(base+2);
181 } 202 }
182 203
183 /** 204 /**
184 * Creates a {@link StreamMessage} from a {@link XMLStreamReader} 205 * Creates a {@link StreamMessage} from a {@link XMLStreamReader}
185 * and the complete infoset of the SOAP envelope. 206 * and the complete infoset of the SOAP envelope.
195 public StreamMessage(@NotNull TagInfoset envelopeTag, @Nullable TagInfoset headerTag, @NotNull AttachmentSet attachmentSet, @Nullable MessageHeaders headers, @NotNull TagInfoset bodyTag, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) { 216 public StreamMessage(@NotNull TagInfoset envelopeTag, @Nullable TagInfoset headerTag, @NotNull AttachmentSet attachmentSet, @Nullable MessageHeaders headers, @NotNull TagInfoset bodyTag, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) {
196 this(envelopeTag, headerTag, attachmentSet, headers, null, bodyTag, null, reader, soapVersion); 217 this(envelopeTag, headerTag, attachmentSet, headers, null, bodyTag, null, reader, soapVersion);
197 } 218 }
198 219
199 public StreamMessage(@NotNull TagInfoset envelopeTag, @Nullable TagInfoset headerTag, @NotNull AttachmentSet attachmentSet, @Nullable MessageHeaders headers, @Nullable String bodyPrologue, @NotNull TagInfoset bodyTag, @Nullable String bodyEpilogue, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) { 220 public StreamMessage(@NotNull TagInfoset envelopeTag, @Nullable TagInfoset headerTag, @NotNull AttachmentSet attachmentSet, @Nullable MessageHeaders headers, @Nullable String bodyPrologue, @NotNull TagInfoset bodyTag, @Nullable String bodyEpilogue, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) {
200 this(headers,attachmentSet,reader,soapVersion); 221 super(soapVersion);
222 init(envelopeTag, headerTag, attachmentSet, headers, bodyPrologue, bodyTag, bodyEpilogue, reader, soapVersion);
223 }
224
225 private void init(@NotNull TagInfoset envelopeTag, @Nullable TagInfoset headerTag, @NotNull AttachmentSet attachmentSet, @Nullable MessageHeaders headers, @Nullable String bodyPrologue, @NotNull TagInfoset bodyTag, @Nullable String bodyEpilogue, @NotNull XMLStreamReader reader, @NotNull SOAPVersion soapVersion) {
226 init(headers,attachmentSet,reader,soapVersion);
201 if(envelopeTag == null ) { 227 if(envelopeTag == null ) {
202 throw new IllegalArgumentException("EnvelopeTag TagInfoset cannot be null"); 228 throw new IllegalArgumentException("EnvelopeTag TagInfoset cannot be null");
203 } 229 }
204 if(bodyTag == null ) { 230 if(bodyTag == null ) {
205 throw new IllegalArgumentException("BodyTag TagInfoset cannot be null"); 231 throw new IllegalArgumentException("BodyTag TagInfoset cannot be null");
210 this.bodyPrologue = bodyPrologue; 236 this.bodyPrologue = bodyPrologue;
211 this.bodyEpilogue = bodyEpilogue; 237 this.bodyEpilogue = bodyEpilogue;
212 } 238 }
213 239
214 public boolean hasHeaders() { 240 public boolean hasHeaders() {
241 if ( envelopeReader != null ) readEnvelope(this);
215 return headers!=null && headers.hasHeaders(); 242 return headers!=null && headers.hasHeaders();
216 } 243 }
217 244
218 public MessageHeaders getHeaders() { 245 public MessageHeaders getHeaders() {
246 if ( envelopeReader != null ) readEnvelope(this);
219 if (headers == null) { 247 if (headers == null) {
220 headers = new HeaderList(getSOAPVersion()); 248 headers = new HeaderList(getSOAPVersion());
221 } 249 }
222 return headers; 250 return headers;
223 } 251 }
224 252
225 public String getPayloadLocalPart() { 253 public String getPayloadLocalPart() {
254 if ( envelopeReader != null ) readEnvelope(this);
226 return payloadLocalName; 255 return payloadLocalName;
227 } 256 }
228 257
229 public String getPayloadNamespaceURI() { 258 public String getPayloadNamespaceURI() {
259 if ( envelopeReader != null ) readEnvelope(this);
230 return payloadNamespaceURI; 260 return payloadNamespaceURI;
231 } 261 }
232 262
233 public boolean hasPayload() { 263 public boolean hasPayload() {
264 if ( envelopeReader != null ) readEnvelope(this);
234 return payloadLocalName!=null; 265 return payloadLocalName!=null;
235 } 266 }
236 267
237 public Source readPayloadAsSource() { 268 public Source readPayloadAsSource() {
238 if(hasPayload()) { 269 if(hasPayload()) {
327 assert unconsumed(); 358 assert unconsumed();
328 return this.reader; 359 return this.reader;
329 } 360 }
330 361
331 public void writePayloadTo(XMLStreamWriter writer)throws XMLStreamException { 362 public void writePayloadTo(XMLStreamWriter writer)throws XMLStreamException {
363 if ( envelopeReader != null ) readEnvelope(this);
332 assert unconsumed(); 364 assert unconsumed();
333 365
334 if(payloadLocalName==null) { 366 if(payloadLocalName==null) {
335 return; // no body 367 return; // no body
336 } 368 }
377 private boolean isBodyElement(String name, String nsUri) { 409 private boolean isBodyElement(String name, String nsUri) {
378 return name.equals("Body") && nsUri.equals(soapVersion.nsUri); 410 return name.equals("Body") && nsUri.equals(soapVersion.nsUri);
379 } 411 }
380 412
381 public void writeTo(XMLStreamWriter sw) throws XMLStreamException{ 413 public void writeTo(XMLStreamWriter sw) throws XMLStreamException{
414 if ( envelopeReader != null ) readEnvelope(this);
382 writeEnvelope(sw); 415 writeEnvelope(sw);
383 } 416 }
384 417
385 /** 418 /**
386 * This method should be called when the StreamMessage is created with a payload 419 * This method should be called when the StreamMessage is created with a payload
387 * @param writer 420 * @param writer
388 */ 421 */
389 private void writeEnvelope(XMLStreamWriter writer) throws XMLStreamException { 422 private void writeEnvelope(XMLStreamWriter writer) throws XMLStreamException {
423 if ( envelopeReader != null ) readEnvelope(this);
390 writer.writeStartDocument(); 424 writer.writeStartDocument();
391 envelopeTag.writeStart(writer); 425 envelopeTag.writeStart(writer);
392 426
393 //write headers 427 //write headers
394 MessageHeaders hl = getHeaders(); 428 MessageHeaders hl = getHeaders();
409 writer.writeEndElement(); 443 writer.writeEndElement();
410 writer.writeEndDocument(); 444 writer.writeEndDocument();
411 } 445 }
412 446
413 public void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException { 447 public void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
448 if ( envelopeReader != null ) readEnvelope(this);
414 assert unconsumed(); 449 assert unconsumed();
415 450
416 try { 451 try {
417 if(payloadLocalName==null) 452 if(payloadLocalName==null)
418 return; // no body 453 return; // no body
463 e.getMessage(),loc.getPublicId(),loc.getSystemId(),loc.getLineNumber(),loc.getColumnNumber(),e); 498 e.getMessage(),loc.getPublicId(),loc.getSystemId(),loc.getLineNumber(),loc.getColumnNumber(),e);
464 errorHandler.error(x); 499 errorHandler.error(x);
465 } 500 }
466 } 501 }
467 502
468 // TODO: this method should be probably rewritten to respect spaces between eelements; is it used at all? 503 // TODO: this method should be probably rewritten to respect spaces between elements; is it used at all?
504 @Override
469 public Message copy() { 505 public Message copy() {
506 if ( envelopeReader != null ) readEnvelope(this);
470 try { 507 try {
471 assert unconsumed(); 508 assert unconsumed();
472 consumedAt = null; // but we don't want to mark it as consumed 509 consumedAt = null; // but we don't want to mark it as consumed
473 MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); 510 MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
474 StreamReaderBufferCreator c = new StreamReaderBufferCreator(xsb); 511 StreamReaderBufferCreator c = new StreamReaderBufferCreator(xsb);
526 xsr.nextTag(); 563 xsr.nextTag();
527 assert xsr.getEventType()==START_ELEMENT || xsr.getEventType()==END_ELEMENT; 564 assert xsr.getEventType()==START_ELEMENT || xsr.getEventType()==END_ELEMENT;
528 } 565 }
529 566
530 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler ) throws SAXException { 567 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler ) throws SAXException {
568 if ( envelopeReader != null ) readEnvelope(this);
531 contentHandler.setDocumentLocator(NULL_LOCATOR); 569 contentHandler.setDocumentLocator(NULL_LOCATOR);
532 contentHandler.startDocument(); 570 contentHandler.startDocument();
533 envelopeTag.writeStart(contentHandler); 571 envelopeTag.writeStart(contentHandler);
534 if (hasHeaders() && headerTag == null) headerTag = new TagInfoset(envelopeTag.nsUri,"Header",envelopeTag.prefix,EMPTY_ATTS); 572 if (hasHeaders() && headerTag == null) headerTag = new TagInfoset(envelopeTag.nsUri,"Header",envelopeTag.prefix,EMPTY_ATTS);
535 if (headerTag != null) { 573 if (headerTag != null) {
568 } 606 }
569 consumedAt = new Exception().fillInStackTrace(); 607 consumedAt = new Exception().fillInStackTrace();
570 return true; 608 return true;
571 } 609 }
572 610
573 private static void create(SOAPVersion v) {
574 int base = v.ordinal()*3;
575 DEFAULT_TAGS[base ] = new TagInfoset(v.nsUri,"Envelope","S",EMPTY_ATTS,"S",v.nsUri);
576 DEFAULT_TAGS[base+1] = new TagInfoset(v.nsUri,"Header","S",EMPTY_ATTS);
577 DEFAULT_TAGS[base+2] = new TagInfoset(v.nsUri,"Body","S",EMPTY_ATTS);
578 }
579
580 public String getBodyPrologue() { 611 public String getBodyPrologue() {
612 if ( envelopeReader != null ) readEnvelope(this);
581 return bodyPrologue; 613 return bodyPrologue;
582 } 614 }
583 615
584 public String getBodyEpilogue() { 616 public String getBodyEpilogue() {
617 if ( envelopeReader != null ) readEnvelope(this);
585 return bodyEpilogue; 618 return bodyEpilogue;
586 } 619 }
587 620
588 public XMLStreamReader getReader() { 621 public XMLStreamReader getReader() {
622 if ( envelopeReader != null ) readEnvelope(this);
589 assert unconsumed(); 623 assert unconsumed();
590 return reader; 624 return reader;
591 } 625 }
626
627
628 private static final String SOAP_ENVELOPE = "Envelope";
629 private static final String SOAP_HEADER = "Header";
630 private static final String SOAP_BODY = "Body";
631
632 protected interface StreamHeaderDecoder {
633 public Header decodeHeader(XMLStreamReader reader, XMLStreamBuffer mark);
634 }
635
636 static final StreamHeaderDecoder SOAP12StreamHeaderDecoder = new StreamHeaderDecoder() {
637 @Override
638 public Header decodeHeader(XMLStreamReader reader, XMLStreamBuffer mark) {
639 return new StreamHeader12(reader, mark);
640 }
641 };
642
643 static final StreamHeaderDecoder SOAP11StreamHeaderDecoder = new StreamHeaderDecoder() {
644 @Override
645 public Header decodeHeader(XMLStreamReader reader, XMLStreamBuffer mark) {
646 return new StreamHeader11(reader, mark);
647 }
648 };
649
650 static private void readEnvelope(StreamMessage message) {
651 if ( message.envelopeReader == null ) return;
652 XMLStreamReader reader = message.envelopeReader;
653 message.envelopeReader = null;
654 SOAPVersion soapVersion = message.soapVersion;
655 // Move to soap:Envelope and verify
656 if(reader.getEventType()!=XMLStreamConstants.START_ELEMENT)
657 XMLStreamReaderUtil.nextElementContent(reader);
658 XMLStreamReaderUtil.verifyReaderState(reader,XMLStreamConstants.START_ELEMENT);
659 if (SOAP_ENVELOPE.equals(reader.getLocalName()) && !soapVersion.nsUri.equals(reader.getNamespaceURI())) {
660 throw new VersionMismatchException(soapVersion, soapVersion.nsUri, reader.getNamespaceURI());
661 }
662 XMLStreamReaderUtil.verifyTag(reader, soapVersion.nsUri, SOAP_ENVELOPE);
663
664 TagInfoset envelopeTag = new TagInfoset(reader);
665
666 // Collect namespaces on soap:Envelope
667 Map<String,String> namespaces = new HashMap<String,String>();
668 for(int i=0; i< reader.getNamespaceCount();i++){
669 namespaces.put(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
670 }
671
672 // Move to next element
673 XMLStreamReaderUtil.nextElementContent(reader);
674 XMLStreamReaderUtil.verifyReaderState(reader,
675 javax.xml.stream.XMLStreamConstants.START_ELEMENT);
676
677 HeaderList headers = null;
678 TagInfoset headerTag = null;
679
680 if (reader.getLocalName().equals(SOAP_HEADER)
681 && reader.getNamespaceURI().equals(soapVersion.nsUri)) {
682 headerTag = new TagInfoset(reader);
683
684 // Collect namespaces on soap:Header
685 for(int i=0; i< reader.getNamespaceCount();i++){
686 namespaces.put(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
687 }
688 // skip <soap:Header>
689 XMLStreamReaderUtil.nextElementContent(reader);
690
691 // If SOAP header blocks are present (i.e. not <soap:Header/>)
692 if (reader.getEventType() == XMLStreamConstants.START_ELEMENT) {
693 headers = new HeaderList(soapVersion);
694
695 try {
696 // Cache SOAP header blocks
697 StreamHeaderDecoder headerDecoder = SOAPVersion.SOAP_11.equals(soapVersion) ? SOAP11StreamHeaderDecoder : SOAP12StreamHeaderDecoder;
698 cacheHeaders(reader, namespaces, headers, headerDecoder);
699 } catch (XMLStreamException e) {
700 // TODO need to throw more meaningful exception
701 throw new WebServiceException(e);
702 }
703 }
704
705 // Move to soap:Body
706 XMLStreamReaderUtil.nextElementContent(reader);
707 }
708
709 // Verify that <soap:Body> is present
710 XMLStreamReaderUtil.verifyTag(reader, soapVersion.nsUri, SOAP_BODY);
711 TagInfoset bodyTag = new TagInfoset(reader);
712
713 String bodyPrologue = XMLStreamReaderUtil.nextWhiteSpaceContent(reader);
714 message.init(envelopeTag,headerTag,message.attachmentSet,headers,bodyPrologue,bodyTag,null,reader,soapVersion);
715 // when there's no payload,
716 // it's tempting to use EmptyMessageImpl, but it doesn't preserve the infoset
717 // of <envelope>,<header>, and <body>, so we need to stick to StreamMessage.
718 }
719
720
721 private static XMLStreamBuffer cacheHeaders(XMLStreamReader reader,
722 Map<String, String> namespaces, HeaderList headers,
723 StreamHeaderDecoder headerDecoder) throws XMLStreamException {
724 MutableXMLStreamBuffer buffer = createXMLStreamBuffer();
725 StreamReaderBufferCreator creator = new StreamReaderBufferCreator();
726 creator.setXMLStreamBuffer(buffer);
727
728 // Reader is positioned at the first header block
729 while(reader.getEventType() == javax.xml.stream.XMLStreamConstants.START_ELEMENT) {
730 Map<String,String> headerBlockNamespaces = namespaces;
731
732 // Collect namespaces on SOAP header block
733 if (reader.getNamespaceCount() > 0) {
734 headerBlockNamespaces = new HashMap<String,String>(namespaces);
735 for (int i = 0; i < reader.getNamespaceCount(); i++) {
736 headerBlockNamespaces.put(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
737 }
738 }
739
740 // Mark
741 XMLStreamBuffer mark = new XMLStreamBufferMark(headerBlockNamespaces, creator);
742 // Create Header
743 headers.add(headerDecoder.decodeHeader(reader, mark));
744
745
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 }
592 } 766 }

mercurial