Author: veithen
Date: Sun Oct 5 14:59:49 2008
New Revision: 701893
URL: http://svn.apache.org/viewvc?rev=701893&view=rev
Log:
SYNAPSE-304: Modified the mail transport to use the message builder API. This
drastically increases the number of standard test cases that are successfully
passed by the transport. Note that SOAP with Attachments still doesn't work in
all cases because attachments are sent with "Content-Transfer-Encoding: binary"
and mail servers don't like that (This could be fixed by using the enhancement
introduced in WSCOMMONS-390).
Removed:
webservices/commons/trunk/modules/transport/modules/mail/src/main/java/org/apache/axis2/transport/mail/MailUtils.java
Modified:
webservices/commons/trunk/modules/transport/modules/mail/src/main/java/org/apache/axis2/transport/mail/MailTransportListener.java
webservices/commons/trunk/modules/transport/modules/tests/src/test/java/org/apache/axis2/transport/mail/MailTransportTest.java
Modified:
webservices/commons/trunk/modules/transport/modules/mail/src/main/java/org/apache/axis2/transport/mail/MailTransportListener.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/transport/modules/mail/src/main/java/org/apache/axis2/transport/mail/MailTransportListener.java?rev=701893&r1=701892&r2=701893&view=diff
==============================================================================
---
webservices/commons/trunk/modules/transport/modules/mail/src/main/java/org/apache/axis2/transport/mail/MailTransportListener.java
(original)
+++
webservices/commons/trunk/modules/transport/modules/mail/src/main/java/org/apache/axis2/transport/mail/MailTransportListener.java
Sun Oct 5 14:59:49 2008
@@ -19,6 +19,7 @@
package org.apache.axis2.transport.mail;
+import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
@@ -29,6 +30,8 @@
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.ParameterInclude;
import org.apache.axis2.description.TransportInDescription;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.transport.TransportUtils;
import org.apache.axis2.transport.base.AbstractPollingTransportListener;
import org.apache.axis2.transport.base.BaseConstants;
import org.apache.axis2.transport.base.BaseUtils;
@@ -41,13 +44,18 @@
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
+import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.AddressException;
+import javax.mail.internet.ContentType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.ParseException;
import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
@@ -257,21 +265,24 @@
// populate transport headers using the mail headers
Map trpHeaders = getTransportHeaders(message, entry);
- // figure out content type of primary request. If the content type is
specified, use it
- // FIXME: shouldn't the content type always be specified by the
message?
+ // Allow the content type to be overridden by configuration.
String contentType = entry.getContentType();
- if (BaseUtils.isBlank(contentType)) {
-
- Object content = message.getContent();
- if (content instanceof Multipart) {
- contentType = message.getContentType();
- } else if (content instanceof String) {
- contentType = message.getContentType();
- } else if (content instanceof InputStream) {
- contentType = MailConstants.APPLICATION_BINARY;
- }
+ Part messagePart;
+ if (contentType != null) {
+ messagePart = message;
+ } else {
+ messagePart = getMessagePart(message,
cfgCtx.getAxisConfiguration());
+ contentType = messagePart.getContentType();
}
-
+
+ // FIXME: remove this ugly hack when Axis2 has learned that content
types are case insensitive...
+ int idx = contentType.indexOf(';');
+ if (idx == -1) {
+ contentType = contentType.toLowerCase();
+ } else {
+ contentType = contentType.substring(0, idx).toLowerCase() +
contentType.substring(idx);
+ }
+
// if the content type was not found, we have an error
if (contentType == null) {
processFailure("Unable to determine Content-type for message : " +
@@ -283,6 +294,17 @@
MessageContext msgContext = createMessageContext(entry);
+ // Extract the charset encoding from the configured content type and
+ // set the CHARACTER_SET_ENCODING property as e.g. SOAPBuilder relies
on this.
+ String charSetEnc;
+ try {
+ charSetEnc = new ContentType(contentType).getParameter("charset");
+ } catch (ParseException ex) {
+ // ignore
+ charSetEnc = null;
+ }
+ msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING,
charSetEnc);
+
MailOutTransportInfo outInfo = buildOutTransportInfo(message, entry);
// save out transport information
@@ -299,24 +321,33 @@
msgContext.setMessageID(outInfo.getRequestMessageID());
// set the message payload to the message context
- MailUtils.getInstace().setSOAPEnvelope(message, msgContext,
contentType);
+ InputStream in = messagePart.getInputStream();
+ try {
+ try {
+
msgContext.setEnvelope(TransportUtils.createSOAPMessage(msgContext, in,
contentType));
+ } catch (XMLStreamException ex) {
+ handleException("Error parsing message", ex);
+ }
- String soapAction = (String) trpHeaders.get(BaseConstants.SOAPACTION);
- if (soapAction == null && message.getSubject() != null &&
- message.getSubject().startsWith(BaseConstants.SOAPACTION)) {
- soapAction =
message.getSubject().substring(BaseConstants.SOAPACTION.length());
- if (soapAction.startsWith(":")) {
- soapAction = soapAction.substring(1).trim();
+ String soapAction = (String)
trpHeaders.get(BaseConstants.SOAPACTION);
+ if (soapAction == null && message.getSubject() != null &&
+ message.getSubject().startsWith(BaseConstants.SOAPACTION)) {
+ soapAction =
message.getSubject().substring(BaseConstants.SOAPACTION.length());
+ if (soapAction.startsWith(":")) {
+ soapAction = soapAction.substring(1).trim();
+ }
}
+
+ handleIncomingMessage(
+ msgContext,
+ trpHeaders,
+ soapAction,
+ contentType
+ );
+ } finally {
+ in.close();
}
- handleIncomingMessage(
- msgContext,
- trpHeaders,
- soapAction,
- contentType
- );
-
if (log.isDebugEnabled()) {
log.debug("Processed message : " + message.getMessageNumber() +
" :: " + message.getSubject());
@@ -357,6 +388,47 @@
} catch (MessagingException ignore) {}
return trpHeaders;
}
+
+ /**
+ * Extract the part from the mail that contains the message to be
processed.
+ * This method supports multipart/mixed messages that contain a text/plain
+ * part alongside the message.
+ *
+ * @param message
+ * @return
+ * @throws MessagingException
+ * @throws IOException
+ */
+ private Part getMessagePart(Message message, AxisConfiguration axisCfg)
+ throws MessagingException, IOException {
+
+ ContentType contentType = new ContentType(message.getContentType());
+ if (contentType.getBaseType().equalsIgnoreCase("multipart/mixed")) {
+ Multipart multipart = (Multipart)message.getContent();
+ Part textMainPart = null;
+ for (int i=0; i<multipart.getCount(); i++) {
+ MimeBodyPart bodyPart = (MimeBodyPart)multipart.getBodyPart(i);
+ ContentType partContentType = new
ContentType(bodyPart.getContentType());
+ if (axisCfg.getMessageBuilder(partContentType.getBaseType())
!= null) {
+ if
(partContentType.getBaseType().equalsIgnoreCase("text/plain")) {
+ // If it's a text/plain part, remember it. We will
return
+ // it later if we don't find something more
interesting.
+ textMainPart = bodyPart;
+ } else {
+ return bodyPart;
+ }
+ }
+ }
+ if (textMainPart != null) {
+ return textMainPart;
+ } else {
+ // We have nothing else to return!
+ return message;
+ }
+ } else {
+ return message;
+ }
+ }
// TODO: the same code is used by other transports; the method should be
moved to Abstract(Polling)TransportListener
private MessageContext createMessageContext(PollTableEntry entry) throws
AxisFault {
Modified:
webservices/commons/trunk/modules/transport/modules/tests/src/test/java/org/apache/axis2/transport/mail/MailTransportTest.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/transport/modules/tests/src/test/java/org/apache/axis2/transport/mail/MailTransportTest.java?rev=701893&r1=701892&r2=701893&view=diff
==============================================================================
---
webservices/commons/trunk/modules/transport/modules/tests/src/test/java/org/apache/axis2/transport/mail/MailTransportTest.java
(original)
+++
webservices/commons/trunk/modules/transport/modules/tests/src/test/java/org/apache/axis2/transport/mail/MailTransportTest.java
Sun Oct 5 14:59:49 2008
@@ -34,15 +34,13 @@
public static TestSuite suite() throws Exception {
TransportTestSuite suite = new
TransportTestSuite(MailTransportTest.class);
- // TODO: these test don't work; need more analysis why this is so
- suite.addExclude("(&(messageType=SOAP12)(data=Latin1))");
- suite.addExclude("(&(messageType=POX)(data=Latin1))");
- suite.addExclude("(&(layout=multipart)(data=Latin1))");
- suite.addExclude("(&(layout=multipart)(messageType=POX))");
+ // SwA doesn't work because attachments are sent with
"Content-Transfer-Encoding: binary"
+ // and mail servers don't like that.
+ // TODO: this could be fixed with the enhancement introduced by
WSCOMMONS-390
suite.addExclude("(test=AsyncSwA)");
- suite.addExclude("(test=AsyncBinary)");
- suite.addExclude("(&(test=AsyncTextPlain)(!(data=ASCII)))");
- suite.addExclude("(&(test=EchoXML)(messageType=SOAP12))");
+ // There seems to be a problem with Sun's IMAP client or GreenMail's
IMAP server
+ // in this particular case:
+
suite.addExclude("(&(protocol=imap)(|(test=AsyncSwA)(&(test=EchoXML)(messageType=SOAP12))))");
// SYNAPSE-434
suite.addExclude("(test=MinConcurrency)");