You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ve...@apache.org on 2009/01/27 14:29:11 UTC
svn commit: r738086 - in /webservices/axis2/trunk/java/modules/saaj:
src/org/apache/axis2/saaj/ test-resources/ test/org/apache/axis2/saaj/
Author: veithen
Date: Tue Jan 27 13:29:10 2009
New Revision: 738086
URL: http://svn.apache.org/viewvc?rev=738086&view=rev
Log:
AXIS2-4189: Fixed MessageFactoryImpl#createMessage(MimeHeaders, InputStream) so that it behaves according to the SAAJ specs (and to Sun's reference implementation), i.e.
* creates AttachmentParts for all attachments (SwA and MTOM);
* doesn't substitute xop:Include elements (this behavior can be changed using the new MessageFactoryImpl#setProcessMTOM method);
* correctly populates the MimeHeader objects linked to the SOAPPart and AttachmentParts.
To this end, processing of multipart/related has been moved from SOAPPartImpl to SOAPMessageImpl. This also makes more sense from a design point of view.
Modified:
webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/MessageFactoryImpl.java
webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java
webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPMessageImpl.java
webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPPartImpl.java
webservices/axis2/trunk/java/modules/saaj/test-resources/message.bin
webservices/axis2/trunk/java/modules/saaj/test/org/apache/axis2/saaj/MessageFactoryTest.java
Modified: webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/MessageFactoryImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/MessageFactoryImpl.java?rev=738086&r1=738085&r2=738086&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/MessageFactoryImpl.java (original)
+++ webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/MessageFactoryImpl.java Tue Jan 27 13:29:10 2009
@@ -77,6 +77,7 @@
public class MessageFactoryImpl extends MessageFactory {
protected String soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
+ private boolean processMTOM;
/**
* Creates a new <CODE>SOAPMessage</CODE> object with the default <CODE>SOAPPart</CODE>,
@@ -128,7 +129,7 @@
*/
public SOAPMessage createMessage(MimeHeaders mimeheaders,
InputStream inputstream) throws IOException, SOAPException {
- SOAPMessageImpl soapMessage = new SOAPMessageImpl(inputstream, mimeheaders);
+ SOAPMessageImpl soapMessage = new SOAPMessageImpl(inputstream, mimeheaders, processMTOM);
soapMessage.setSaveRequired();
return soapMessage;
}
@@ -136,4 +137,23 @@
public void setSOAPVersion(String soapVersion) {
this.soapVersion = soapVersion;
}
+
+ /**
+ * Specify whether MTOM messages should be processed or parsed literally.
+ * <p>
+ * The way MTOM messages are handled fundamentally differs between Axiom and SAAJ.
+ * While Axiom replaces xop:Include elements by {@link javax.activation.DataHandler} backed
+ * {@link org.apache.axiom.om.OMText} nodes, there is no such requirement in SAAJ. The only
+ * requirement there is that {@link SOAPMessage#getAttachment(javax.xml.soap.SOAPElement)}
+ * returns the relevant {@link javax.xml.soap.AttachmentPart} when applied to an
+ * xop:Include element.
+ * <p>
+ * This method allows to make this SAAJ implementation behave as Axiom, i.e. to substitute
+ * xop:Include elements.
+ *
+ * @param processMTOM whether xop:Include elements should be substituted
+ */
+ public void setProcessMTOM(boolean processMTOM) {
+ this.processMTOM = processMTOM;
+ }
}
Modified: webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java?rev=738086&r1=738085&r2=738086&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java Tue Jan 27 13:29:10 2009
@@ -476,7 +476,7 @@
httpInputStream = httpCon.getInputStream();
}
- soapMessage = new SOAPMessageImpl(httpInputStream, mimeHeaders);
+ soapMessage = new SOAPMessageImpl(httpInputStream, mimeHeaders, false);
httpInputStream.close();
httpCon.disconnect();
Modified: webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPMessageImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPMessageImpl.java?rev=738086&r1=738085&r2=738086&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPMessageImpl.java (original)
+++ webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPMessageImpl.java Tue Jan 27 13:29:10 2009
@@ -19,7 +19,9 @@
package org.apache.axis2.saaj;
+import org.apache.axiom.attachments.Attachments;
import org.apache.axiom.attachments.ByteArrayDataSource;
+import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.impl.MIMEOutputUtils;
import org.apache.axiom.soap.SOAP11Constants;
@@ -72,7 +74,7 @@
soapPart = new SOAPPartImpl(this, soapEnvelope);
}
- public SOAPMessageImpl(InputStream inputstream, javax.xml.soap.MimeHeaders mimeHeaders)
+ public SOAPMessageImpl(InputStream inputstream, MimeHeaders mimeHeaders, boolean processMTOM)
throws SOAPException {
String contentType = null;
String tmpContentType = "";
@@ -83,11 +85,37 @@
contentType = SAAJUtil.normalizeContentType(tmpContentType);
}
}
- initCharsetEncodingFromContentType(tmpContentType);
- if (contentType != null) {
- soapPart = new SOAPPartImpl(this, inputstream, mimeHeaders);
+ if ("multipart/related".equals(contentType)) {
+ try {
+ Attachments attachments =
+ new Attachments(inputstream, tmpContentType, false, "", "");
+
+ // Axiom doesn't give us access to the MIME headers of the individual
+ // parts of the SOAP message package. We need to reconstruct them from
+ // the available information.
+ MimeHeaders soapPartHeaders = new MimeHeaders();
+ soapPartHeaders.addHeader(HTTPConstants.CONTENT_TYPE,
+ attachments.getSOAPPartContentType());
+ String soapPartContentId = attachments.getSOAPPartContentID();
+ soapPartHeaders.addHeader("Content-ID", "<" + soapPartContentId + ">");
+
+ soapPart = new SOAPPartImpl(this, attachments.getSOAPPartInputStream(),
+ soapPartHeaders, processMTOM ? attachments : null);
+
+ for (String contentId : attachments.getAllContentIDs()) {
+ if (!contentId.equals(soapPartContentId)) {
+ AttachmentPart ap =
+ createAttachmentPart(attachments.getDataHandler(contentId));
+ ap.setContentId("<" + contentId + ">");
+ attachmentParts.add(ap);
+ }
+ }
+ } catch (OMException e) {
+ throw new SOAPException(e);
+ }
} else {
- soapPart = new SOAPPartImpl(this, inputstream);
+ initCharsetEncodingFromContentType(tmpContentType);
+ soapPart = new SOAPPartImpl(this, inputstream, mimeHeaders, null);
}
this.mimeHeaders = (mimeHeaders == null) ?
Modified: webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPPartImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPPartImpl.java?rev=738086&r1=738085&r2=738086&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPPartImpl.java (original)
+++ webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPPartImpl.java Tue Jan 27 13:29:10 2009
@@ -29,7 +29,6 @@
import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
import org.apache.axiom.soap.impl.dom.soap11.SOAP11Factory;
import org.apache.axiom.soap.impl.dom.soap12.SOAP12Factory;
-import org.apache.axis2.builder.BuilderUtil;
import org.apache.axis2.saaj.util.IDGenerator;
import org.apache.axis2.saaj.util.SAAJUtil;
import org.apache.axis2.transport.http.HTTPConstants;
@@ -53,6 +52,8 @@
import org.w3c.dom.Text;
import org.w3c.dom.UserDataHandler;
+import javax.mail.internet.ContentType;
+import javax.mail.internet.ParseException;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
@@ -95,11 +96,26 @@
envelope.setSOAPPartParent(this);
}
- public SOAPPartImpl(SOAPMessageImpl parentSoapMsg,
- InputStream inputStream, javax.xml.soap.MimeHeaders mimeHeaders
- ) throws SOAPException {
- String contentType = "";
- String fullContentTypeStr = "";
+ /**
+ * Construct a SOAP part from the given input stream.
+ * The content type (as provided by the MIME headers) must be SOAP 1.1, SOAP 1.2
+ * or XOP (MTOM). MIME packages (multipart/related) are not supported and should be
+ * parsed using {@link SOAPMessageImpl#SOAPMessageImpl(InputStream, MimeHeaders).
+ * <p>
+ * If the content type is XOP, xop:Include elements will only be replaced if
+ * the <code>attachments</code> parameter is not null.
+ *
+ * @see MessageFactoryImpl#setProcessMTOM(boolean)
+ *
+ * @param parentSoapMsg the parent SOAP message
+ * @param inputStream the input stream with the content of the SOAP part
+ * @param mimeHeaders the MIME headers
+ * @param attachments the set of attachments to be used to substitute xop:Include elements
+ * @throws SOAPException
+ */
+ public SOAPPartImpl(SOAPMessageImpl parentSoapMsg, InputStream inputStream,
+ MimeHeaders mimeHeaders, Attachments attachments) throws SOAPException {
+ ContentType contentType = null;
if (mimeHeaders == null) {
//TODO : read string from constants
this.mimeHeaders = new MimeHeaders();
@@ -108,93 +124,78 @@
} else {
String contentTypes[] = mimeHeaders.getHeader(HTTPConstants.CONTENT_TYPE);
if (contentTypes != null && contentTypes.length > 0) {
- fullContentTypeStr = contentTypes[0];
- contentType = SAAJUtil.normalizeContentType(fullContentTypeStr);
+ try {
+ contentType = new ContentType(contentTypes[0]);
+ } catch (ParseException ex) {
+ throw new SOAPException("Invalid content type '" + contentTypes[0] + "'");
+ }
}
this.mimeHeaders = SAAJUtil.copyMimeHeaders(mimeHeaders);
}
soapMessage = parentSoapMsg;
- String knownEncoding = (String) soapMessage.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
- XMLStreamReader xmlReader = null;
-
-
- StAXSOAPModelBuilder builder = null;
-
- if (contentType.indexOf("multipart/related") == 0) {
- //This contains attachements
- try {
- Attachments attachments =
- new Attachments(inputStream, fullContentTypeStr, false, "", "");
-
- String soapEnvelopeNamespaceURI =
- BuilderUtil.getEnvelopeNamespace(fullContentTypeStr);
-
- String charSetEncoding =
- BuilderUtil.getCharSetEncoding(attachments.getSOAPPartContentType());
-
- XMLStreamReader streamReader =
- StAXUtils.createXMLStreamReader(BuilderUtil.getReader(
- attachments.getSOAPPartInputStream(), charSetEncoding));
-
- SOAPFactory factory;
- if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapEnvelopeNamespaceURI)) {
- factory = new SOAP11Factory();
- } else {
- factory = new SOAP12Factory();
- }
- if (attachments.getAttachmentSpecType().equals(
- MTOMConstants.MTOM_TYPE)) {
- //Creates the MTOM specific MTOMStAXSOAPModelBuilder
- builder = new MTOMStAXSOAPModelBuilder(streamReader,
- factory,
- attachments,
- soapEnvelopeNamespaceURI);
- } else if (attachments.getAttachmentSpecType().equals(
- MTOMConstants.SWA_TYPE)) {
- builder = new StAXSOAPModelBuilder(streamReader,
- factory,
- soapEnvelopeNamespaceURI);
- } else if (attachments.getAttachmentSpecType().equals(
- MTOMConstants.SWA_TYPE_12)) {
- builder = new StAXSOAPModelBuilder(streamReader,
- factory,
- soapEnvelopeNamespaceURI);
- }
-
- } catch (Exception e) {
- throw new SOAPException(e);
- }
+ String charset;
+ boolean isMTOM;
+ String soapEnvelopeNamespaceURI;
+ SOAPFactory soapFactory;
+ if (contentType == null) {
+ charset = null;
+ isMTOM = false;
+ soapFactory = new SOAP11Factory();
+ soapEnvelopeNamespaceURI = null;
} else {
- try {
- XMLStreamReader streamReader = null;
-
- if(knownEncoding != null){
- streamReader = StAXUtils.createXMLStreamReader(inputStream, knownEncoding);
- }else{
- streamReader = StAXUtils.createXMLStreamReader(inputStream);
- }
-
- if (HTTPConstants.MEDIA_TYPE_TEXT_XML.equals(contentType)) {
- builder = new StAXSOAPModelBuilder(streamReader,
- new SOAP11Factory(),
- SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
-
- } else if (HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML.equals(contentType)) {
- builder = new StAXSOAPModelBuilder(streamReader,
- new SOAP12Factory(),
- SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
-
+ String baseType = contentType.getBaseType().toLowerCase();
+ String soapContentType;
+ if (baseType.equals(MTOMConstants.MTOM_TYPE)) {
+ isMTOM = true;
+ String typeParam = contentType.getParameter("type");
+ if (typeParam == null) {
+ throw new SOAPException("Missing 'type' parameter in XOP content type");
} else {
- builder = new StAXSOAPModelBuilder(streamReader,
- new SOAP11Factory(),
- null);
+ soapContentType = typeParam.toLowerCase();
}
- } catch (XMLStreamException e) {
- throw new SOAPException(e);
+ } else {
+ isMTOM = false;
+ soapContentType = baseType;
}
+
+ if (soapContentType.equals(HTTPConstants.MEDIA_TYPE_TEXT_XML)) {
+ soapEnvelopeNamespaceURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
+ soapFactory = new SOAP11Factory();
+ } else if (soapContentType.equals(HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML)) {
+ soapEnvelopeNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
+ soapFactory = new SOAP12Factory();
+ } else {
+ throw new SOAPException("Unrecognized content type '" + soapContentType + "'");
+ }
+
+ charset = contentType.getParameter("charset");
+ }
+
+ XMLStreamReader streamReader;
+ try {
+ if (charset != null) {
+ streamReader = StAXUtils.createXMLStreamReader(inputStream, charset);
+ } else {
+ streamReader = StAXUtils.createXMLStreamReader(inputStream);
+ }
+ } catch (XMLStreamException e) {
+ throw new SOAPException(e);
}
+
+ StAXSOAPModelBuilder builder;
+ if (isMTOM && attachments != null) {
+ builder = new MTOMStAXSOAPModelBuilder(streamReader,
+ soapFactory,
+ attachments,
+ soapEnvelopeNamespaceURI);
+ } else {
+ builder = new StAXSOAPModelBuilder(streamReader,
+ soapFactory,
+ soapEnvelopeNamespaceURI);
+ }
+
try {
org.apache.axiom.soap.SOAPEnvelope soapEnvelope = builder.getSOAPEnvelope();
envelope = new SOAPEnvelopeImpl(
@@ -207,11 +208,6 @@
}
}
- public SOAPPartImpl(SOAPMessageImpl parentSoapMsg,
- InputStream inputStream) throws SOAPException {
- this(parentSoapMsg, inputStream, null);
- }
-
/**
* Obtain the SOAPMessage
*
Modified: webservices/axis2/trunk/java/modules/saaj/test-resources/message.bin
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/test-resources/message.bin?rev=738086&r1=738085&r2=738086&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/test-resources/message.bin (original)
+++ webservices/axis2/trunk/java/modules/saaj/test-resources/message.bin Tue Jan 27 13:29:10 2009
@@ -1,5 +1,5 @@
--MIMEBoundaryurn:uuid:F02ECC18873CFB73E211412748909307
-content-type: application/xop+xml; charset=UTF-8; type="text/xml";
+content-type: application/xop+xml; charset=UTF-8; type="text/xml"
content-transfer-encoding: binary
content-id: <0....@apache.org>
Modified: webservices/axis2/trunk/java/modules/saaj/test/org/apache/axis2/saaj/MessageFactoryTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/test/org/apache/axis2/saaj/MessageFactoryTest.java?rev=738086&r1=738085&r2=738086&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/test/org/apache/axis2/saaj/MessageFactoryTest.java (original)
+++ webservices/axis2/trunk/java/modules/saaj/test/org/apache/axis2/saaj/MessageFactoryTest.java Tue Jan 27 13:29:10 2009
@@ -24,10 +24,12 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.w3c.dom.Node;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
@@ -142,7 +144,7 @@
}
}
- @Validated @Test @Ignore("AXIS2-4189")
+ @Validated @Test
public void testParseMTOMMessage() throws Exception {
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type",
@@ -159,15 +161,27 @@
SOAPPart soapPart = message.getSOAPPart();
assertEquals("<0....@apache.org>",
soapPart.getContentId());
+
+ // Check the xop:Include element. Note that SAAJ doesn't resolve xop:Includes!
+ SOAPElement textElement =
+ (SOAPElement)soapPart.getEnvelope().getElementsByTagName("text").item(0);
+ assertNotNull(textElement);
+ Node xopIncludeNode = textElement.getChildNodes().item(0);
+ assertTrue(xopIncludeNode instanceof SOAPElement);
+ AttachmentPart ap = message.getAttachment((SOAPElement)xopIncludeNode);
+ assertEquals("<1....@apache.org>",
+ ap.getContentId());
+
+ // Now check the attachments
Iterator attachments = message.getAttachments();
assertTrue(attachments.hasNext());
- AttachmentPart ap = (AttachmentPart)attachments.next();
+ ap = (AttachmentPart)attachments.next();
assertEquals("<1....@apache.org>",
ap.getContentId());
assertFalse(attachments.hasNext());
}
- @Validated @Test @Ignore("AXIS2-4189")
+ @Validated @Test
public void testParseSwAMessage() throws Exception {
MimeHeaders headers = new MimeHeaders();
headers.addHeader("Content-Type",