diff --git a/src/main/java/org/simplejavamail/mailer/internal/datasource/NamedDataSource.java b/src/main/java/org/simplejavamail/mailer/internal/datasource/NamedDataSource.java new file mode 100644 index 000000000..41b31962e --- /dev/null +++ b/src/main/java/org/simplejavamail/mailer/internal/datasource/NamedDataSource.java @@ -0,0 +1,92 @@ +package org.simplejavamail.mailer.internal.datasource; + +import javax.activation.DataSource; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Data source used to fix bug, when user try to use different name for file in {@link javax.activation.FileDataSource}, + * than the actual name is. + * + * @author Lukas Kosina + * @see DataSource + * @see javax.activation.FileDataSource + */ +public class NamedDataSource implements DataSource { + + /** + * Original data source used for attachment + */ + private final DataSource dataSource; + /** + * The new name, which will be applied as email attachment + */ + private final String name; + + /** + * Constructor. Used for wrapping data source in parameter. Method {@link NamedDataSource#getName()} will + * use original name of the data source + * + * @param dataSource wrapped data source + */ + public NamedDataSource(DataSource dataSource) { + this.dataSource = dataSource; + this.name = null; + } + + /** + * Constructor. Used for wrapping data source in parameter. Method {@link NamedDataSource#getName()} will + * not use the original name, but it will use the name in the parameter instead. + * + * @param dataSource wrapped data source + * @param name new name of data source + */ + public NamedDataSource(String name, DataSource dataSource) { + this.dataSource = dataSource; + this.name = name; + } + + /** + * Return the input stream from {@link #dataSource} + * + * @return input stream + * @throws IOException if exception occurs during getting input stream from {@link #dataSource} + */ + @Override + public InputStream getInputStream() throws IOException { + return dataSource.getInputStream(); + } + + /** + * Return the output stream from {@link #dataSource} + * + * @return output stream + * @throws IOException if exception occurs during getting output stream from {@link #dataSource} + */ + @Override + public OutputStream getOutputStream() throws IOException { + return dataSource.getOutputStream(); + } + + /** + * Return the original content type from {@link #dataSource} + * + * @return content type of data source + */ + @Override + public String getContentType() { + return dataSource.getContentType(); + } + + /** + * If parameter {@link #name} is set, then return the value of parameter name. Otherwise, return the name of the + * {@link #dataSource} + * + * @return name of data source + */ + @Override + public String getName() { + return name != null ? name : dataSource.getName(); + } +} diff --git a/src/main/java/org/simplejavamail/mailer/internal/mailsender/MimeMessageHelper.java b/src/main/java/org/simplejavamail/mailer/internal/mailsender/MimeMessageHelper.java index 120f94fa9..6ca33629b 100644 --- a/src/main/java/org/simplejavamail/mailer/internal/mailsender/MimeMessageHelper.java +++ b/src/main/java/org/simplejavamail/mailer/internal/mailsender/MimeMessageHelper.java @@ -7,6 +7,7 @@ import org.simplejavamail.email.AttachmentResource; import org.simplejavamail.email.Email; import org.simplejavamail.email.Recipient; +import org.simplejavamail.mailer.internal.datasource.NamedDataSource; import javax.activation.DataHandler; import javax.activation.DataSource; @@ -29,15 +30,15 @@ */ public final class MimeMessageHelper { - private MimeMessageHelper() { - - } - /** * Encoding used for setting body text, email address, headers, reply-to fields etc. ({@link StandardCharsets#UTF_8}). */ private static final String CHARACTER_ENCODING = StandardCharsets.UTF_8.name(); + private MimeMessageHelper() { + + } + /** * Creates a new {@link MimeMessage} instance coupled to a specific {@link Session} instance and prepares it in the email structure, so that it * can be filled and send. @@ -207,7 +208,7 @@ private static BodyPart getBodyPartFromDatasource(final AttachmentResource attac // setting headers isn't working nicely using the javax mail API, so let's do that manually String resourceName = determineResourceName(attachmentResource, false); String fileName = determineResourceName(attachmentResource, true); - attachmentPart.setDataHandler(new DataHandler(attachmentResource.getDataSource())); + attachmentPart.setDataHandler(new DataHandler(new NamedDataSource(fileName, attachmentResource.getDataSource()))); attachmentPart.setFileName(fileName); String contentType = attachmentResource.getDataSource().getContentType(); attachmentPart.setHeader("Content-Type", contentType + "; filename=" + fileName + "; name=" + resourceName); diff --git a/src/test/java/org/simplejavamail/mailer/internal/datasource/NamedDataSourceTest.java b/src/test/java/org/simplejavamail/mailer/internal/datasource/NamedDataSourceTest.java new file mode 100644 index 000000000..533a59e11 --- /dev/null +++ b/src/test/java/org/simplejavamail/mailer/internal/datasource/NamedDataSourceTest.java @@ -0,0 +1,81 @@ +package org.simplejavamail.mailer.internal.datasource; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import javax.activation.DataSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class NamedDataSourceTest { + + @Mock + private DataSource dataSource; + + @Before + public void setUp() throws Exception { + when(dataSource.getName()).thenReturn("testName"); + } + + @Test + public void renameWillWork() throws Exception { + DataSource testDataSource = new NamedDataSource("newName", dataSource); + assertThat(testDataSource.getName()).isEqualTo("newName"); + verifyZeroInteractions(dataSource); + } + + @Test + public void originalNameWillWork() throws Exception { + DataSource testDataSource = new NamedDataSource(dataSource); + assertThat(testDataSource.getName()).isEqualTo("testName"); + verify(dataSource).getName(); + } + + @Test + public void inputStreamWillBeTheSame1() throws Exception { + DataSource testDataSource = new NamedDataSource("newName", dataSource); + testDataSource.getInputStream(); + verify(dataSource).getInputStream(); + } + + @Test + public void inputStreamWillBeTheSame2() throws Exception { + DataSource testDataSource = new NamedDataSource(dataSource); + testDataSource.getInputStream(); + verify(dataSource).getInputStream(); + } + + @Test + public void outputStreamWillBeTheSame1() throws Exception { + DataSource testDataSource = new NamedDataSource("newName", dataSource); + testDataSource.getOutputStream(); + verify(dataSource).getOutputStream(); + } + + @Test + public void outputStreamWillBeTheSame2() throws Exception { + DataSource testDataSource = new NamedDataSource(dataSource); + testDataSource.getOutputStream(); + verify(dataSource).getOutputStream(); + } + + @Test + public void contentTypeStreamWillBeTheSame1() throws Exception { + DataSource testDataSource = new NamedDataSource("newName", dataSource); + testDataSource.getContentType(); + verify(dataSource).getContentType(); + } + + @Test + public void contentTypeStreamWillBeTheSame2() throws Exception { + DataSource testDataSource = new NamedDataSource(dataSource); + testDataSource.getContentType(); + verify(dataSource).getContentType(); + } + +} \ No newline at end of file