From 49503b9b3379c613544ea8b4c727395ad6118fe9 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Mon, 6 Feb 2023 20:02:24 +0800 Subject: [PATCH 01/19] EMAIL-204: Disable eager loading while parsing email attachement --- .../org/apache/commons/mail/util/MimeMessageParser.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index e29269eeb..8ebb355bd 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -270,12 +270,7 @@ protected DataSource createDataSource(final Multipart parent, final MimePart par final DataHandler dataHandler = part.getDataHandler(); final DataSource dataSource = dataHandler.getDataSource(); final String contentType = getBaseMimeType(dataSource.getContentType()); - byte[] content; - try (InputStream inputStream = dataSource.getInputStream()) - { - content = this.getContent(inputStream); - } - final ByteArrayDataSource result = new ByteArrayDataSource(content, contentType); + final ByteArrayDataSource result = new ByteArrayDataSource(dataSource.getInputStream(), contentType); final String dataSourceName = getDataSourceName(part, dataSource); result.setName(dataSourceName); return result; From 4a34933d8b6cd7c5aeee3f724e0de0c7ebe9d298 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Mon, 6 Feb 2023 21:35:00 +0800 Subject: [PATCH 02/19] EMAIL-204: Remove unused methods --- .../commons/mail/util/MimeMessageParser.java | 47 ++----------------- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index 8ebb355bd..0f4a8113c 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -16,34 +16,17 @@ */ package org.apache.commons.mail.util; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import javax.activation.DataHandler; import javax.activation.DataSource; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Part; -import javax.mail.internet.ContentType; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimePart; -import javax.mail.internet.MimeUtility; -import javax.mail.internet.ParseException; +import javax.mail.internet.*; import javax.mail.util.ByteArrayDataSource; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.*; /** * Parses a MimeMessage and stores the individual parts such a plain text, @@ -406,28 +389,6 @@ protected String getDataSourceName(final Part part, final DataSource dataSource) return result; } - /** - * Read the content of the input stream. - * - * @param is the input stream to process - * @return the content of the input stream - * @throws IOException reading the input stream failed - */ - private byte[] getContent(final InputStream is) - throws IOException - { - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - final BufferedInputStream isReader = new BufferedInputStream(is); - try (BufferedOutputStream osWriter = new BufferedOutputStream(os)) { - int ch; - while ((ch = isReader.read()) != -1) - { - osWriter.write(ch); - } - osWriter.flush(); - return os.toByteArray(); - } - } /** * Parses the mimeType. From ae324f91be7e0f4d127ed71680526cb9a74c7f7f Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Wed, 8 Feb 2023 13:26:16 +0800 Subject: [PATCH 03/19] EMAIL-204: Update dep --- .../commons/mail/util/MimeMessageParser.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index 0f4a8113c..430990740 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -15,6 +15,15 @@ * limitations under the License. */ package org.apache.commons.mail.util; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import javax.activation.DataHandler; import javax.activation.DataSource; @@ -22,11 +31,14 @@ import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Part; -import javax.mail.internet.*; +import javax.mail.internet.ContentType; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimePart; +import javax.mail.internet.MimeUtility; +import javax.mail.internet.ParseException; import javax.mail.util.ByteArrayDataSource; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.*; /** * Parses a MimeMessage and stores the individual parts such a plain text, From e48d8c8456b8ca8e12a49044705ca2898c05ce8d Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Wed, 8 Feb 2023 22:15:26 +0800 Subject: [PATCH 04/19] EMAIL-204: Wrapper class for data src --- .../commons/mail/AttachmentDataSource.java | 68 +++++++++++++++++++ .../commons/mail/util/MimeMessageParser.java | 10 +-- .../mail/util/MimeMessageParserTest.java | 38 +++++++++++ 3 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/apache/commons/mail/AttachmentDataSource.java diff --git a/src/main/java/org/apache/commons/mail/AttachmentDataSource.java b/src/main/java/org/apache/commons/mail/AttachmentDataSource.java new file mode 100644 index 000000000..cc7db455c --- /dev/null +++ b/src/main/java/org/apache/commons/mail/AttachmentDataSource.java @@ -0,0 +1,68 @@ +/* + * 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.commons.mail; + +import javax.activation.DataSource; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Proxy dataSource class which contain reference of MimePartDataSource for given attachment, + * with revised type and name, in order delay the memory allocation for attachment until when the content of the attachment is needed. + * + * @since 1.3 + */ +public class AttachmentDataSource implements DataSource { + + + private String type; // content-type + private String name = ""; + private DataSource ds; + + + public AttachmentDataSource(DataSource ds, String type, String name) { + + this.ds = ds; + this.type = type; + this.name = name; + } + + @Override + public InputStream getInputStream() throws IOException { + if (ds == null) { + throw new IOException("no data available"); + } else{ + return ds.getInputStream(); + } + } + + @Override + public OutputStream getOutputStream() throws IOException { + throw new IOException("cannot do this"); + } + + @Override + public String getContentType() { + return type; + } + + @Override + public String getName() { + return name; + } +} diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index 430990740..c0d0b03d1 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -15,8 +15,9 @@ * limitations under the License. */ package org.apache.commons.mail.util; -import java.io.IOException; -import java.io.UnsupportedEncodingException; +import org.apache.commons.mail.AttachmentDataSource; + +import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -265,9 +266,10 @@ protected DataSource createDataSource(final Multipart parent, final MimePart par final DataHandler dataHandler = part.getDataHandler(); final DataSource dataSource = dataHandler.getDataSource(); final String contentType = getBaseMimeType(dataSource.getContentType()); - final ByteArrayDataSource result = new ByteArrayDataSource(dataSource.getInputStream(), contentType); final String dataSourceName = getDataSourceName(part, dataSource); - result.setName(dataSourceName); + final AttachmentDataSource result = new AttachmentDataSource(dataSource, contentType, dataSourceName); + System.out.println("New stream: " + result.getInputStream()); + return result; } diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index 5b507d439..7831bff30 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -497,5 +497,43 @@ public void testParseInlineCID() throws Exception assertNotNull(ds); assertEquals(ds, mimeMessageParser.getAttachmentList().get(0)); } + @Test + public void testParseHtmlEmailWithAttachments_size() throws Exception + { + DataSource dataSource; + final Session session = Session.getDefaultInstance(new Properties()); + final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/html-attachment.eml")); + final MimeMessageParser mimeMessageParser = new MimeMessageParser(message); + + mimeMessageParser.parse(); + + assertEquals("Test", mimeMessageParser.getSubject()); + assertNotNull(mimeMessageParser.getMimeMessage()); + assertTrue(mimeMessageParser.isMultipart()); + assertTrue(mimeMessageParser.hasHtmlContent()); + assertTrue(mimeMessageParser.hasPlainContent()); + assertNotNull(mimeMessageParser.getPlainContent()); + assertNotNull(mimeMessageParser.getHtmlContent()); + assertTrue(mimeMessageParser.getTo().size() == 1); + assertTrue(mimeMessageParser.getCc().isEmpty()); + assertTrue(mimeMessageParser.getBcc().isEmpty()); + assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getFrom()); + assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getReplyTo()); + assertTrue(mimeMessageParser.hasAttachments()); + final List attachmentList = mimeMessageParser.getAttachmentList(); + assertTrue(attachmentList.size() == 2); + + dataSource = mimeMessageParser.findAttachmentByName("Wasserlilien.jpg"); + assertNotNull(dataSource); + assertEquals("image/jpeg", dataSource.getContentType()); + + System.out.println(dataSource.getInputStream().available()); + + dataSource = mimeMessageParser.findAttachmentByName("it20one.pdf"); + assertNotNull(dataSource); + assertEquals("application/pdf", dataSource.getContentType()); + System.out.println(dataSource.getInputStream().available()); + } + } From a976fff19e76932d6d4b188829bee84cb7917b2b Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Wed, 8 Feb 2023 23:55:50 +0800 Subject: [PATCH 05/19] EMAIL-204: Update count --- .../commons/mail/LazyByteArrayDataSource.java | 67 +++++++++++++++++++ .../commons/mail/util/MimeMessageParser.java | 5 +- .../mail/util/MimeMessageParserTest.java | 3 +- 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java diff --git a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java new file mode 100644 index 000000000..4a046cd50 --- /dev/null +++ b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java @@ -0,0 +1,67 @@ +/* + * 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.commons.mail; + +import javax.activation.DataSource; +import javax.mail.util.ByteArrayDataSource; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Proxy dataSource class which contain reference of MimePartDataSource for given attachment, + * with revised type and name, in order delay the memory allocation for attachment until when the content of the attachment is needed. + * + * @since 1.3 + */ +public class LazyByteArrayDataSource implements DataSource { + + private InputStream referenceInputStream; + private ByteArrayDataSource ds; + private String type; + private String name; + + public LazyByteArrayDataSource(InputStream is, String type, String name) { + this.referenceInputStream = is; + this.type = type; + this.name = name; + } + + @Override + public InputStream getInputStream() throws IOException { + if (ds == null) { + //Only read attachment data to memory when getInputStream() is called. + ds = new ByteArrayDataSource(referenceInputStream, type); + } + return ds.getInputStream(); + } + + @Override + public OutputStream getOutputStream() throws IOException { + throw new IOException("cannot do this"); + } + + @Override + public String getContentType() { + return type; + } + + @Override + public String getName() { + return name; + } +} diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index c0d0b03d1..7c2da7ea9 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -16,6 +16,7 @@ */ package org.apache.commons.mail.util; import org.apache.commons.mail.AttachmentDataSource; +import org.apache.commons.mail.LazyByteArrayDataSource; import java.io.*; import java.util.ArrayList; @@ -267,9 +268,7 @@ protected DataSource createDataSource(final Multipart parent, final MimePart par final DataSource dataSource = dataHandler.getDataSource(); final String contentType = getBaseMimeType(dataSource.getContentType()); final String dataSourceName = getDataSourceName(part, dataSource); - final AttachmentDataSource result = new AttachmentDataSource(dataSource, contentType, dataSourceName); - System.out.println("New stream: " + result.getInputStream()); - + final LazyByteArrayDataSource result = new LazyByteArrayDataSource(dataSource.getInputStream(), contentType, dataSourceName); return result; } diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index 7831bff30..5469f21f6 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -527,12 +527,11 @@ public void testParseHtmlEmailWithAttachments_size() throws Exception assertNotNull(dataSource); assertEquals("image/jpeg", dataSource.getContentType()); - System.out.println(dataSource.getInputStream().available()); dataSource = mimeMessageParser.findAttachmentByName("it20one.pdf"); assertNotNull(dataSource); assertEquals("application/pdf", dataSource.getContentType()); - System.out.println(dataSource.getInputStream().available()); + } From 8712ae03b5bacee62e1a457c18eec3558afe6de0 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Mon, 27 Feb 2023 21:06:39 +0800 Subject: [PATCH 06/19] EMAIL-204: Update test-cases --- .../commons/mail/LazyByteArrayDataSource.java | 1 + .../commons/mail/util/MimeMessageParser.java | 3 +- .../mail/util/MimeMessageParserTest.java | 109 ++++++++++++------ 3 files changed, 74 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java index 4a046cd50..eb3ddf55b 100644 --- a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java +++ b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java @@ -46,6 +46,7 @@ public InputStream getInputStream() throws IOException { if (ds == null) { //Only read attachment data to memory when getInputStream() is called. ds = new ByteArrayDataSource(referenceInputStream, type); + ds.setName(name); } return ds.getInputStream(); } diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index 7c2da7ea9..4b2ed77ed 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -15,7 +15,7 @@ * limitations under the License. */ package org.apache.commons.mail.util; -import org.apache.commons.mail.AttachmentDataSource; + import org.apache.commons.mail.LazyByteArrayDataSource; import java.io.*; @@ -40,7 +40,6 @@ import javax.mail.internet.MimePart; import javax.mail.internet.MimeUtility; import javax.mail.internet.ParseException; -import javax.mail.util.ByteArrayDataSource; /** * Parses a MimeMessage and stores the individual parts such a plain text, diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index 5469f21f6..253970ef3 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -16,19 +16,24 @@ */ package org.apache.commons.mail.util; +import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.powermock.api.easymock.PowerMock.*; import java.io.File; +import java.io.InputStream; import java.util.List; import java.util.Properties; +import javax.activation.DataHandler; import javax.activation.DataSource; import javax.mail.Session; import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimePart; import org.apache.commons.mail.HtmlEmail; import org.junit.Test; @@ -497,42 +502,72 @@ public void testParseInlineCID() throws Exception assertNotNull(ds); assertEquals(ds, mimeMessageParser.getAttachmentList().get(0)); } - @Test - public void testParseHtmlEmailWithAttachments_size() throws Exception - { - DataSource dataSource; - final Session session = Session.getDefaultInstance(new Properties()); - final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/html-attachment.eml")); - final MimeMessageParser mimeMessageParser = new MimeMessageParser(message); - - mimeMessageParser.parse(); - - assertEquals("Test", mimeMessageParser.getSubject()); - assertNotNull(mimeMessageParser.getMimeMessage()); - assertTrue(mimeMessageParser.isMultipart()); - assertTrue(mimeMessageParser.hasHtmlContent()); - assertTrue(mimeMessageParser.hasPlainContent()); - assertNotNull(mimeMessageParser.getPlainContent()); - assertNotNull(mimeMessageParser.getHtmlContent()); - assertTrue(mimeMessageParser.getTo().size() == 1); - assertTrue(mimeMessageParser.getCc().isEmpty()); - assertTrue(mimeMessageParser.getBcc().isEmpty()); - assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getFrom()); - assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getReplyTo()); - assertTrue(mimeMessageParser.hasAttachments()); - final List attachmentList = mimeMessageParser.getAttachmentList(); - assertTrue(attachmentList.size() == 2); - - dataSource = mimeMessageParser.findAttachmentByName("Wasserlilien.jpg"); - assertNotNull(dataSource); - assertEquals("image/jpeg", dataSource.getContentType()); - - - dataSource = mimeMessageParser.findAttachmentByName("it20one.pdf"); - assertNotNull(dataSource); - assertEquals("application/pdf", dataSource.getContentType()); - - } - +// +// @Test +// public void testAttachmentNotLoaded() throws Exception +// { +// final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); +// +// final InputStream inputStream = createMock(InputStream.class); +// final MimePart mimePart = createMock(MimePart.class); +// final DataHandler dataHandler = createMock(DataHandler.class); +// final DataSource dataSource = createMock(DataSource.class); +// +// expect(dataSource.getContentType()).andReturn("test_type"); +// expect(dataSource.getName()).andReturn("test_name"); +// expect(dataSource.getInputStream()).andReturn(inputStream).once(); +// +// expect(mimePart.getDataHandler()).andReturn(dataHandler); +// expect(dataHandler.getDataSource()).andReturn(dataSource); +// replay(mimePart,dataHandler,dataSource,inputStream); +// +// // Create data source with mock data. +// final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); +// // No inputStream.read() is made as this point (Lazy initialization). +// verify(inputStream); +// +// +// // Assert on no call made to input stream +// // Call a get call on data stream +// +// // Assert now the method call count is 1. +// +// +// } +// +// +// @Test +// public void testAttachmentLoaded() throws Exception +// { +// final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); +// +// final InputStream inputStream = createMock(InputStream.class); +// final MimePart mimePart = createMock(MimePart.class); +// final DataHandler dataHandler = createMock(DataHandler.class); +// final DataSource dataSource = createMock(DataSource.class); +// +// expect(dataSource.getContentType()).andReturn("test_type"); +// expect(dataSource.getName()).andReturn("test_name"); +// expect(dataSource.getInputStream()).andReturn(inputStream).once(); +// // Verify the input stream.read() method call count, as this indicate whether attachment loaded into memory or not. +// expect(inputStream.read(new byte[8192])).andReturn(0).once(); +// +// expect(mimePart.getDataHandler()).andReturn(dataHandler); +// expect(dataHandler.getDataSource()).andReturn(dataSource); +// replay(mimePart,dataHandler,dataSource,inputStream); +// +// // Create data source with mock data. +// final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); +// +// // No matter how many .getInputStream call from the call, it will only load the attachment once, after its frist call. +// dataSource_new.getInputStream(); +// dataSource_new.getInputStream(); +// dataSource_new.getInputStream(); +// // No inputStream.read() is made as this point (Lazy initialization). +// verify(inputStream); +// +// // Assert now the method call count is 1. +// } +// } From 395ca7a62670901555fcfd010101ddcc5b689110 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Mon, 27 Feb 2023 21:12:43 +0800 Subject: [PATCH 07/19] EMAIL-204: Update testcases --- .../mail/util/MimeMessageParserTest.java | 133 +++++++++--------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index 253970ef3..e8a56c853 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -502,72 +502,71 @@ public void testParseInlineCID() throws Exception assertNotNull(ds); assertEquals(ds, mimeMessageParser.getAttachmentList().get(0)); } -// -// @Test -// public void testAttachmentNotLoaded() throws Exception -// { -// final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); -// -// final InputStream inputStream = createMock(InputStream.class); -// final MimePart mimePart = createMock(MimePart.class); -// final DataHandler dataHandler = createMock(DataHandler.class); -// final DataSource dataSource = createMock(DataSource.class); -// -// expect(dataSource.getContentType()).andReturn("test_type"); -// expect(dataSource.getName()).andReturn("test_name"); -// expect(dataSource.getInputStream()).andReturn(inputStream).once(); -// -// expect(mimePart.getDataHandler()).andReturn(dataHandler); -// expect(dataHandler.getDataSource()).andReturn(dataSource); -// replay(mimePart,dataHandler,dataSource,inputStream); -// -// // Create data source with mock data. -// final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); -// // No inputStream.read() is made as this point (Lazy initialization). -// verify(inputStream); -// -// -// // Assert on no call made to input stream -// // Call a get call on data stream -// -// // Assert now the method call count is 1. -// -// -// } -// -// -// @Test -// public void testAttachmentLoaded() throws Exception -// { -// final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); -// -// final InputStream inputStream = createMock(InputStream.class); -// final MimePart mimePart = createMock(MimePart.class); -// final DataHandler dataHandler = createMock(DataHandler.class); -// final DataSource dataSource = createMock(DataSource.class); -// -// expect(dataSource.getContentType()).andReturn("test_type"); -// expect(dataSource.getName()).andReturn("test_name"); -// expect(dataSource.getInputStream()).andReturn(inputStream).once(); -// // Verify the input stream.read() method call count, as this indicate whether attachment loaded into memory or not. -// expect(inputStream.read(new byte[8192])).andReturn(0).once(); -// -// expect(mimePart.getDataHandler()).andReturn(dataHandler); -// expect(dataHandler.getDataSource()).andReturn(dataSource); -// replay(mimePart,dataHandler,dataSource,inputStream); -// -// // Create data source with mock data. -// final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); -// -// // No matter how many .getInputStream call from the call, it will only load the attachment once, after its frist call. -// dataSource_new.getInputStream(); -// dataSource_new.getInputStream(); -// dataSource_new.getInputStream(); -// // No inputStream.read() is made as this point (Lazy initialization). -// verify(inputStream); -// -// // Assert now the method call count is 1. -// } -// + + @Test + public void testAttachmentNotLoaded() throws Exception + { + final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); + + final InputStream inputStream = createMock(InputStream.class); + final MimePart mimePart = createMock(MimePart.class); + final DataHandler dataHandler = createMock(DataHandler.class); + final DataSource dataSource = createMock(DataSource.class); + + expect(dataSource.getContentType()).andReturn("test_type"); + expect(dataSource.getName()).andReturn("test_name"); + expect(dataSource.getInputStream()).andReturn(inputStream).once(); + + expect(mimePart.getDataHandler()).andReturn(dataHandler); + expect(dataHandler.getDataSource()).andReturn(dataSource); + replay(mimePart,dataHandler,dataSource,inputStream); + + // Create data source with mock data. + final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); + // No inputStream.read() is made as this point (Lazy initialization). + verify(inputStream); + + + // Assert on no call made to input stream + // Call a get call on data stream + + // Assert now the method call count is 1. + + + } + + + @Test + public void testAttachmentLoaded() throws Exception + { + final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); + + final InputStream inputStream = createMock(InputStream.class); + final MimePart mimePart = createMock(MimePart.class); + final DataHandler dataHandler = createMock(DataHandler.class); + final DataSource dataSource = createMock(DataSource.class); + + expect(dataSource.getContentType()).andReturn("test_type"); + expect(dataSource.getName()).andReturn("test_name"); + expect(dataSource.getInputStream()).andReturn(inputStream).once(); + // Verify the input stream.read() method call count, as this indicate whether attachment loaded into memory or not. + expect(inputStream.read(new byte[8192])).andReturn(0).once(); + + expect(mimePart.getDataHandler()).andReturn(dataHandler); + expect(dataHandler.getDataSource()).andReturn(dataSource); + replay(mimePart,dataHandler,dataSource,inputStream); + + // Create data source with mock data. + final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); + + // No matter how many .getInputStream call from the call, it will only load the attachment once, after its frist call. + dataSource_new.getInputStream(); + dataSource_new.getInputStream(); + dataSource_new.getInputStream(); + // No inputStream.read() is made as this point (Lazy initialization). + verify(inputStream); + + } + } From 44c8ae5e496c54f1fb442a380944fefff1f3cb09 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 00:38:14 +0800 Subject: [PATCH 08/19] EMAIL-204: Java doc --- .../commons/mail/LazyByteArrayDataSource.java | 52 ++++++++++++++++--- .../commons/mail/SendWithAttachmentsTest.java | 2 +- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java index eb3ddf55b..6221e45d0 100644 --- a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java +++ b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java @@ -23,24 +23,46 @@ import java.io.OutputStream; /** - * Proxy dataSource class which contain reference of MimePartDataSource for given attachment, - * with revised type and name, in order delay the memory allocation for attachment until when the content of the attachment is needed. + *

Wrapper class for ByteArrayDataSource, which contain reference of MimePartDataSource for given attachment. + * Both type and name are duplicated stored in this class, in order to delay the load of attachment binary till getInputStream() is called. + *

* - * @since 1.3 + * @since 1.5 */ public class LazyByteArrayDataSource implements DataSource { - private InputStream referenceInputStream; + /** InputStream reference for the email attachment binary. */ + private final InputStream referenceInputStream; + + /** ByteArrayDateSource instance which contain email attachment binary in the form of byte array. */ private ByteArrayDataSource ds; - private String type; - private String name; + /** Name of the attachment. */ + private final String name; + + /** Type of the attachment. */ + private final String type; + + + /** + * Constructor for this class to read all necessary information for an email attachment. + * + * @param is the InputStream which represent the attachment binary. + * @param type the type of the attachment. + * @param name the name of the attachment. + */ public LazyByteArrayDataSource(InputStream is, String type, String name) { this.referenceInputStream = is; this.type = type; this.name = name; } + /** + * To return an {@code ByteArrayDataSource} instance which represent the email attachment. + * + * @return An ByteArrayDataSource instance which contain the email attachment. + * @throws IOException resolving the email attachment failed + */ @Override public InputStream getInputStream() throws IOException { if (ds == null) { @@ -51,16 +73,34 @@ public InputStream getInputStream() throws IOException { return ds.getInputStream(); } + /** + * Not supported. + * + * @return N/A + * @since 1.5 + */ @Override public OutputStream getOutputStream() throws IOException { throw new IOException("cannot do this"); } + /** + * Get the content type. + * + * @return A String. + * @since 1.5 + */ @Override public String getContentType() { return type; } + /** + * Get the name. + * + * @return A String. + * @since 1.5 + */ @Override public String getName() { return name; diff --git a/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java b/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java index 17e9be581..cbded0b8c 100644 --- a/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java +++ b/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java @@ -44,7 +44,7 @@ public void setUpSendWithAttachmentsTest() } /** - * @throws EmailException on an email error + * @throws EmailException on a¡n email error * @throws IOException when sending fails, or a bad URL is used */ @Test From e5e3b06b9cd8719cbd302cefc3263446dd2b481b Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 00:55:46 +0800 Subject: [PATCH 09/19] EMAIL-204: Update testcase --- .../mail/util/MimeMessageParserTest.java | 63 ++++++++----------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index e8a56c853..abbc5f72b 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -507,41 +507,45 @@ public void testParseInlineCID() throws Exception public void testAttachmentNotLoaded() throws Exception { final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); - final InputStream inputStream = createMock(InputStream.class); - final MimePart mimePart = createMock(MimePart.class); - final DataHandler dataHandler = createMock(DataHandler.class); - final DataSource dataSource = createMock(DataSource.class); + final MimePart mimePart = getMockedMimePart(inputStream); - expect(dataSource.getContentType()).andReturn("test_type"); - expect(dataSource.getName()).andReturn("test_name"); - expect(dataSource.getInputStream()).andReturn(inputStream).once(); - - expect(mimePart.getDataHandler()).andReturn(dataHandler); - expect(dataHandler.getDataSource()).andReturn(dataSource); - replay(mimePart,dataHandler,dataSource,inputStream); - - // Create data source with mock data. + // Create data source with mocked data. final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); - // No inputStream.read() is made as this point (Lazy initialization). + // Verify no inputStream.read() is made at this point (Lazy initialization). verify(inputStream); + } - // Assert on no call made to input stream - // Call a get call on data stream + @Test + public void testAttachmentLoaded() throws Exception + { + final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); + final InputStream inputStream = createMock(InputStream.class); + // Despite .getInputStream() called for 3 times, but the desk IO for attachment read should only happen once. + expect(inputStream.read(new byte[8192])).andReturn(0).once(); + final MimePart mimePart = getMockedMimePart(inputStream); - // Assert now the method call count is 1. + // Create data source with mocked data. + final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); + dataSource_new.getInputStream(); + dataSource_new.getInputStream(); + dataSource_new.getInputStream(); + // To make sure disk IO only happen when .getInputStream() invoked for first time but during the object construction. + verify(inputStream); } - - @Test - public void testAttachmentLoaded() throws Exception + /** + * Helper method to return a mocked MimePart class. + * @param inputStream Mocked input stream + * @return Mocked MimePart instance. + * @throws Exception When attachment read failed. + */ + private MimePart getMockedMimePart(InputStream inputStream) throws Exception { - final MimeMessageParser mimeMessageParser = new MimeMessageParser(null); - final InputStream inputStream = createMock(InputStream.class); final MimePart mimePart = createMock(MimePart.class); final DataHandler dataHandler = createMock(DataHandler.class); final DataSource dataSource = createMock(DataSource.class); @@ -549,24 +553,11 @@ public void testAttachmentLoaded() throws Exception expect(dataSource.getContentType()).andReturn("test_type"); expect(dataSource.getName()).andReturn("test_name"); expect(dataSource.getInputStream()).andReturn(inputStream).once(); - // Verify the input stream.read() method call count, as this indicate whether attachment loaded into memory or not. - expect(inputStream.read(new byte[8192])).andReturn(0).once(); - expect(mimePart.getDataHandler()).andReturn(dataHandler); expect(dataHandler.getDataSource()).andReturn(dataSource); replay(mimePart,dataHandler,dataSource,inputStream); - // Create data source with mock data. - final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); - - // No matter how many .getInputStream call from the call, it will only load the attachment once, after its frist call. - dataSource_new.getInputStream(); - dataSource_new.getInputStream(); - dataSource_new.getInputStream(); - // No inputStream.read() is made as this point (Lazy initialization). - verify(inputStream); - + return mimePart; } - } From eb2673fcb7900bdd5b966553c7c60f75d1e914fe Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 01:01:04 +0800 Subject: [PATCH 10/19] EMAIL-204: Remove unused class --- .../commons/mail/AttachmentDataSource.java | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 src/main/java/org/apache/commons/mail/AttachmentDataSource.java diff --git a/src/main/java/org/apache/commons/mail/AttachmentDataSource.java b/src/main/java/org/apache/commons/mail/AttachmentDataSource.java deleted file mode 100644 index cc7db455c..000000000 --- a/src/main/java/org/apache/commons/mail/AttachmentDataSource.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.commons.mail; - -import javax.activation.DataSource; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Proxy dataSource class which contain reference of MimePartDataSource for given attachment, - * with revised type and name, in order delay the memory allocation for attachment until when the content of the attachment is needed. - * - * @since 1.3 - */ -public class AttachmentDataSource implements DataSource { - - - private String type; // content-type - private String name = ""; - private DataSource ds; - - - public AttachmentDataSource(DataSource ds, String type, String name) { - - this.ds = ds; - this.type = type; - this.name = name; - } - - @Override - public InputStream getInputStream() throws IOException { - if (ds == null) { - throw new IOException("no data available"); - } else{ - return ds.getInputStream(); - } - } - - @Override - public OutputStream getOutputStream() throws IOException { - throw new IOException("cannot do this"); - } - - @Override - public String getContentType() { - return type; - } - - @Override - public String getName() { - return name; - } -} From 0af61604bf06ad8cf960bd894886f8e9e1dce65c Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 01:04:04 +0800 Subject: [PATCH 11/19] EMAIL-204: Update import --- .../java/org/apache/commons/mail/util/MimeMessageParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index 4b2ed77ed..3df938ab4 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -18,7 +18,9 @@ import org.apache.commons.mail.LazyByteArrayDataSource; -import java.io.*; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; From 6bb26b6bf011ee0b6873697381eb186d39114016 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 01:05:13 +0800 Subject: [PATCH 12/19] EMAIL-204: Update code style --- .../java/org/apache/commons/mail/SendWithAttachmentsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java b/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java index cbded0b8c..17e9be581 100644 --- a/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java +++ b/src/test/java/org/apache/commons/mail/SendWithAttachmentsTest.java @@ -44,7 +44,7 @@ public void setUpSendWithAttachmentsTest() } /** - * @throws EmailException on a¡n email error + * @throws EmailException on an email error * @throws IOException when sending fails, or a bad URL is used */ @Test From 286bd35b98ffeee5fa64956cb62384d4a4853bd4 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 01:07:16 +0800 Subject: [PATCH 13/19] EMAIL-204: Update import --- .../java/org/apache/commons/mail/util/MimeMessageParser.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index 3df938ab4..fa061b984 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; From 23ba449b6ab32238ede682866abbebf90a2bad4e Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Fri, 3 Mar 2023 01:15:57 +0800 Subject: [PATCH 14/19] EMAIL-204: Typo --- .../org/apache/commons/mail/util/MimeMessageParserTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index abbc5f72b..ffae7f433 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -532,7 +532,7 @@ public void testAttachmentLoaded() throws Exception dataSource_new.getInputStream(); dataSource_new.getInputStream(); dataSource_new.getInputStream(); - // To make sure disk IO only happen when .getInputStream() invoked for first time but during the object construction. + // To make sure disk IO only happen when .getInputStream() invoked for first time but not during the object construction. verify(inputStream); } From 5dbcc5f93844a702d9eff02123e0ac2d0e3feef7 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Sat, 4 Mar 2023 13:09:50 +0800 Subject: [PATCH 15/19] EMAIL-204: Code style fix --- .../apache/commons/mail/LazyByteArrayDataSource.java | 12 ++++-------- .../apache/commons/mail/util/MimeMessageParser.java | 3 +-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java index 6221e45d0..4610cfdf3 100644 --- a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java +++ b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java @@ -43,7 +43,6 @@ public class LazyByteArrayDataSource implements DataSource { /** Type of the attachment. */ private final String type; - /** * Constructor for this class to read all necessary information for an email attachment. * @@ -77,18 +76,16 @@ public InputStream getInputStream() throws IOException { * Not supported. * * @return N/A - * @since 1.5 */ @Override - public OutputStream getOutputStream() throws IOException { - throw new IOException("cannot do this"); + public OutputStream getOutputStream() throws UnsupportedOperationException { + throw new UnsupportedOperationException("cannot do this"); } /** - * Get the content type. + * Gets the content type. * * @return A String. - * @since 1.5 */ @Override public String getContentType() { @@ -96,10 +93,9 @@ public String getContentType() { } /** - * Get the name. + * Gets the name. * * @return A String. - * @since 1.5 */ @Override public String getName() { diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java index fa061b984..3ac50c455 100644 --- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java +++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java @@ -268,8 +268,7 @@ protected DataSource createDataSource(final Multipart parent, final MimePart par final DataSource dataSource = dataHandler.getDataSource(); final String contentType = getBaseMimeType(dataSource.getContentType()); final String dataSourceName = getDataSourceName(part, dataSource); - final LazyByteArrayDataSource result = new LazyByteArrayDataSource(dataSource.getInputStream(), contentType, dataSourceName); - return result; + return new LazyByteArrayDataSource(dataSource.getInputStream(), contentType, dataSourceName); } /** @return Returns the mimeMessage. */ From 1685f0747d170ac88e36889d89d4360c77af1776 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Sat, 4 Mar 2023 13:11:41 +0800 Subject: [PATCH 16/19] EMAIL-204: Update testcase --- .../commons/mail/util/MimeMessageParserTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index ffae7f433..424f0ee1e 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -511,8 +511,8 @@ public void testAttachmentNotLoaded() throws Exception final MimePart mimePart = getMockedMimePart(inputStream); // Create data source with mocked data. - final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); - // Verify no inputStream.read() is made at this point (Lazy initialization). + final DataSource dataSource = mimeMessageParser.createDataSource(null,mimePart); + // Verify no inputStream.read() call is made at this point (Lazy initialization). verify(inputStream); } @@ -527,11 +527,11 @@ public void testAttachmentLoaded() throws Exception final MimePart mimePart = getMockedMimePart(inputStream); // Create data source with mocked data. - final DataSource dataSource_new = mimeMessageParser.createDataSource(null,mimePart); + final DataSource dataSource = mimeMessageParser.createDataSource(null,mimePart); - dataSource_new.getInputStream(); - dataSource_new.getInputStream(); - dataSource_new.getInputStream(); + dataSource.getInputStream(); + dataSource.getInputStream(); + dataSource.getInputStream(); // To make sure disk IO only happen when .getInputStream() invoked for first time but not during the object construction. verify(inputStream); From c101e966c0db3c5f14800da0447ae783a9f545f1 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Sat, 4 Mar 2023 13:36:49 +0800 Subject: [PATCH 17/19] EMAIL-204: Update java doc --- .../apache/commons/mail/LazyByteArrayDataSource.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java index 4610cfdf3..e3b4d7966 100644 --- a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java +++ b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java @@ -23,9 +23,11 @@ import java.io.OutputStream; /** - *

Wrapper class for ByteArrayDataSource, which contain reference of MimePartDataSource for given attachment. - * Both type and name are duplicated stored in this class, in order to delay the load of attachment binary till getInputStream() is called. - *

+ *

The class is created to replace the usage of {@code org.apache.commons.mail.ByteArrayDataSource} and {@code javax.mail.util.ByteArrayDataSource}, + * as both implementations load attachment binary in eager manner. + * + *

In order to cater the scenario that user only access the metadata (Name, Type) but not interested in the actual attachment binary, + * in this scenario, the memory usage can be further reduced as attachment binary only loaded when .getInputStream() called. * * @since 1.5 */ @@ -57,13 +59,13 @@ public LazyByteArrayDataSource(InputStream is, String type, String name) { } /** - * To return an {@code ByteArrayDataSource} instance which represent the email attachment. + * Gets an {@code ByteArrayDataSource} instance, to represent the email attachment. * * @return An ByteArrayDataSource instance which contain the email attachment. * @throws IOException resolving the email attachment failed */ @Override - public InputStream getInputStream() throws IOException { + public synchronized InputStream getInputStream() throws IOException { if (ds == null) { //Only read attachment data to memory when getInputStream() is called. ds = new ByteArrayDataSource(referenceInputStream, type); From e5164d8814e6174dd8b1a3b764b45321104b36b9 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Sat, 4 Mar 2023 13:40:59 +0800 Subject: [PATCH 18/19] EMAIL-204: Update test import --- .../java/org/apache/commons/mail/LazyByteArrayDataSource.java | 4 ++-- .../org/apache/commons/mail/util/MimeMessageParserTest.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java index e3b4d7966..cd4586f83 100644 --- a/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java +++ b/src/main/java/org/apache/commons/mail/LazyByteArrayDataSource.java @@ -23,7 +23,7 @@ import java.io.OutputStream; /** - *

The class is created to replace the usage of {@code org.apache.commons.mail.ByteArrayDataSource} and {@code javax.mail.util.ByteArrayDataSource}, + *

This class is created to replace the usage of {@code org.apache.commons.mail.ByteArrayDataSource} and {@code javax.mail.util.ByteArrayDataSource}, * as both implementations load attachment binary in eager manner. * *

In order to cater the scenario that user only access the metadata (Name, Type) but not interested in the actual attachment binary, @@ -46,7 +46,7 @@ public class LazyByteArrayDataSource implements DataSource { private final String type; /** - * Constructor for this class to read all necessary information for an email attachment. + * Constructs a new instance to read all necessary information for an email attachment. * * @param is the InputStream which represent the attachment binary. * @param type the type of the attachment. diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index 424f0ee1e..009ce0f6b 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -16,13 +16,15 @@ */ package org.apache.commons.mail.util; +import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.powermock.api.easymock.PowerMock.*; import java.io.File; import java.io.InputStream; From 094a2b3db0b93bb403b687bfcbd45422a9907bc6 Mon Sep 17 00:00:00 2001 From: HiuFung Kwok Date: Sun, 5 Mar 2023 00:30:37 +0800 Subject: [PATCH 19/19] EMAIL-204: Update test-case --- .../org/apache/commons/mail/util/MimeMessageParserTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java index 009ce0f6b..7b47747da 100644 --- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java +++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java @@ -549,15 +549,14 @@ private MimePart getMockedMimePart(InputStream inputStream) throws Exception { final MimePart mimePart = createMock(MimePart.class); - final DataHandler dataHandler = createMock(DataHandler.class); final DataSource dataSource = createMock(DataSource.class); + final DataHandler dataHandler = new DataHandler(dataSource); expect(dataSource.getContentType()).andReturn("test_type"); expect(dataSource.getName()).andReturn("test_name"); expect(dataSource.getInputStream()).andReturn(inputStream).once(); expect(mimePart.getDataHandler()).andReturn(dataHandler); - expect(dataHandler.getDataSource()).andReturn(dataSource); - replay(mimePart,dataHandler,dataSource,inputStream); + replay(mimePart,dataSource,inputStream); return mimePart; }