Skip to content

Commit 8632308

Browse files
committed
#219, #249, #310, #351: Properly fix support for duplicate file names this time
1 parent 968ce45 commit 8632308

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.simplejavamail.internal.util;
2+
3+
import java.util.Comparator;
4+
import java.util.Map;
5+
6+
public class NaturalEntryKeyComparator<T extends Comparable<T>> implements Comparator<Map.Entry<T, Object>> {
7+
8+
public static final NaturalEntryKeyComparator INSTANCE = new NaturalEntryKeyComparator();
9+
10+
// TODO Lombok
11+
private NaturalEntryKeyComparator(){
12+
}
13+
14+
15+
@Override
16+
public int compare(Map.Entry<T, Object> o1, Map.Entry<T, Object> o2) {
17+
int keyComparison = o1.getKey().compareTo(o2.getKey());
18+
if (keyComparison != 0) {
19+
return keyComparison;
20+
}
21+
return Integer.compare(o1.getValue().hashCode(), o2.getValue().hashCode());
22+
}
23+
}

modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ private static EmailPopulatingBuilder buildEmailFromMimeMessage(@NotNull final E
682682
final String cidName = checkNonEmptyArgument(cid.getKey(), "cid.key");
683683
builder.withEmbeddedImage(extractCID(cidName), cid.getValue());
684684
}
685-
for (final Map.Entry<String, DataSource> attachment : parsed.getAttachmentList().entrySet()) {
685+
for (final Map.Entry<String, DataSource> attachment : parsed.getAttachmentList()) {
686686
builder.withAttachment(extractCID(attachment.getKey()), attachment.getValue());
687687
}
688688
return builder;

modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParser.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.jetbrains.annotations.NotNull;
55
import org.jetbrains.annotations.Nullable;
66
import org.simplejavamail.internal.util.MiscUtil;
7+
import org.simplejavamail.internal.util.NaturalEntryKeyComparator;
78
import org.simplejavamail.internal.util.Preconditions;
89

910
import javax.activation.ActivationDataFlavor;
@@ -29,6 +30,7 @@
2930
import java.io.IOException;
3031
import java.io.InputStream;
3132
import java.io.UnsupportedEncodingException;
33+
import java.util.AbstractMap.SimpleEntry;
3234
import java.util.ArrayList;
3335
import java.util.Arrays;
3436
import java.util.Collection;
@@ -38,7 +40,9 @@
3840
import java.util.Iterator;
3941
import java.util.List;
4042
import java.util.Map;
43+
import java.util.Set;
4144
import java.util.TreeMap;
45+
import java.util.TreeSet;
4246
import java.util.regex.Matcher;
4347
import java.util.regex.Pattern;
4448

@@ -160,13 +164,13 @@ private static void parseMimePartTree(@NotNull final MimePart currentPart, @NotN
160164
final DataSource ds = createDataSource(currentPart, fetchAttachmentData);
161165
// if the diposition is not provided, for now the part should be treated as inline (later non-embedded inline attachments are moved)
162166
if (Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
163-
parsedComponents.attachmentList.put(parseResourceNameOrUnnamed(parseContentID(currentPart), parseFileName(currentPart)), ds);
167+
parsedComponents.attachmentList.add(new SimpleEntry<>(parseResourceNameOrUnnamed(parseContentID(currentPart), parseFileName(currentPart)), ds));
164168
} else if (disposition == null || Part.INLINE.equalsIgnoreCase(disposition)) {
165169
if (parseContentID(currentPart) != null) {
166170
parsedComponents.cidMap.put(parseContentID(currentPart), ds);
167171
} else {
168172
// contentID missing -> treat as standard attachment
169-
parsedComponents.attachmentList.put(parseResourceNameOrUnnamed(null, parseFileName(currentPart)), ds);
173+
parsedComponents.attachmentList.add(new SimpleEntry<>(parseResourceNameOrUnnamed(null, parseFileName(currentPart)), ds));
170174
}
171175
} else {
172176
throw new IllegalStateException("invalid attachment type");
@@ -549,14 +553,15 @@ static void moveInvalidEmbeddedResourcesToAttachments(ParsedMimeMessageComponent
549553
Map.Entry<String, DataSource> cidEntry = it.next();
550554
String cid = extractCID(cidEntry.getKey());
551555
if (!htmlContent.contains("cid:" + cid)) {
552-
parsedComponents.attachmentList.put(cid, cidEntry.getValue());
556+
parsedComponents.attachmentList.add(new SimpleEntry<>(cid, cidEntry.getValue()));
553557
it.remove();
554558
}
555559
}
556560
}
557561

558562
public static class ParsedMimeMessageComponents {
559-
final Map<String, DataSource> attachmentList = new TreeMap<>();
563+
@SuppressWarnings("unchecked")
564+
final Set<Map.Entry<String, DataSource>> attachmentList = new TreeSet<>(NaturalEntryKeyComparator.INSTANCE);
560565
final Map<String, DataSource> cidMap = new TreeMap<>();
561566
private final Map<String, Collection<Object>> headers = new HashMap<>();
562567
private final List<InternetAddress> toAddresses = new ArrayList<>();
@@ -580,7 +585,7 @@ public String getMessageId() {
580585
return messageId;
581586
}
582587

583-
public Map<String, DataSource> getAttachmentList() {
588+
public Set<Map.Entry<String, DataSource>> getAttachmentList() {
584589
return attachmentList;
585590
}
586591

modules/simple-java-mail/src/test/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParserTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public void testBasicParsing()
6666
assertThat(mimeMessageParts.getSentDate()).isBetween(receiveWindowStart.getTime(), new Date());
6767

6868
assertThat(mimeMessageParts.getCidMap()).containsOnlyKeys("<thumbsup>");
69-
assertThat(mimeMessageParts.getAttachmentList()).containsOnlyKeys("dresscode.txt", "location.txt");
69+
assertThat(mimeMessageParts.getAttachmentList()).extracting("key").containsOnly("dresscode.txt", "location.txt");
7070
}
7171

7272
@Test
@@ -78,7 +78,7 @@ public void testAttachmentNameResolution()
7878
assertThat(components.getHtmlContent()).isNull();
7979
assertThat(components.getPlainContent()).isEqualTo("body text");
8080
assertThat(components.getCidMap()).isEmpty();
81-
assertThat(components.getAttachmentList()).containsOnlyKeys("proper-name.txt");
81+
assertThat(components.getAttachmentList()).extracting("key").containsOnly("proper-name.txt");
8282
}
8383

8484
private MimeMessage produceMimeMessageWithNamingIssue()
@@ -126,7 +126,7 @@ public void testMoveInvalidEmbeddedResourcesToAttachments_NoHtmlNoInvalid() thro
126126
moveInvalidEmbeddedResourcesToAttachments(parsedComponents);
127127

128128
assertThat(parsedComponents.cidMap).isEmpty();
129-
assertThat(parsedComponents.attachmentList).containsKeys("moo1", "moo2");
129+
assertThat(parsedComponents.attachmentList).extracting("key").containsOnly("moo1", "moo2");
130130
}
131131

132132
@Test
@@ -138,7 +138,7 @@ public void testMoveInvalidEmbeddedResourcesToAttachments_HtmlButNoInvalid() thr
138138
moveInvalidEmbeddedResourcesToAttachments(parsedComponents);
139139

140140
assertThat(parsedComponents.cidMap).isEmpty();
141-
assertThat(parsedComponents.attachmentList).containsOnlyKeys("moo1", "moo2");
141+
assertThat(parsedComponents.attachmentList).extracting("key").containsOnly("moo1", "moo2");
142142
}
143143

144144
@Test
@@ -150,7 +150,7 @@ public void testMoveInvalidEmbeddedResourcesToAttachments_Invalid() throws IOExc
150150
moveInvalidEmbeddedResourcesToAttachments(parsedComponents);
151151

152152
assertThat(parsedComponents.cidMap).containsOnlyKeys("moo1");
153-
assertThat(parsedComponents.attachmentList).containsOnlyKeys("moo2");
153+
assertThat(parsedComponents.attachmentList).extracting("key").containsOnly("moo2");
154154
}
155155

156156
@Test

0 commit comments

Comments
 (0)