You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2009/04/01 17:00:23 UTC
svn commit: r760909 - in /camel/trunk/components/camel-mail/src:
main/java/org/apache/camel/component/mail/
test/java/org/apache/camel/component/mail/
Author: ningjiang
Date: Wed Apr 1 15:00:20 2009
New Revision: 760909
URL: http://svn.apache.org/viewvc?rev=760909&view=rev
Log:
CAMEL-1506 CAMEL-1507 Applied patch with thanks to Ryan
Added:
camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java (with props)
Modified:
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailMessage.java
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailUtils.java
Modified: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java?rev=760909&r1=760908&r2=760909&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java (original)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java Wed Apr 1 15:00:20 2009
@@ -87,15 +87,20 @@
mimeMessage.setFrom(new InternetAddress(from));
}
- if (exchange.getIn().hasAttachments()) {
- appendAttachmentsFromCamel(mimeMessage, exchange.getIn(), endpoint.getConfiguration());
+ // if there is an alternativebody provided, set up a mime multipart alternative message
+ if (hasAlternativeBody(endpoint.getConfiguration(), exchange.getIn())) {
+ createMultipartAlternativeMessage(mimeMessage, exchange.getIn(), endpoint.getConfiguration());
} else {
- if ("text/html".equals(endpoint.getConfiguration().getContentType())) {
- DataSource ds = new ByteArrayDataSource(exchange.getIn().getBody(String.class), "text/html");
- mimeMessage.setDataHandler(new DataHandler(ds));
+ if (exchange.getIn().hasAttachments()) {
+ appendAttachmentsFromCamel(mimeMessage, exchange.getIn(), endpoint.getConfiguration());
} else {
- // its just text/plain
- mimeMessage.setText(exchange.getIn().getBody(String.class));
+ if ("text/html".equals(endpoint.getConfiguration().getContentType())) {
+ DataSource ds = new ByteArrayDataSource(exchange.getIn().getBody(String.class), "text/html");
+ mimeMessage.setDataHandler(new DataHandler(ds));
+ } else {
+ // its just text/plain
+ mimeMessage.setText(exchange.getIn().getBody(String.class));
+ }
}
}
}
@@ -192,16 +197,22 @@
protected void appendAttachmentsFromCamel(MimeMessage mimeMessage, org.apache.camel.Message camelMessage,
MailConfiguration configuration)
throws MessagingException {
+
+ // Put parts in message
+ mimeMessage.setContent(createMixedMultipartAttachments(camelMessage, configuration));
+ }
- // Create a Multipart
- MimeMultipart multipart = new MimeMultipart();
-
+ private MimeMultipart createMixedMultipartAttachments(org.apache.camel.Message camelMessage, MailConfiguration configuration) throws MessagingException {
// fill the body with text
+ MimeMultipart multipart = new MimeMultipart();
multipart.setSubType("mixed");
- MimeBodyPart textBodyPart = new MimeBodyPart();
- textBodyPart.setContent(camelMessage.getBody(String.class), configuration.getContentType());
- multipart.addBodyPart(textBodyPart);
+ addBodyToMultipart(camelMessage, configuration, multipart);
+ String partDisposition = configuration.isUseInlineAttachments() ? Part.INLINE : Part.ATTACHMENT;
+ addAttachmentsToMultipart(camelMessage, multipart, partDisposition);
+ return multipart;
+ }
+ protected void addAttachmentsToMultipart(org.apache.camel.Message camelMessage, MimeMultipart multipart, String partDisposition) throws MessagingException {
for (Map.Entry<String, DataHandler> entry : camelMessage.getAttachments().entrySet()) {
String attachmentFilename = entry.getKey();
DataHandler handler = entry.getValue();
@@ -211,20 +222,66 @@
BodyPart messageBodyPart = new MimeBodyPart();
// Set the data handler to the attachment
messageBodyPart.setDataHandler(handler);
+
+ if (attachmentFilename.toLowerCase().startsWith("cid:")) {
+ // add a Content-ID header to the attachment
+ messageBodyPart.addHeader("Content-ID", attachmentFilename.substring(4));
+ }
// Set the filename
messageBodyPart.setFileName(attachmentFilename);
// Set Disposition
- messageBodyPart.setDisposition(Part.ATTACHMENT);
+ messageBodyPart.setDisposition(partDisposition);
// Add part to multipart
multipart.addBodyPart(messageBodyPart);
}
}
}
+ }
+
+ protected void createMultipartAlternativeMessage(MimeMessage mimeMessage, org.apache.camel.Message camelMessage, MailConfiguration configuration)
+ throws MessagingException {
+
+ MimeMultipart multipartAlternative = new MimeMultipart("alternative");
+ mimeMessage.setContent(multipartAlternative);
+
+ BodyPart plainText = new MimeBodyPart();
+ plainText.setText(getAlternativeBody(configuration, camelMessage));
+ multipartAlternative.addBodyPart(plainText);
+
+ // if there are no attachments, add the body to the same mulitpart message
+ if (!camelMessage.hasAttachments()) {
+ addBodyToMultipart(camelMessage, configuration, multipartAlternative);
+ } else {
+ // if there are attachments, but they aren't set to be inline, add them to
+ // treat them as normal. It will append a multipart-mixed with the attachments and the
+ // body text
+ if (!configuration.isUseInlineAttachments()) {
+ BodyPart mixedAttachments = new MimeBodyPart();
+ mixedAttachments.setContent(createMixedMultipartAttachments(camelMessage, configuration));
+ multipartAlternative.addBodyPart(mixedAttachments);
+ //appendAttachmentsFromCamel(mimeMessage, camelMessage, configuration);
+ } else { // if the attachments are set to be inline, attach them as inline attachments
+ MimeMultipart multipartRelated = new MimeMultipart("related");
+ BodyPart related = new MimeBodyPart();
+
+ related.setContent(multipartRelated);
+ multipartAlternative.addBodyPart(related);
+
+ addBodyToMultipart(camelMessage, configuration, multipartRelated);
+
+ addAttachmentsToMultipart(camelMessage, multipartRelated, Part.INLINE);
+ }
+ }
- // Put parts in message
- mimeMessage.setContent(multipart);
}
+ protected void addBodyToMultipart(org.apache.camel.Message camelMessage, MailConfiguration configuration, MimeMultipart activeMultipart) throws MessagingException {
+ BodyPart bodyMessage = new MimeBodyPart();
+ bodyMessage.setContent(camelMessage.getBody(String.class), configuration.getContentType());
+ activeMultipart.addBodyPart(bodyMessage);
+ }
+
+
/**
* Strategy to allow filtering of attachments which are put on the Mail message
*/
@@ -276,6 +333,15 @@
return false;
}
+ protected static boolean hasAlternativeBody(MailConfiguration configuration, org.apache.camel.Message camelMessage) {
+ return getAlternativeBody(configuration, camelMessage) != null;
+ }
+
+ protected static String getAlternativeBody(MailConfiguration configuration, org.apache.camel.Message camelMessage) {
+ String alternativeBodyHeader = configuration.getAlternateBodyHeader();
+ return camelMessage.getHeader(alternativeBodyHeader, java.lang.String.class);
+ }
+
/**
* Is the given key a mime message recipient header (To, CC or BCC)
*/
Modified: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java?rev=760909&r1=760908&r2=760909&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java (original)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java Wed Apr 1 15:00:20 2009
@@ -37,6 +37,7 @@
public static final String DEFAULT_FOLDER_NAME = "INBOX";
public static final String DEFAULT_FROM = "camel@localhost";
+ public static final String DEFAULT_ALTERNATE_BODY_HEADER = "mail_alternateBody";
public static final long DEFAULT_CONNECTION_TIMEOUT = 30000L;
private Properties javaMailProperties;
@@ -59,6 +60,8 @@
private long connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
private boolean dummyTrustManager;
private String contentType = "text/plain";
+ private String alternateBodyHeader = DEFAULT_ALTERNATE_BODY_HEADER;
+ private boolean useInlineAttachments;
public MailConfiguration() {
}
@@ -409,4 +412,20 @@
public void setContentType(String contentType) {
this.contentType = contentType;
}
+
+ public String getAlternateBodyHeader() {
+ return alternateBodyHeader;
+ }
+
+ public void setAlternateBodyHeader(String alternateBodyHeader) {
+ this.alternateBodyHeader = alternateBodyHeader;
+ }
+
+ public boolean isUseInlineAttachments() {
+ return useInlineAttachments;
+ }
+
+ public void setUseInlineAttachments(boolean useInlineAttachments) {
+ this.useInlineAttachments = useInlineAttachments;
+ }
}
Modified: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailMessage.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailMessage.java?rev=760909&r1=760908&r2=760909&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailMessage.java (original)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailMessage.java Wed Apr 1 15:00:20 2009
@@ -140,22 +140,31 @@
Object content = message.getContent();
if (content instanceof Multipart) {
- // mail with attachment
- Multipart mp = (Multipart)content;
- for (int i = 0; i < mp.getCount(); i++) {
- Part part = mp.getBodyPart(i);
+ extractFromMultipart((Multipart)content, map);
+ }
+ }
+
+ protected static void extractFromMultipart(Multipart mp, Map<String, DataHandler> map)
+ throws javax.mail.MessagingException, IOException {
+
+ for (int i = 0; i < mp.getCount(); i++) {
+ Part part = mp.getBodyPart(i);
+ if (part.isMimeType("multipart/*")) {
+ extractFromMultipart((Multipart)part.getContent(), map);
+ } else {
String disposition = part.getDisposition();
if (disposition != null) {
if (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE)) {
// only add named attachments
if (part.getFileName() != null) {
- // Parts marked with a disposition of Part.ATTACHMENT are clearly attachments
+ // Parts marked with a disposition of Part.ATTACHMENT
+ // are clearly attachments
CollectionHelper.appendValue(map, part.getFileName(), part.getDataHandler());
}
}
}
}
}
- }
+ }
}
Modified: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailUtils.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailUtils.java?rev=760909&r1=760908&r2=760909&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailUtils.java (original)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailUtils.java Wed Apr 1 15:00:20 2009
@@ -135,4 +135,5 @@
}
+
}
Added: camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java?rev=760909&view=auto
==============================================================================
--- camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java (added)
+++ camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java Wed Apr 1 15:00:20 2009
@@ -0,0 +1,148 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.mail;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Producer;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+
+
+public class MimeMultipartAlternativeTest extends ContextTestSupport {
+ private String alternativeBody = "hello world! (plain text)";
+ private String htmlBody = "<html><body><h1>Hello</h1>World<img src=\"cid:0001\"></body></html>";
+
+ public void testMultipartEmailWithInlineAttachments() throws Exception {
+ // START SNIPPET: e1
+
+ // create an exchange with a normal body and attachment to be produced as email
+ MailEndpoint endpoint = context.getEndpoint("smtp://ryan@mymailserver.com?password=secret", MailEndpoint.class);
+ endpoint.getConfiguration().setUseInlineAttachments(true);
+ endpoint.getConfiguration().setAlternateBodyHeader(MailConfiguration.DEFAULT_ALTERNATE_BODY_HEADER);
+
+ // create the exchange with the mail message that is multipart with a file and a Hello World text/plain message.
+ Exchange exchange = endpoint.createExchange();
+ Message in = exchange.getIn();
+ in.setBody(htmlBody);
+ in.setHeader("mail_alternateBody", alternativeBody);
+ in.addAttachment("cid:0001", new DataHandler(new FileDataSource("src/test/data/logo.jpeg")));
+
+ // create a producer that can produce the exchange (= send the mail)
+ Producer producer = endpoint.createProducer();
+ // start the producer
+ producer.start();
+ // and let it go (processes the exchange by sending the email)
+ producer.process(exchange);
+
+ // END SNIPPET: e1
+
+ // need some time for the mail to arrive on the inbox (consumed and sent to the mock)
+ Thread.sleep(1000);
+
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedMessageCount(1);
+ Exchange out = mock.assertExchangeReceived(0);
+ mock.assertIsSatisfied();
+
+ if (log.isTraceEnabled()) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(((MailMessage)out.getIn()).getMessage().getSize());
+ ((MailMessage)out.getIn()).getMessage().writeTo(baos);
+ String dumpedMessage = baos.toString();
+ log.trace("multipart alternative: \n" + dumpedMessage);
+ }
+
+ // plain text
+ assertEquals(alternativeBody, out.getIn().getBody(String.class));
+
+ // attachment
+ Map<String, DataHandler> attachments = out.getIn().getAttachments();
+ assertNotNull("Should not have null attachments", attachments);
+ assertEquals(1, attachments.size());
+ assertEquals("multipart body should have 2 parts", 2, out.getIn().getBody(MimeMultipart.class).getCount());
+
+ producer.stop();
+ }
+
+ public void testMultipartEmailWithRegularAttachments() throws Exception {
+ // START SNIPPET: e1
+
+ // create an exchange with a normal body and attachment to be produced as email
+ MailEndpoint endpoint = context.getEndpoint("smtp://ryan@mymailserver.com?password=secret", MailEndpoint.class);
+ endpoint.getConfiguration().setUseInlineAttachments(false);
+ endpoint.getConfiguration().setAlternateBodyHeader(MailConfiguration.DEFAULT_ALTERNATE_BODY_HEADER);
+
+ // create the exchange with the mail message that is multipart with a file and a Hello World text/plain message.
+ Exchange exchange = endpoint.createExchange();
+ Message in = exchange.getIn();
+ in.setBody(htmlBody);
+ in.setHeader("mail_alternateBody", alternativeBody);
+ in.setHeader("sendInlineAttachments", false);
+ in.addAttachment("cid:0001", new DataHandler(new FileDataSource("src/test/data/logo.jpeg")));
+
+ // create a producer that can produce the exchange (= send the mail)
+ Producer producer = endpoint.createProducer();
+ // start the producer
+ producer.start();
+ // and let it go (processes the exchange by sending the email)
+ producer.process(exchange);
+
+ // END SNIPPET: e1
+
+ // need some time for the mail to arrive on the inbox (consumed and sent to the mock)
+ Thread.sleep(1000);
+
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedMessageCount(1);
+ Exchange out = mock.assertExchangeReceived(0);
+ mock.assertIsSatisfied();
+
+ if (log.isTraceEnabled()) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(((MailMessage)out.getIn()).getMessage().getSize());
+ ((MailMessage)out.getIn()).getMessage().writeTo(baos);
+ String dumpedMessage = baos.toString();
+ log.trace("multipart alternative: \n" + dumpedMessage);
+ }
+
+ // plain text
+ assertEquals(alternativeBody, out.getIn().getBody(String.class));
+
+ // attachment
+ Map<String, DataHandler> attachments = out.getIn().getAttachments();
+ assertNotNull("Should not have null attachments", attachments);
+ assertEquals(1, attachments.size());
+ assertEquals("multipart body should have 2 parts", 2, out.getIn().getBody(MimeMultipart.class).getCount());
+
+ producer.stop();
+ }
+
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() throws Exception {
+ from("pop3://ryan@mymailserver.com?password=secret&consumer.delay=1000").to("mock:result");
+ }
+ };
+ }
+}
Propchange: camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MimeMultipartAlternativeTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date