You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2009/05/14 08:46:08 UTC
svn commit: r774657 - in /camel/trunk/components/camel-mail/src:
main/java/org/apache/camel/component/mail/
test/java/org/apache/camel/component/mail/ test/resources/
Author: davsclaus
Date: Thu May 14 06:46:07 2009
New Revision: 774657
URL: http://svn.apache.org/viewvc?rev=774657&view=rev
Log:
MR-173: Added TRACE logging to camel-mail and option for ContentTypeResolver to work around bugs in geronimo mail jar.
Added:
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java (with props)
camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailContentTypeResolverTest.java
- copied, changed from r774627, camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentTest.java
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/MailComponent.java
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailMessage.java
camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailSubjectTest.java
camel/trunk/components/camel-mail/src/test/resources/log4j.properties
Added: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java?rev=774657&view=auto
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java (added)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java Thu May 14 06:46:07 2009
@@ -0,0 +1,45 @@
+/**
+ * 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;
+
+/**
+ * Resolver to determine Content-Type for file attachments.
+ * <p/>
+ * Strategy introduced to work around mail providers having problems with this such as geronimo mail jars.
+ * <p/>
+ * Note using SUN mail jar have no problem with resolving Content-Type based on file attachments. This resolver
+ * is thus only needed to work around mail providers having bugs or when you a new mime type is unknown by the
+ * mail provider allowing you to deterime it.
+ *
+ * @version $Revision$
+ */
+public interface ContentTypeResolver {
+
+ /**
+ * Resolves the mime content-type based on the attachment file name.
+ * <p/>
+ * Return <tt>null</tt> if you cannot resolve a content type or want to rely on the mail provider
+ * to resolve it for you.
+ * <p/>
+ * The returned value should only be the mime part of the ContentType header, for example:
+ * <tt>image/jpeg</tt> should be returned. Camel will add the remaining <tt>; name=FILENAME</tt>.
+ *
+ * @param fileName the attachment file nane
+ * @return the Content-Type or <tt>null</tt> to rely on the mail provider
+ */
+ public String resolveContentType(String fileName);
+}
Propchange: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/ContentTypeResolver.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=774657&r1=774656&r2=774657&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 Thu May 14 06:46:07 2009
@@ -43,6 +43,8 @@
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.util.CollectionHelper;
import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* A Strategy used to convert between a Camel {@link Exchange} and {@link Message} to and
@@ -52,14 +54,17 @@
*/
public class MailBinding {
+ private static final transient Log LOG = LogFactory.getLog(MailBinding.class);
private HeaderFilterStrategy headerFilterStrategy;
+ private ContentTypeResolver contentTypeResolver;
public MailBinding() {
headerFilterStrategy = new DefaultHeaderFilterStrategy();
}
- public MailBinding(HeaderFilterStrategy headerFilterStrategy) {
+ public MailBinding(HeaderFilterStrategy headerFilterStrategy, ContentTypeResolver contentTypeResolver) {
this.headerFilterStrategy = headerFilterStrategy;
+ this.contentTypeResolver = contentTypeResolver;
}
public void populateMailMessage(MailEndpoint endpoint, MimeMessage mimeMessage, Exchange exchange)
@@ -152,7 +157,7 @@
}
private void setRecipientFromCamelMessage(MimeMessage mimeMessage, Exchange exchange,
- org.apache.camel.Message camelMessage)
+ org.apache.camel.Message camelMessage)
throws MessagingException {
for (Map.Entry<String, Object> entry : camelMessage.getHeaders().entrySet()) {
@@ -208,34 +213,63 @@
multipart.setSubType("mixed");
addBodyToMultipart(camelMessage, configuration, multipart);
String partDisposition = configuration.isUseInlineAttachments() ? Part.INLINE : Part.ATTACHMENT;
- addAttachmentsToMultipart(camelMessage, multipart, partDisposition);
+ if (camelMessage.hasAttachments()) {
+ addAttachmentsToMultipart(camelMessage, multipart, partDisposition);
+ }
return multipart;
}
protected void addAttachmentsToMultipart(org.apache.camel.Message camelMessage, MimeMultipart multipart, String partDisposition) throws MessagingException {
+ LOG.trace("Adding attachments +++ start +++");
+ int i = 0;
for (Map.Entry<String, DataHandler> entry : camelMessage.getAttachments().entrySet()) {
String attachmentFilename = entry.getKey();
DataHandler handler = entry.getValue();
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Attachment #" + i + ": Disposition: " + partDisposition);
+ LOG.trace("Attachment #" + i + ": DataHandler: " + handler);
+ LOG.trace("Attachment #" + i + ": FileName: " + attachmentFilename);
+ }
if (handler != null) {
- if (shouldOutputAttachment(camelMessage, attachmentFilename, handler)) {
+ if (shouldAddAttachment(camelMessage, attachmentFilename, handler)) {
// Create another body part
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
+ // add a Content-ID header to the attachment
messageBodyPart.addHeader("Content-ID", attachmentFilename.substring(4));
}
+
// Set the filename
messageBodyPart.setFileName(attachmentFilename);
+ LOG.trace("Attachment #" + i + ": ContentType: " + messageBodyPart.getContentType());
+
+ if (contentTypeResolver != null) {
+ String contentType = contentTypeResolver.resolveContentType(attachmentFilename);
+ LOG.trace("Attachment #" + i + ": Using content type resolver: " + contentTypeResolver + " resolved content type as: " + contentType);
+ if (contentType != null) {
+ String value = contentType + "; name=" + attachmentFilename;
+ messageBodyPart.setHeader("Content-Type", value);
+ LOG.trace("Attachment #" + i + ": ContentType: " + messageBodyPart.getContentType());
+ }
+ }
+
// Set Disposition
messageBodyPart.setDisposition(partDisposition);
// Add part to multipart
multipart.addBodyPart(messageBodyPart);
+ } else {
+ LOG.trace("shouldAddAttachment: false");
}
+ } else {
+ LOG.warn("Cannot add attachment: " + attachmentFilename + " as DataHandler is null");
}
+ i++;
}
+ LOG.trace("Adding attachments +++ done +++");
}
protected void createMultipartAlternativeMessage(MimeMessage mimeMessage, org.apache.camel.Message camelMessage, MailConfiguration configuration)
@@ -281,11 +315,10 @@
activeMultipart.addBodyPart(bodyMessage);
}
-
/**
- * Strategy to allow filtering of attachments which are put on the Mail message
+ * Strategy to allow filtering of attachments which are added on the Mail message
*/
- protected boolean shouldOutputAttachment(org.apache.camel.Message camelMessage, String attachmentFilename, DataHandler handler) {
+ protected boolean shouldAddAttachment(org.apache.camel.Message camelMessage, String attachmentFilename, DataHandler handler) {
return true;
}
Modified: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailComponent.java?rev=774657&r1=774656&r2=774657&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailComponent.java (original)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailComponent.java Thu May 14 06:46:07 2009
@@ -33,6 +33,7 @@
*/
public class MailComponent extends DefaultComponent {
private MailConfiguration configuration;
+ private ContentTypeResolver contentTypeResolver;
public MailComponent() {
this.configuration = new MailConfiguration();
@@ -63,6 +64,7 @@
configureAdditionalJavaMailProperties(config, parameters);
MailEndpoint endpoint = new MailEndpoint(uri, this, config);
+ endpoint.setContentTypeResolver(contentTypeResolver);
setProperties(endpoint.getConfiguration(), parameters);
// sanity check that we know the mail server
@@ -112,4 +114,11 @@
return path;
}
+ public ContentTypeResolver getContentTypeResolver() {
+ return contentTypeResolver;
+ }
+
+ public void setContentTypeResolver(ContentTypeResolver contentTypeResolver) {
+ this.contentTypeResolver = contentTypeResolver;
+ }
}
Modified: camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java?rev=774657&r1=774656&r2=774657&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java (original)
+++ camel/trunk/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java Thu May 14 06:46:07 2009
@@ -38,6 +38,7 @@
private MailBinding binding;
private MailConfiguration configuration;
private HeaderFilterStrategy headerFilterStrategy = new DefaultHeaderFilterStrategy();
+ private ContentTypeResolver contentTypeResolver;
public MailEndpoint() {
}
@@ -111,7 +112,7 @@
public MailBinding getBinding() {
if (binding == null) {
- binding = new MailBinding(headerFilterStrategy);
+ binding = new MailBinding(headerFilterStrategy, contentTypeResolver);
}
return binding;
}
@@ -139,4 +140,11 @@
this.headerFilterStrategy = headerFilterStrategy;
}
+ public ContentTypeResolver getContentTypeResolver() {
+ return contentTypeResolver;
+ }
+
+ public void setContentTypeResolver(ContentTypeResolver contentTypeResolver) {
+ this.contentTypeResolver = contentTypeResolver;
+ }
}
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=774657&r1=774656&r2=774657&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 Thu May 14 06:46:07 2009
@@ -28,6 +28,8 @@
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.impl.DefaultMessage;
import org.apache.camel.util.CollectionHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* Represents a {@link org.apache.camel.Message} for working with Mail
@@ -35,6 +37,7 @@
* @version $Revision:520964 $
*/
public class MailMessage extends DefaultMessage {
+ private static final transient Log LOG = LogFactory.getLog(MailMessage.class);
private Message mailMessage;
public MailMessage() {
@@ -138,29 +141,46 @@
protected static void extractAttachments(Message message, Map<String, DataHandler> map)
throws javax.mail.MessagingException, IOException {
+ LOG.trace("Extracting attachments +++ start +++");
+
Object content = message.getContent();
if (content instanceof Multipart) {
extractFromMultipart((Multipart)content, map);
+ } else if (content != null) {
+ LOG.trace("No attachments to extract as content is not Multipart: " + content.getClass().getName());
}
+
+ LOG.trace("Extracting attachments +++ done +++");
}
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);
+ Part part = mp.getBodyPart(i);
+ LOG.trace("Part #" + i + ": " + part);
+
if (part.isMimeType("multipart/*")) {
+ LOG.trace("Part #" + i + ": is mimetype: 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
- CollectionHelper.appendValue(map, part.getFileName(), part.getDataHandler());
- }
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Part #" + i + ": Disposition: " + part.getDisposition());
+ LOG.trace("Part #" + i + ": Description: " + part.getDescription());
+ LOG.trace("Part #" + i + ": ContentType: " + part.getContentType());
+ LOG.trace("Part #" + i + ": FileName: " + part.getFileName());
+ LOG.trace("Part #" + i + ": Size: " + part.getSize());
+ LOG.trace("Part #" + i + ": LineCount: " + part.getLineCount());
+ }
+
+ if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {
+ // only add named attachments
+ String fileName = part.getFileName();
+ if (fileName != null) {
+ LOG.debug("Mail contains file attachment: " + fileName);
+ // Parts marked with a disposition of Part.ATTACHMENT are clearly attachments
+ CollectionHelper.appendValue(map, fileName, part.getDataHandler());
}
}
}
Copied: camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailContentTypeResolverTest.java (from r774627, camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailContentTypeResolverTest.java?p2=camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailContentTypeResolverTest.java&p1=camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentTest.java&r1=774627&r2=774657&rev=774657&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentTest.java (original)
+++ camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailContentTypeResolverTest.java Thu May 14 06:46:07 2009
@@ -17,7 +17,6 @@
package org.apache.camel.component.mail;
import java.util.Map;
-
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
@@ -32,11 +31,9 @@
/**
* Unit test for Camel attachments and Mail attachments.
*/
-public class MailAttachmentTest extends ContextTestSupport {
-
- public void testSendAndRecieveMailWithAttachments() throws Exception {
- // START SNIPPET: e1
+public class MailContentTypeResolverTest extends ContextTestSupport {
+ public void testCustomContentTypeResolver() throws Exception {
// create an exchange with a normal body and attachment to be produced as email
Endpoint endpoint = context.getEndpoint("smtp://james@mymailserver.com?password=secret");
@@ -53,8 +50,6 @@
// 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);
@@ -74,8 +69,8 @@
DataHandler handler = out.getIn().getAttachment("logo.jpeg");
assertNotNull("The logo should be there", handler);
- // TODO: content type does not work with geronomi mail jar (its a buggy jar, use SUN mail jar instead)
- // assertEquals("image/jpeg; name=logo.jpeg", handler.getContentType());
+ // as we use a custom content type resolver the content type should then be fixed and correct
+ assertEquals("image/jpeg; name=logo.jpeg", handler.getContentType());
producer.stop();
}
@@ -83,8 +78,15 @@
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() throws Exception {
+ MailComponent mail = getContext().getComponent("smtp", MailComponent.class);
+ mail.setContentTypeResolver(new ContentTypeResolver() {
+ public String resolveContentType(String fileName) {
+ return "image/jpeg";
+ }
+ });
+
from("pop3://james@mymailserver.com?password=secret&consumer.delay=1000").to("mock:result");
}
};
}
-}
+}
\ No newline at end of file
Modified: camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailSubjectTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailSubjectTest.java?rev=774657&r1=774656&r2=774657&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailSubjectTest.java (original)
+++ camel/trunk/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailSubjectTest.java Thu May 14 06:46:07 2009
@@ -40,6 +40,8 @@
template.sendBody("direct:a", body);
mock.assertIsSatisfied();
+
+ assertFalse("Should not have attachements", mock.getExchanges().get(0).getIn().hasAttachments());
}
protected RouteBuilder createRouteBuilder() throws Exception {
Modified: camel/trunk/components/camel-mail/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-mail/src/test/resources/log4j.properties?rev=774657&r1=774656&r2=774657&view=diff
==============================================================================
--- camel/trunk/components/camel-mail/src/test/resources/log4j.properties (original)
+++ camel/trunk/components/camel-mail/src/test/resources/log4j.properties Thu May 14 06:46:07 2009
@@ -32,4 +32,4 @@
log4j.appender.file.file=target/camel-mail-test.log
# debug logging for Camel
-log4j.logger.org.apache.camel.component.mail=DEBUG
\ No newline at end of file
+log4j.logger.org.apache.camel.component.mail=TRACE
\ No newline at end of file