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 2016/01/28 11:38:00 UTC

camel git commit: CAMEL-9544. Option to add headers to MIME-Multipart in DataFormat. Thanks to Stephan Siano for the patch.

Repository: camel
Updated Branches:
  refs/heads/master 740a5a73c -> 1044ce5fc


CAMEL-9544. Option to add headers to MIME-Multipart in DataFormat. Thanks to Stephan Siano for the patch.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1044ce5f
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1044ce5f
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1044ce5f

Branch: refs/heads/master
Commit: 1044ce5fc39c4cb51d8465f8218bda466f2703a1
Parents: 740a5a7
Author: Claus Ibsen <da...@apache.org>
Authored: Thu Jan 28 11:37:53 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Jan 28 11:37:53 2016 +0100

----------------------------------------------------------------------
 .../apache/camel/builder/DataFormatClause.java  | 24 ++++++++++++++
 .../dataformat/MimeMultipartDataFormat.java     | 19 +++++++++++
 .../mime/multipart/MimeMultipartDataFormat.java | 28 +++++++++++++++++
 .../multipart/MimeMultipartDataFormatTest.java  | 33 ++++++++++++++++++++
 4 files changed, 104 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/1044ce5f/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java b/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
index d9fd05b..de2a7c1 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DataFormatClause.java
@@ -324,6 +324,30 @@ public class DataFormatClause<T extends ProcessorDefinition<?>> {
     /**
      * Uses the MIME Multipart data format
      *
+     * @param multipartSubType           the subtype of the MIME Multipart
+     * @param multipartWithoutAttachment defines whether a message without attachment is also marshaled
+     *                                   into a MIME Multipart (with only one body part).
+     * @param headersInline              define the MIME Multipart headers as part of the message body
+     *                                   or as Camel headers
+     * @param includeHeadeers            if headersInline is set to true all camel headers matching this
+     *                                   regex are also stored as MIME headers on the Multipart
+     * @param binaryContent              have binary encoding for binary content (true) or use Base-64
+     *                                   encoding for binary content (false)
+     */
+    public T mimeMultipart(String multipartSubType, boolean multipartWithoutAttachment, boolean headersInline,
+                           String includeHeaders, boolean binaryContent) {
+        MimeMultipartDataFormat mm = new MimeMultipartDataFormat();
+        mm.setMultipartSubType(multipartSubType);
+        mm.setMultipartWithoutAttachment(multipartWithoutAttachment);
+        mm.setHeadersInline(headersInline);
+        mm.setIncludeHeaders(includeHeaders);
+        mm.setBinaryContent(binaryContent);
+        return dataFormat(mm);
+    }
+
+    /**
+     * Uses the MIME Multipart data format
+     *
      * @param multipartWithoutAttachment defines whether a message without attachment is also marshaled
      *                                   into a MIME Multipart (with only one body part).
      * @param headersInline              define the MIME Multipart headers as part of the message body

http://git-wip-us.apache.org/repos/asf/camel/blob/1044ce5f/camel-core/src/main/java/org/apache/camel/model/dataformat/MimeMultipartDataFormat.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/MimeMultipartDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/MimeMultipartDataFormat.java
index 7116f39..535fd91 100644
--- a/camel-core/src/main/java/org/apache/camel/model/dataformat/MimeMultipartDataFormat.java
+++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/MimeMultipartDataFormat.java
@@ -44,6 +44,8 @@ public class MimeMultipartDataFormat extends DataFormatDefinition {
     @Metadata(defaultValue = "false")
     private Boolean headersInline;
     @XmlAttribute
+    private String includeHeaders;
+    @XmlAttribute
     @Metadata(defaultValue = "false")
     private Boolean binaryContent;
 
@@ -62,6 +64,9 @@ public class MimeMultipartDataFormat extends DataFormatDefinition {
         if (getHeadersInline() != null) {
             setProperty(camelContext, dataFormat, "headersInline", getHeadersInline());
         }
+        if (getIncludeHeaders() != null) {
+            setProperty(camelContext, dataFormat, "includeHeaders", getIncludeHeaders());
+        }
         if (getBinaryContent() != null) {
             setProperty(camelContext, dataFormat, "binaryContent", getBinaryContent());
         }
@@ -113,6 +118,20 @@ public class MimeMultipartDataFormat extends DataFormatDefinition {
     }
 
     /**
+     * A regex that defines which Camel headers are also included as MIME headers
+     * into the MIME multipart. This will only work if headersInline is set to true.
+     * <p>
+     * Default is to include no headers
+     */
+    public void setIncludeHeaders(String includeHeaders) {
+        this.includeHeaders = includeHeaders;
+    }
+
+    public String getIncludeHeaders() {
+        return includeHeaders;
+    }
+
+    /**
      * Defines whether the content of binary parts in the MIME multipart is
      * binary (true) or Base-64 encoded (false)
      * <p>

http://git-wip-us.apache.org/repos/asf/camel/blob/1044ce5f/components/camel-mail/src/main/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-mail/src/main/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormat.java b/components/camel-mail/src/main/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormat.java
index 7d6cf1c..51fdd2c 100644
--- a/components/camel-mail/src/main/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormat.java
+++ b/components/camel-mail/src/main/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormat.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import javax.activation.DataHandler;
 import javax.activation.DataSource;
@@ -57,9 +58,11 @@ public class MimeMultipartDataFormat implements DataFormat {
     private static final String CONTENT_TYPE = "Content-Type";
     private static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
     private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
+    private static final String[] STANDARD_HEADERS = {"Message-ID", "MIME-Version", "Content-Type"};
     private String multipartSubType = "mixed";
     private boolean multipartWithoutAttachment;
     private boolean headersInline;
+    private Pattern includeHeaders;
     private boolean binaryContent;
 
     public void setBinaryContent(boolean binaryContent) {
@@ -70,6 +73,10 @@ public class MimeMultipartDataFormat implements DataFormat {
         this.headersInline = headersInline;
     }
 
+    public void setIncludeHeaders(String includeHeaders) {
+        this.includeHeaders = Pattern.compile(includeHeaders, Pattern.CASE_INSENSITIVE);
+    }
+
     public void setMultipartWithoutAttachment(boolean multipartWithoutAttachment) {
         this.multipartWithoutAttachment = multipartWithoutAttachment;
     }
@@ -108,6 +115,18 @@ public class MimeMultipartDataFormat implements DataFormat {
                 exchange.getOut().removeAttachment(attachmentFilename);
             }
             mm.setContent(mp);
+            // copy headers if required and if the content can be converted into
+            // a String
+            if (headersInline && includeHeaders != null) {
+                for (Map.Entry<String, Object> entry : exchange.getIn().getHeaders().entrySet()) {
+                    if (includeHeaders.matcher(entry.getKey()).matches()) {
+                        String headerStr = ExchangeHelper.convertToType(exchange, String.class, entry.getValue());
+                        if (headerStr != null) {
+                            mm.setHeader(entry.getKey(), headerStr);
+                        }
+                    }
+                }
+            }
             mm.saveChanges();
             Enumeration<?> hl = mm.getAllHeaders();
             List<String> headers = new ArrayList<String>();
@@ -168,6 +187,15 @@ public class MimeMultipartDataFormat implements DataFormat {
             camelMessage = exchange.getOut();
             MessageHelper.copyHeaders(exchange.getIn(), camelMessage, true);
             contentType = mimeMessage.getHeader(CONTENT_TYPE, null);
+            // write the MIME headers not generated by javamail as Camel headers
+            Enumeration<?> headersEnum = mimeMessage.getNonMatchingHeaders(STANDARD_HEADERS);
+            while (headersEnum.hasMoreElements()) {
+                Object ho = headersEnum.nextElement();
+                if (ho instanceof Header) {
+                    Header header = (Header) ho;
+                    camelMessage.setHeader(header.getName(), header.getValue());
+                }
+            }
         } else {
             // check if this a multipart at all. Otherwise do nothing
             contentType = exchange.getIn().getHeader(CONTENT_TYPE, String.class);

http://git-wip-us.apache.org/repos/asf/camel/blob/1044ce5f/components/camel-mail/src/test/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormatTest.java
----------------------------------------------------------------------
diff --git a/components/camel-mail/src/test/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormatTest.java b/components/camel-mail/src/test/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormatTest.java
index c839074..dbc7c04 100644
--- a/components/camel-mail/src/test/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormatTest.java
+++ b/components/camel-mail/src/test/java/org/apache/camel/dataformat/mime/multipart/MimeMultipartDataFormatTest.java
@@ -34,6 +34,8 @@ import org.junit.Before;
 import org.junit.Test;
 
 import static org.hamcrest.core.IsCollectionContaining.hasItem;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.StringContains.containsString;
 import static org.hamcrest.core.StringStartsWith.startsWith;
 
 public class MimeMultipartDataFormatTest extends CamelTestSupport {
@@ -252,6 +254,35 @@ public class MimeMultipartDataFormatTest extends CamelTestSupport {
         assertThat(result.getOut().getHeader("Content-Type", String.class), startsWith("multipart/related"));
     }
 
+    @Test
+    public void marhsalUnmarshalInlineHeaders() throws IOException {
+        in.setBody("Body text");
+        in.setHeader("Content-Type", "text/plain");
+        in.setHeader("included", "must be included");
+        in.setHeader("excluded", "should not be there");
+        in.setHeader("x-foo", "any value");
+        in.setHeader("x-bar", "also there");
+        in.setHeader("xbar", "should not be there");
+        addAttachment("application/octet-stream", "foobar", "attachment.bin");
+        Exchange intermediate = template.send("direct:marshalonlyinlineheaders", exchange);
+        String bodyStr = intermediate.getOut().getBody(String.class);
+        assertThat(bodyStr, containsString("must be included"));
+        assertThat(bodyStr, not(containsString("should not be there")));
+        assertThat(bodyStr, containsString("x-foo:"));
+        assertThat(bodyStr, containsString("x-bar:"));
+        assertThat(bodyStr, not(containsString("xbar")));
+        intermediate.setIn(intermediate.getOut());
+        intermediate.setOut(null);
+        intermediate.getIn().removeHeaders(".*");
+        intermediate.getIn().setHeader("included", "should be replaced");
+        Exchange out = template.send("direct:unmarshalonlyinlineheaders", intermediate);
+        assertEquals("Body text", out.getOut().getBody(String.class));
+        assertEquals("must be included", out.getOut().getHeader("included"));
+        assertNull(out.getOut().getHeader("excluded"));
+        assertEquals("any value", out.getOut().getHeader("x-foo"));
+        assertEquals("also there", out.getOut().getHeader("x-bar"));
+    }
+
     private void addAttachment(String attContentType, String attText, String attFileName) throws IOException {
         DataSource ds = new ByteArrayDataSource(attText, attContentType);
         in.addAttachment(attFileName, new DataHandler(ds));
@@ -268,6 +299,8 @@ public class MimeMultipartDataFormatTest extends CamelTestSupport {
                 from("direct:roundtripbinarycontent").marshal().mimeMultipart(false, false, true).to("log:mime?showHeaders=true").to("dataformat:mime-multipart:unmarshal");
                 from("direct:marshalonlyrelated").marshal().mimeMultipart("related");
                 from("direct:marshalonlymixed").marshal().mimeMultipart();
+                from("direct:marshalonlyinlineheaders").marshal().mimeMultipart("mixed", false, true, "(included|x-.*)", false);
+                from("direct:unmarshalonlyinlineheaders").unmarshal().mimeMultipart(false, true, false);
             }
         };
     }