INTSAMPLES-70 - Sample showing how to process E-mail attachments
For reference see: https://jira.springsource.org/browse/INTSAMPLES-70
This commit is contained in:
41
intermediate/mail-attachments/README.md
Normal file
41
intermediate/mail-attachments/README.md
Normal file
@@ -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
|
||||
|
||||
103
intermediate/mail-attachments/pom.xml
Normal file
103
intermediate/mail-attachments/pom.xml
Normal file
@@ -0,0 +1,103 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.integration.samples</groupId>
|
||||
<artifactId>mail-attachments</artifactId>
|
||||
<name>Samples (Intermediate) - Mail Attachment Demo</name>
|
||||
<version>2.2.0.BUILD-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.integration.version>2.2.0.RC1</spring.integration.version>
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
<junit.version>4.10</junit.version>
|
||||
</properties>
|
||||
|
||||
<prerequisites>
|
||||
<maven>2.2.1</maven>
|
||||
</prerequisites>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-mail</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-file</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>3.1.1.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.subethamail</groupId>
|
||||
<artifactId>subethasmtp-wiser</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<compilerArgument>-Xlint:all</compilerArgument>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<configuration>
|
||||
<mainClass>org.springframework.integration.samples.mailattachments.Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repo.springsource.org.milestone</id>
|
||||
<name>Spring Framework Maven Milestone Repository</name>
|
||||
<url>https://repo.springsource.org/libs-milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EmailFragment> 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<EmailFragment> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Message<?>> splitIntoMessages(final List<EmailFragment> emailFragments) {
|
||||
|
||||
final List<Message<?>> messages = new ArrayList<Message<?>>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EmailFragment> transformit(javax.mail.Message mailMessage) {
|
||||
|
||||
final List<EmailFragment> emailFragments = new ArrayList<EmailFragment>();
|
||||
|
||||
EmailParserUtils.handleMessage(null, mailMessage, emailFragments);
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info(String.format("Email contains %s fragments.", emailFragments.size()));
|
||||
}
|
||||
|
||||
return emailFragments;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd
|
||||
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<int-mail:inbound-channel-adapter id="poll-for-email"
|
||||
channel="inboundChannel"
|
||||
java-mail-properties="javaMailProperties"
|
||||
store-uri="pop3://test:test@localhost:110/INBOX"
|
||||
should-delete-messages="true">
|
||||
<int:poller fixed-rate="5000"/>
|
||||
</int-mail:inbound-channel-adapter>
|
||||
|
||||
<util:properties id="javaMailProperties">
|
||||
<prop key="mail.store.protocol">pop3</prop>
|
||||
<prop key="mail.debug">false</prop>
|
||||
</util:properties>
|
||||
|
||||
<int:channel id="inboundChannel"/>
|
||||
|
||||
<int:chain id="transform-split" input-channel="inboundChannel" output-channel="outputChannel">
|
||||
<int:transformer>
|
||||
<bean class="org.springframework.integration.samples.mailattachments.support.EmailTransformer"/>
|
||||
</int:transformer>
|
||||
<int:splitter>
|
||||
<bean class="org.springframework.integration.samples.mailattachments.support.EmailSplitter"/>
|
||||
</int:splitter>
|
||||
</int:chain>
|
||||
|
||||
<int:channel id="outputChannel"/>
|
||||
|
||||
<int-file:outbound-channel-adapter id="save-as-file"
|
||||
auto-create-directory="true"
|
||||
channel="outputChannel"
|
||||
directory-expression="'target/out/' + headers.directory"/>
|
||||
</beans>
|
||||
28
intermediate/mail-attachments/src/main/resources/log4j.xml
Normal file
28
intermediate/mail-attachments/src/main/resources/log4j.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<!-- Appenders -->
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<param name="Target" value="System.out" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Loggers -->
|
||||
<logger name="org.springframework.integration.mail">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.samples">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<!-- Root Logger -->
|
||||
<root>
|
||||
<priority value="warn" />
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
||||
@@ -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<WiserMessage> wiserMessages = wiser.getMessages();
|
||||
|
||||
Assert.assertTrue(wiserMessages.size() == 1);
|
||||
|
||||
boolean foundTextMessage = false;
|
||||
boolean foundPicture = false;
|
||||
|
||||
for (WiserMessage wiserMessage : wiserMessages) {
|
||||
|
||||
final List<EmailFragment> emailFragments = new ArrayList<EmailFragment>();
|
||||
|
||||
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 <b>Rocks</b>!");
|
||||
|
||||
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<WiserMessage> wiserMessages = wiser.getMessages();
|
||||
|
||||
Assert.assertTrue(wiserMessages.size() == 1);
|
||||
|
||||
boolean foundTextMessage = false;
|
||||
boolean foundPicture = false;
|
||||
boolean foundHtmlMessage = false;
|
||||
|
||||
for (WiserMessage wiserMessage : wiserMessages) {
|
||||
|
||||
List<EmailFragment> emailFragments = new ArrayList<EmailFragment>();
|
||||
|
||||
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 ("<picture12345>".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.");
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -17,6 +17,7 @@
|
||||
<module>stored-procedures-derby</module>
|
||||
<module>tcp-client-server-multiplex</module>
|
||||
<module>travel</module>
|
||||
<module>mail-attachments</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
||||
Reference in New Issue
Block a user