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)");
         


Reply via email to