diff --git a/intermediate/mail-attachments/README.md b/intermediate/mail-attachments/README.md new file mode 100644 index 00000000..5e71a4a9 --- /dev/null +++ b/intermediate/mail-attachments/README.md @@ -0,0 +1,41 @@ +Spring Integration - Processing Email Attachments Sample +======================================================== + +# Overview + +This example demonstrates how emails including their attachments can be processed using Spring Integration. This sample uses the following Spring Integration components: + +* Mail Inbound Channel Adapter +* Chain +* Transformer +* Splitter +* File Outbound Channel Adapter + +# Getting Started + +In order to use this sample you must have access to a mail-server. You can either use an external server (e.g. GMail) or you can also easily setup your own mail server using Apache James 3.0 (http://james.apache.org/). You can find instructions for setting up a basic instance at: + +* http://james.apache.org/server/3/quick-start.html +* http://hillert.blogspot.com/2011/05/testing-email-notifications-with-apache.html + +In **src/main/resources/META-INF/spring/integration/spring-integration-context.xml** change the following to reflect the settings for your mail server. + + store-uri="imap://test:test@localhost:143/INBOX" + +Lastly, before you run the example, please make sure that your email inbox contains some messages. + +You can run this sample by either. + +* running the "Main" class from within STS (Right-click on Main class --> Run As --> Java Application) +* or from the command line: + - mvn package + - mvn exec:java + +Once started, the configured mail server will be polled for new email messages every 5 seconds. + +-------------------------------------------------------------------------------- + +For help please take a look at the Spring Integration documentation: + +http://www.springsource.org/spring-integration + diff --git a/intermediate/mail-attachments/pom.xml b/intermediate/mail-attachments/pom.xml new file mode 100644 index 00000000..504c8451 --- /dev/null +++ b/intermediate/mail-attachments/pom.xml @@ -0,0 +1,103 @@ + + 4.0.0 + org.springframework.integration.samples + mail-attachments + Samples (Intermediate) - Mail Attachment Demo + 2.2.0.BUILD-SNAPSHOT + + + UTF-8 + 2.2.0.RC1 + 1.2.17 + 4.10 + + + + 2.2.1 + + + + + org.springframework.integration + spring-integration-mail + ${spring.integration.version} + + + org.springframework.integration + spring-integration-file + ${spring.integration.version} + + + javax.activation + activation + 1.1.1 + + + javax.mail + mail + 1.4.5 + + + commons-io + commons-io + 2.4 + + + + junit + junit + ${junit.version} + test + + + org.springframework + spring-test + 3.1.1.RELEASE + test + + + org.subethamail + subethasmtp-wiser + 1.2 + test + + + + log4j + log4j + ${log4j.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.6 + 1.6 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + org.springframework.integration.samples.mailattachments.Main + + + + + + + repo.springsource.org.milestone + Spring Framework Maven Milestone Repository + https://repo.springsource.org/libs-milestone + + + diff --git a/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/Main.java b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/Main.java new file mode 100644 index 00000000..795c7990 --- /dev/null +++ b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/Main.java @@ -0,0 +1,84 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed 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.springframework.integration.samples.mailattachments; + +import java.util.Scanner; + +import org.apache.log4j.Logger; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * Starts the Spring Context and will initialize the Spring Integration routes. + * + * @author Gunnar Hillert + * @since 2.2 + * + */ +public final class Main { + + private static final Logger LOGGER = Logger.getLogger(Main.class); + + private static final String HORIZONTAL_LINE = + "\n========================================================="; + + private Main() { } + + /** + * Load the Spring Integration Application Context + * + * @param args - command line arguments + */ + public static void main(final String... args) { + + LOGGER.info(HORIZONTAL_LINE + + "\n" + + "\n Welcome to Spring Integration! " + + "\n" + + "\n For more information please visit: " + + "\n http://www.springsource.org/spring-integration " + + "\n" + + HORIZONTAL_LINE ); + + final AbstractApplicationContext context = + new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml"); + + context.registerShutdownHook(); + + final Scanner scanner = new Scanner(System.in); + + LOGGER.info(HORIZONTAL_LINE + + "\n" + + "\n Please press 'q + Enter' to quit the application. " + + "\n" + + HORIZONTAL_LINE ); + + while (true) { + + final String input = scanner.nextLine(); + + if("q".equals(input.trim())) { + break; + } + + } + + LOGGER.info("Exiting application...bye."); + + System.exit(0); + + } +} diff --git a/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailFragment.java b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailFragment.java new file mode 100644 index 00000000..1784e2b2 --- /dev/null +++ b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailFragment.java @@ -0,0 +1,129 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed 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.springframework.integration.samples.mailattachments.support; + +import java.io.File; + +import org.springframework.util.Assert; + +/** + * Represents a part of the original email messsage. EmailFragments could be either + * Email messages themselves or also attachments. The sample will use {@link EmailFragment}s + * to ultimately write the various pieces that constitute an email message out to + * the file system. + * + * @author Gunnar Hillert + * @since 2.2 + * + */ +public class EmailFragment { + + private Object data; + private String filename; + private File directory; + + /** + * Constructor. + * + * @param directory Must not be null + * @param filename Must not be null + * @param data Must not be null + */ + public EmailFragment(File directory, String filename, Object data) { + super(); + + Assert.notNull(directory); + Assert.hasText(filename); + Assert.notNull(data); + + this.directory = directory; + this.filename = filename; + this.data = data; + } + + /** + * The data to save to the file system, e.g. text messages/attachments, binary + * file attachments etc. + */ + public Object getData() { + return data; + } + + /** + * The file name to create for the respective {@link EmailFragment}. + */ + public String getFilename() { + return filename; + } + + /** + * The directory where to store the {@link #getData()} using the specified + * {@link #getFilename()}. + * + */ + public File getDirectory() { + return this.directory; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((directory == null) ? 0 : directory.hashCode()); + result = prime * result + + ((filename == null) ? 0 : filename.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EmailFragment other = (EmailFragment) obj; + if (directory == null) { + if (other.directory != null) { + return false; + } + } + else if (!directory.equals(other.directory)) { + return false; + } + if (filename == null) { + if (other.filename != null) { + return false; + } + } + else if (!filename.equals(other.filename)) { + return false; + } + return true; + } + + @Override + public String toString() { + return "EmailFragment [filename=" + filename + ", directory=" + + directory + "]"; + } + +} diff --git a/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailParserUtils.java b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailParserUtils.java new file mode 100644 index 00000000..33d001a5 --- /dev/null +++ b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailParserUtils.java @@ -0,0 +1,258 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed 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.springframework.integration.samples.mailattachments.support; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import javax.mail.BodyPart; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Part; +import javax.mail.internet.ContentType; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.ParseException; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.springframework.util.Assert; + +/** + * Utility Class for parsing mail messages. + * + * @author Gunnar Hillert + * @since 2.2 + * + */ +public final class EmailParserUtils { + + private static final Logger LOGGER = Logger.getLogger(EmailParserUtils.class); + + /** Prevent instantiation. */ + private EmailParserUtils() { + throw new AssertionError(); + } + + /** + * Parses a mail message. The respective message can either be the root message + * or another message that is attached to another message. + * + * If the mail message is an instance of {@link String}, then a {@link EmailFragment} + * is being created using the email message's subject line as the file name, + * which will contain the mail message's content. + * + * If the mail message is an instance of {@link Multipart} then we delegate + * to {@link #handleMultipart(File, Multipart, javax.mail.Message, List)}. + * + * @param directory The directory for storing the message. If null this is the root message. + * @param mailMessage The mail message to be parsed. Must not be null. + * @param emailFragments Must not be null. + */ + public static void handleMessage(final File directory, + final javax.mail.Message mailMessage, + final List emailFragments) { + + Assert.notNull(mailMessage, "The mail message to be parsed must not be null."); + Assert.notNull(emailFragments, "The collection of emailfragments must not be null."); + + final Object content; + final String subject; + + try { + content = mailMessage.getContent(); + subject = mailMessage.getSubject(); + } catch (IOException e) { + throw new IllegalStateException("Error while retrieving the email contents.", e); + } catch (MessagingException e) { + throw new IllegalStateException("Error while retrieving the email contents.", e); + } + + final File directoryToUse; + + if (directory == null) { + directoryToUse = new File(subject); + } else { + directoryToUse = new File(directory, subject); + } + + if (content instanceof String) { + emailFragments.add(new EmailFragment(new File(subject), "message.txt", content)); + } + else if (content instanceof Multipart) { + Multipart multipart = (Multipart) content; + handleMultipart(directoryToUse, multipart, mailMessage, emailFragments); + } + else { + throw new IllegalStateException("This content type is not handled - " + content.getClass().getSimpleName()); + } + + } + + /** + * Parses any {@link Multipart} instances that contain text or Html attachments, + * {@link InputStream} instances, additional instances of {@link Multipart} + * or other attached instances of {@link javax.mail.Message}. + * + * Will create the respective {@link EmailFragment}s representing those attachments. + * + * Instances of {@link javax.mail.Message} are delegated to + * {@link #handleMessage(File, javax.mail.Message, List)}. Further instances + * of {@link Multipart} are delegated to + * {@link #handleMultipart(File, Multipart, javax.mail.Message, List)}. + * + * @param directory Must not be null + * @param multipart Must not be null + * @param mailMessage Must not be null + * @param emailFragments Must not be null + */ + public static void handleMultipart(File directory, Multipart multipart, javax.mail.Message mailMessage, List emailFragments) { + + Assert.notNull(directory, "The directory must not be null."); + Assert.notNull(multipart, "The multipart object to be parsed must not be null."); + Assert.notNull(mailMessage, "The mail message to be parsed must not be null."); + Assert.notNull(emailFragments, "The collection of emailfragments must not be null."); + + final int count; + + try { + count = multipart.getCount(); + + if (LOGGER.isInfoEnabled()) { + LOGGER.info(String.format("Number of enclosed BodyPart objects: %s.", count)); + } + + } + catch (MessagingException e) { + throw new IllegalStateException("Error while retrieving the number of enclosed BodyPart objects.", e); + } + + for (int i = 0; i < count; i++) { + + final BodyPart bp; + + try { + bp = multipart.getBodyPart(i); + } + catch (MessagingException e) { + throw new IllegalStateException("Error while retrieving body part.", e); + } + + final String contentType; + String filename; + final String disposition; + final String subject; + + try { + + contentType = bp.getContentType(); + filename = bp.getFileName(); + disposition = bp.getDisposition(); + subject = mailMessage.getSubject(); + + if (filename == null && bp instanceof MimeBodyPart) { + filename = ((MimeBodyPart) bp).getContentID(); + } + + } + catch (MessagingException e) { + throw new IllegalStateException("Unable to retrieve body part meta data.", e); + } + + if (LOGGER.isInfoEnabled()) { + LOGGER.info(String.format("BodyPart - Content Type: '%s', filename: '%s', disposition: '%s', subject: '%s'", + new Object[]{contentType, filename, disposition, subject})); + } + + if (Part.ATTACHMENT.equalsIgnoreCase(disposition)) { + LOGGER.info(String.format("Handdling attachment '%s', type: '%s'", filename, contentType)); + } + + final Object content; + + try { + content = bp.getContent(); + } + catch (IOException e) { + throw new IllegalStateException("Error while retrieving the email contents.", e); + } + catch (MessagingException e) { + throw new IllegalStateException("Error while retrieving the email contents.", e); + } + + if (content instanceof String) { + + if (Part.ATTACHMENT.equalsIgnoreCase(disposition)) { + emailFragments.add(new EmailFragment(directory, i + "-" + filename, content)); + LOGGER.info(String.format("Handdling attachment '%s', type: '%s'", filename, contentType)); + } + else { + + final String textFilename; + final ContentType ct; + + try { + ct = new ContentType(contentType); + } + catch (ParseException e) { + throw new IllegalStateException("Error while parsing content type '" + contentType + "'.", e); + } + + if ("text/plain".equalsIgnoreCase(ct.getBaseType())) { + textFilename = "message.txt"; + } + else if ("text/html".equalsIgnoreCase(ct.getBaseType())) { + textFilename = "message.html"; + } + else { + textFilename = "message.other"; + } + + emailFragments.add(new EmailFragment(directory, textFilename, content)); + } + + + } + else if (content instanceof InputStream) { + + final InputStream inputStream = (InputStream) content; + final ByteArrayOutputStream bis = new ByteArrayOutputStream(); + + try { + IOUtils.copy(inputStream, bis); + } + catch (IOException e) { + throw new IllegalStateException("Error while copying input stream to the ByteArrayOutputStream.", e); + } + + emailFragments.add(new EmailFragment(directory, filename, bis.toByteArray())); + + } + else if (content instanceof javax.mail.Message) { + handleMessage(directory, (javax.mail.Message) content, emailFragments); + } + else if (content instanceof Multipart) { + final Multipart mp2 = (Multipart) content; + handleMultipart(directory, mp2, mailMessage, emailFragments); + } + else { + throw new IllegalStateException("Content type not handled: " + content.getClass().getSimpleName()); + } + } + } +} diff --git a/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailSplitter.java b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailSplitter.java new file mode 100644 index 00000000..98a65593 --- /dev/null +++ b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailSplitter.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed 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.springframework.integration.samples.mailattachments.support; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.integration.Message; +import org.springframework.integration.annotation.Splitter; +import org.springframework.integration.file.FileHeaders; +import org.springframework.integration.support.MessageBuilder; + +/** + * Splits a {@link List} of {@link EmailFragment}s into individual Spring Integration + * {@link Message}s. + * + * @author Gunnar Hillert + * @since 2.2 + * + */ +public class EmailSplitter { + + @Splitter + public List> splitIntoMessages(final List emailFragments) { + + final List> messages = new ArrayList>(); + + for (EmailFragment emailFragment : emailFragments) { + Message message = MessageBuilder.withPayload(emailFragment.getData()) + .setHeader(FileHeaders.FILENAME, emailFragment.getFilename()) + .setHeader("directory", emailFragment.getDirectory()) + .build(); + messages.add(message); + } + + return messages; + } + +} diff --git a/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailTransformer.java b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailTransformer.java new file mode 100644 index 00000000..dbe1599f --- /dev/null +++ b/intermediate/mail-attachments/src/main/java/org/springframework/integration/samples/mailattachments/support/EmailTransformer.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed 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.springframework.integration.samples.mailattachments.support; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.springframework.integration.annotation.Transformer; + +/** + * Parses the E-mail Message and converts each containing message and/or attachment into + * a {@link List} of {@link EmailFragment}s. + * + * @author Gunnar Hillert + * @since 2.2 + * + */ +public class EmailTransformer { + + private static final Logger LOGGER = Logger.getLogger(EmailTransformer.class); + + @Transformer + public List transformit(javax.mail.Message mailMessage) { + + final List emailFragments = new ArrayList(); + + EmailParserUtils.handleMessage(null, mailMessage, emailFragments); + + if (LOGGER.isInfoEnabled()) { + LOGGER.info(String.format("Email contains %s fragments.", emailFragments.size())); + } + + return emailFragments; + } + +} diff --git a/intermediate/mail-attachments/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/intermediate/mail-attachments/src/main/resources/META-INF/spring/integration/spring-integration-context.xml new file mode 100644 index 00000000..7019a6c5 --- /dev/null +++ b/intermediate/mail-attachments/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -0,0 +1,45 @@ + + + + + + + + + pop3 + false + + + + + + + + + + + + + + + + + diff --git a/intermediate/mail-attachments/src/main/resources/log4j.xml b/intermediate/mail-attachments/src/main/resources/log4j.xml new file mode 100644 index 00000000..a78006b5 --- /dev/null +++ b/intermediate/mail-attachments/src/main/resources/log4j.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/intermediate/mail-attachments/src/test/java/org/springframework/integration/samples/mailattachments/MimeMessageParsingTest.java b/intermediate/mail-attachments/src/test/java/org/springframework/integration/samples/mailattachments/MimeMessageParsingTest.java new file mode 100644 index 00000000..0fa4560c --- /dev/null +++ b/intermediate/mail-attachments/src/test/java/org/springframework/integration/samples/mailattachments/MimeMessageParsingTest.java @@ -0,0 +1,242 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed 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.springframework.integration.samples.mailattachments; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.integration.samples.mailattachments.support.EmailFragment; +import org.springframework.integration.samples.mailattachments.support.EmailParserUtils; +import org.springframework.mail.MailParseException; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.subethamail.wiser.Wiser; +import org.subethamail.wiser.WiserMessage; + +/** + * Test to verify the correct parsing of Email Messages. + * + * @author Gunnar Hillert + * @since 2.2 + */ +public class MimeMessageParsingTest { + + private static final Logger LOGGER = Logger.getLogger(MimeMessageParsingTest.class); + + private Wiser wiser; + + @Before + public void startWiser() { + wiser = new Wiser(); + wiser.setPort(2500); + wiser.start(); + LOGGER.info("Wiser was started."); + } + + /** + * This test will create a Mime Message that contains an Attachment, send it + * to an SMTP Server (Using Wiser) and retrieve and process the Mime Message. + * + * This test verifies that the parsing of the retrieved Mime Message is + * successful and that the correct number of {@link EmailFragment}s is created. + */ + @Test + public void testProcessingOfEmailAttachments() { + + final JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setPort(2500); + + final MimeMessage message = mailSender.createMimeMessage(); + final String pictureName = "picture.png"; + + final ByteArrayResource byteArrayResource = getFileData(pictureName); + + try { + + final MimeMessageHelper helper = new MimeMessageHelper(message, true); + + helper.setFrom("testfrom@springintegration.org"); + helper.setTo("testto@springintegration.org"); + helper.setSubject("Parsing of Attachments"); + helper.setText("Spring Integration Rocks!"); + + helper.addAttachment(pictureName, byteArrayResource, "image/png"); + + } + catch (MessagingException e) { + throw new MailParseException(e); + } + + mailSender.send(message); + + final List wiserMessages = wiser.getMessages(); + + Assert.assertTrue(wiserMessages.size() == 1); + + boolean foundTextMessage = false; + boolean foundPicture = false; + + for (WiserMessage wiserMessage : wiserMessages) { + + final List emailFragments = new ArrayList(); + + try { + final MimeMessage mailMessage = wiserMessage.getMimeMessage(); + EmailParserUtils.handleMessage(null, mailMessage, emailFragments); + } + catch (MessagingException e) { + throw new IllegalStateException("Error while retrieving Mime Message."); + } + + Assert.assertTrue(emailFragments.size() == 2); + + for (EmailFragment emailFragment : emailFragments) { + if ("picture.png".equals(emailFragment.getFilename())) { + foundPicture = true; + } + + if ("message.txt".equals(emailFragment.getFilename())) { + foundTextMessage = true; + } + } + + Assert.assertTrue(foundPicture); + Assert.assertTrue(foundTextMessage); + + } + } + + /** + * This test will create a Mime Message that in return contains another + * mime message. The nested mime message contains an attachment. + * + * The root message consist of both HTML and Text message. + * + */ + @Test + public void testProcessingOfNestedEmailAttachments() { + + final JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setPort(2500); + + final MimeMessage rootMessage = mailSender.createMimeMessage(); + + try { + + final MimeMessageHelper messageHelper = new MimeMessageHelper(rootMessage, true); + + messageHelper.setFrom("testfrom@springintegration.org"); + messageHelper.setTo("testto@springintegration.org"); + messageHelper.setSubject("Parsing of Attachments"); + messageHelper.setText("Spring Integration Rocks!", "Spring Integration Rocks!"); + + final String pictureName = "picture.png"; + + final ByteArrayResource byteArrayResource = getFileData(pictureName); + + messageHelper.addInline("picture12345", byteArrayResource, "image/png"); + + } + catch (MessagingException e) { + throw new MailParseException(e); + } + + mailSender.send(rootMessage); + + final List wiserMessages = wiser.getMessages(); + + Assert.assertTrue(wiserMessages.size() == 1); + + boolean foundTextMessage = false; + boolean foundPicture = false; + boolean foundHtmlMessage = false; + + for (WiserMessage wiserMessage : wiserMessages) { + + List emailFragments = new ArrayList(); + + try { + + final MimeMessage mailMessage = wiserMessage.getMimeMessage(); + EmailParserUtils.handleMessage(null, mailMessage, emailFragments); + + } catch (MessagingException e) { + throw new IllegalStateException("Error while retrieving Mime Message."); + } + + Assert.assertTrue(emailFragments.size() == 3); + + for (EmailFragment emailFragment : emailFragments) { + if ("".equals(emailFragment.getFilename())) { + foundPicture = true; + } + + if ("message.txt".equals(emailFragment.getFilename())) { + foundTextMessage = true; + } + + if ("message.html".equals(emailFragment.getFilename())) { + foundHtmlMessage = true; + } + } + + Assert.assertTrue(foundPicture); + Assert.assertTrue(foundTextMessage); + Assert.assertTrue(foundHtmlMessage); + + } + } + + private ByteArrayResource getFileData(String filename) { + + final InputStream attachmentInputStream = MimeMessageParsingTest.class.getResourceAsStream(filename); + + Assert.assertNotNull("Resource not found: " + filename, attachmentInputStream); + + ByteArrayResource byteArrayResource = null; + + try { + byteArrayResource = new ByteArrayResource(IOUtils.toByteArray(attachmentInputStream)); + attachmentInputStream.close(); + } + catch (IOException e1) { + Assert.fail(); + } + + return byteArrayResource; + + } + + @After + public void stopWiser() { + wiser.stop(); + LOGGER.info("Wiser stopped."); + } + +} diff --git a/intermediate/mail-attachments/src/test/resources/org/springframework/integration/samples/mailattachments/picture.png b/intermediate/mail-attachments/src/test/resources/org/springframework/integration/samples/mailattachments/picture.png new file mode 100644 index 00000000..01761ab0 Binary files /dev/null and b/intermediate/mail-attachments/src/test/resources/org/springframework/integration/samples/mailattachments/picture.png differ diff --git a/intermediate/pom.xml b/intermediate/pom.xml index a86b430a..5ff4ac00 100644 --- a/intermediate/pom.xml +++ b/intermediate/pom.xml @@ -17,6 +17,7 @@ stored-procedures-derby tcp-client-server-multiplex travel + mail-attachments