MAILET-115 Moving subject prefixing from AbstractRedirect to MimeMessageModifier
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/82625a9b Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/82625a9b Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/82625a9b Branch: refs/heads/master Commit: 82625a9b30b41a2d021fcd4a1131ec63d8ec63a2 Parents: 90cb230 Author: Benoit Tellier <[email protected]> Authored: Tue Oct 25 17:06:08 2016 +0200 Committer: Benoit Tellier <[email protected]> Committed: Wed Jan 11 10:03:28 2017 +0700 ---------------------------------------------------------------------- mailet/pom.xml | 3 +- .../utils/CharsetFromSubjectMailHeader.java | 65 +++++++++++++++ .../mailets/utils/MimeMessageModifier.java | 37 +++++++-- .../utils/CharsetFromSubjectMailHeaderTest.java | 85 ++++++++++++++++++++ .../mailets/utils/MimeMessageModifierTest.java | 81 +++++++++++++++++++ .../apache/james/transport/mailets/Forward.java | 7 +- .../james/transport/mailets/Redirect.java | 7 +- .../apache/james/transport/mailets/Resend.java | 7 +- .../mailets/redirect/AbstractRedirect.java | 76 ----------------- .../redirect/CharsetFromSubjectMailHeader.java | 65 --------------- .../CharsetFromSubjectMailHeaderTest.java | 85 -------------------- 11 files changed, 273 insertions(+), 245 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/mailet/pom.xml ---------------------------------------------------------------------- diff --git a/mailet/pom.xml b/mailet/pom.xml index e2dd161..e9aabdf 100644 --- a/mailet/pom.xml +++ b/mailet/pom.xml @@ -56,6 +56,7 @@ <mime4j.version>0.8.0</mime4j.version> <qdox.version>1.12.1</qdox.version> <assertj-1.version>1.7.1</assertj-1.version> + <assertj-1-guava.version>1.3.1</assertj-1-guava.version> <slf4j.version>1.7.7</slf4j.version> </properties> @@ -160,7 +161,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-guava</artifactId> - <version>1.3.1</version> + <version>${assertj-1-guava.version}</version> </dependency> <dependency> <groupId>com.thoughtworks.qdox</groupId> http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeader.java ---------------------------------------------------------------------- diff --git a/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeader.java b/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeader.java new file mode 100644 index 0000000..fa1825a --- /dev/null +++ b/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeader.java @@ -0,0 +1,65 @@ +/**************************************************************** + * 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.james.transport.mailets.utils; + +import com.google.common.base.Optional; +import com.google.common.base.Strings; + +public class CharsetFromSubjectMailHeader { + + + /** + * It attempts to determine the charset used to encode an "unstructured" RFC + * 822 header (like Subject). The encoding is specified in RFC 2047. If it + * cannot determine or the the text is not encoded then it returns null. + * <p/> + * Here is an example raw text: Subject: + * =?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?= + * + * @param subject the raw (not decoded) value of the header. Null means that the + * header was not present (in this case it always return null). + * @return the MIME charset name or null if no encoding applied + */ + public Optional<String> parse(String subject) { + if (Strings.isNullOrEmpty(subject)) { + return Optional.absent(); + } + int iEncodingPrefix = subject.indexOf("=?"); + if (iEncodingPrefix == -1) { + return Optional.absent(); + } + int iCharsetBegin = iEncodingPrefix + 2; + int iSecondQuestionMark = subject.indexOf('?', iCharsetBegin); + if (iSecondQuestionMark == -1) { + return Optional.absent(); + } + if (iSecondQuestionMark == iCharsetBegin) { + return Optional.absent(); + } + int iThirdQuestionMark = subject.indexOf('?', iSecondQuestionMark + 1); + if (iThirdQuestionMark == -1) { + return Optional.absent(); + } + if (subject.indexOf("?=", iThirdQuestionMark + 1) == -1) { + return Optional.absent(); + } + return Optional.of(subject.substring(iCharsetBegin, iSecondQuestionMark)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/MimeMessageModifier.java ---------------------------------------------------------------------- diff --git a/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/MimeMessageModifier.java b/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/MimeMessageModifier.java index efaf596..1d0692f 100644 --- a/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/MimeMessageModifier.java +++ b/mailet/standard/src/main/java/org/apache/james/transport/mailets/utils/MimeMessageModifier.java @@ -22,8 +22,12 @@ package org.apache.james.transport.mailets.utils; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import org.apache.mailet.Mail; + import com.google.common.base.Charsets; import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.google.common.base.Strings; public class MimeMessageModifier { @@ -34,7 +38,7 @@ public class MimeMessageModifier { } public void addSubjectPrefix(String subjectPrefix) throws MessagingException { - String newSubject = prefixSubject(message, subjectPrefix); + String newSubject = prefixSubject(message.getSubject(), subjectPrefix); replaceSubject(message, newSubject); } @@ -42,14 +46,35 @@ public class MimeMessageModifier { message.setSubject(null); message.setSubject(newSubject, Charsets.UTF_8.displayName()); } - - private String prefixSubject(MimeMessage message, String subjectPrefix) throws MessagingException { - String subject = message.getSubject(); - - if (subject != null) { + + private static String prefixSubject(String subject, String subjectPrefix) throws MessagingException { + if (!Strings.isNullOrEmpty(subject)) { return Joiner.on(' ').join(subjectPrefix, subject); } else { return subjectPrefix; } } + + public void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail originalMail, String subject) throws MessagingException { + Optional<String> newSubject = buildNewSubject(subjectPrefix, originalMail.getMessage().getSubject(), subject); + if (newSubject.isPresent()) { + replaceSubject(newMail.getMessage(), newSubject.get()); + } + } + + public static Optional<String> buildNewSubject(String subjectPrefix, String originalSubject, String subject) throws MessagingException { + String nullablePrefix = Strings.emptyToNull(subjectPrefix); + if (nullablePrefix == null && subject == null) { + return Optional.absent(); + } + if (nullablePrefix == null) { + return Optional.of(subject); + } + String chosenSubject = chooseSubject(subject, originalSubject); + return Optional.of(prefixSubject(chosenSubject, nullablePrefix)); + } + + private static String chooseSubject(String newSubject, String originalSubject) { + return Optional.fromNullable(newSubject).or(originalSubject); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeaderTest.java ---------------------------------------------------------------------- diff --git a/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeaderTest.java b/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeaderTest.java new file mode 100644 index 0000000..e3e0177 --- /dev/null +++ b/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/CharsetFromSubjectMailHeaderTest.java @@ -0,0 +1,85 @@ +/**************************************************************** + * 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.james.transport.mailets.utils; + +import static org.assertj.guava.api.Assertions.assertThat; + +import org.junit.Test; + +import com.google.common.base.Optional; + +public class CharsetFromSubjectMailHeaderTest { + + @Test + public void parseShouldReturnAbsentWhenRawTextIsNull() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse(null); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnAbsentWhenRawTextIsEmpty() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse(""); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnAbsentWhenRawTextDoesNotContainEncodingPrefix() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse("iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?="); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnAbsentWhenRawTextDoesNotContainSecondQuestionMark() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2"); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnAbsentWhenRawTextDoesNotContainCharset() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=??"); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnAbsentWhenRawTextDoesNotContainThirdQuestionMark() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2?"); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnAbsentWhenRawTextDoesNotContainClosingTag() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel"); + + assertThat(charset).isAbsent(); + } + + @Test + public void parseShouldReturnCharsetWhenRawTextIsWellFormatted() { + Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?="); + + assertThat(charset).contains("iso-8859-2"); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/MimeMessageModifierTest.java ---------------------------------------------------------------------- diff --git a/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/MimeMessageModifierTest.java b/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/MimeMessageModifierTest.java index 5b17964..d80fd30 100644 --- a/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/MimeMessageModifierTest.java +++ b/mailet/standard/src/test/java/org/apache/james/transport/mailets/utils/MimeMessageModifierTest.java @@ -26,8 +26,11 @@ import java.util.Properties; import javax.mail.Session; import javax.mail.internet.MimeMessage; +import org.apache.mailet.base.test.FakeMail; import org.junit.Test; +import com.google.common.base.Optional; + public class MimeMessageModifierTest { @Test @@ -48,4 +51,82 @@ public class MimeMessageModifierTest { assertThat(message.getSubject()).isEqualTo("my"); } + + @Test + public void setSubjectPrefixShouldNotAlterSubjectWhenNullPrefix() throws Exception { + MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties())); + message.setSubject("original subject"); + FakeMail newMail = FakeMail.from(message); + FakeMail oldMail = FakeMail.from(message); + String subjectPrefix = null; + String subject = null; + + new MimeMessageModifier(message).setSubjectPrefix(newMail, subjectPrefix, oldMail, subject); + + assertThat(message.getSubject()).isEqualTo("original subject"); + } + + @Test + public void setSubjectPrefixShouldNotAlterSubjectWhenEmptyPrefix() throws Exception { + MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties())); + message.setSubject("original subject"); + FakeMail newMail = FakeMail.from(message); + FakeMail oldMail = FakeMail.from(message); + String subjectPrefix = ""; + String subject = null; + + new MimeMessageModifier(message).setSubjectPrefix(newMail, subjectPrefix, oldMail, subject); + + assertThat(message.getSubject()).isEqualTo("original subject"); + } + + + @Test + public void buildNewSubjectShouldPrefixOriginalSubjectWhenSubjectIsNull() throws Exception { + String prefix = "prefix"; + String originalSubject = "original subject"; + Optional<String> newSubject = MimeMessageModifier.buildNewSubject(prefix, originalSubject, null); + + assertThat(newSubject.get()).isEqualTo(prefix + " " + originalSubject); + } + + @Test + public void buildNewSubjectShouldPrefixNewSubjectWhenSubjectIsGiven() throws Exception { + String prefix = "prefix"; + String originalSubject = "original subject"; + String subject = "new subject"; + Optional<String> newSubject = MimeMessageModifier.buildNewSubject(prefix, originalSubject, subject); + + assertThat(newSubject.get()).isEqualTo(prefix + " " + subject); + } + + @Test + public void buildNewSubjectShouldReplaceSubjectWhenPrefixIsNull() throws Exception { + String prefix = null; + String originalSubject = "original subject"; + String subject = "new subject"; + Optional<String> newSubject = MimeMessageModifier.buildNewSubject(prefix, originalSubject, subject); + + assertThat(newSubject.get()).isEqualTo(subject); + } + + @Test + public void buildNewSubjectShouldReplaceSubjectWhenPrefixIsEmpty() throws Exception { + String prefix = ""; + String originalSubject = "original subject"; + String subject = "new subject"; + Optional<String> newSubject = MimeMessageModifier.buildNewSubject(prefix, originalSubject, subject); + + assertThat(newSubject.get()).isEqualTo(subject); + } + + @Test + public void buildNewSubjectShouldReplaceSubjectWithPrefixWhenSubjectIsEmpty() throws Exception { + String prefix = "prefix"; + String originalSubject = "original subject"; + String subject = ""; + Optional<String> newSubject = MimeMessageModifier.buildNewSubject(prefix, originalSubject, subject); + + assertThat(newSubject.get()).isEqualTo(prefix); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Forward.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Forward.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Forward.java index 7d1c2b3..d2630ef 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Forward.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Forward.java @@ -31,6 +31,7 @@ import org.apache.james.transport.mailets.redirect.AddressExtractor; import org.apache.james.transport.mailets.redirect.InitParameters; import org.apache.james.transport.mailets.redirect.RedirectMailetInitParameters; import org.apache.james.transport.mailets.redirect.TypeCode; +import org.apache.james.transport.mailets.utils.MimeMessageModifier; import org.apache.mailet.Mail; import org.apache.mailet.MailAddress; @@ -175,9 +176,7 @@ public class Forward extends AbstractRedirect { @Override protected void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail originalMail) throws MessagingException { - Optional<String> newSubject = getNewSubject(subjectPrefix, originalMail); - if (newSubject.isPresent()) { - changeSubject(newMail.getMessage(), newSubject.get()); - } + new MimeMessageModifier(newMail.getMessage()) + .setSubjectPrefix(newMail, subjectPrefix, originalMail, getInitParameters().getSubject()); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Redirect.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Redirect.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Redirect.java index c1c8fd4..b918514 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Redirect.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Redirect.java @@ -30,6 +30,7 @@ import org.apache.james.transport.mailets.redirect.AddressExtractor; import org.apache.james.transport.mailets.redirect.InitParameters; import org.apache.james.transport.mailets.redirect.RedirectMailetInitParameters; import org.apache.james.transport.mailets.redirect.TypeCode; +import org.apache.james.transport.mailets.utils.MimeMessageModifier; import org.apache.mailet.Mail; import org.apache.mailet.MailAddress; @@ -412,10 +413,8 @@ public class Redirect extends AbstractRedirect { @Override protected void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail originalMail) throws MessagingException { - Optional<String> newSubject = getNewSubject(subjectPrefix, originalMail); - if (newSubject.isPresent()) { - changeSubject(newMail.getMessage(), newSubject.get()); - } + new MimeMessageModifier(newMail.getMessage()) + .setSubjectPrefix(newMail, subjectPrefix, originalMail, getInitParameters().getSubject()); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Resend.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Resend.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Resend.java index 4f550f1..f46e8c2 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Resend.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/Resend.java @@ -28,6 +28,7 @@ import org.apache.james.transport.mailets.redirect.AbstractRedirect; import org.apache.james.transport.mailets.redirect.AddressExtractor; import org.apache.james.transport.mailets.redirect.InitParameters; import org.apache.james.transport.mailets.redirect.RedirectMailetInitParameters; +import org.apache.james.transport.mailets.utils.MimeMessageModifier; import org.apache.mailet.Mail; import org.apache.mailet.MailAddress; @@ -349,10 +350,8 @@ public class Resend extends AbstractRedirect { @Override protected void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail originalMail) throws MessagingException { - Optional<String> newSubject = getNewSubject(subjectPrefix, originalMail); - if (newSubject.isPresent()) { - changeSubject(newMail.getMessage(), newSubject.get()); - } + new MimeMessageModifier(newMail.getMessage()) + .setSubjectPrefix(newMail, subjectPrefix, originalMail, getInitParameters().getSubject()); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/AbstractRedirect.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/AbstractRedirect.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/AbstractRedirect.java index 4dac188..32ae435 100644 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/AbstractRedirect.java +++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/AbstractRedirect.java @@ -35,7 +35,6 @@ import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; -import javax.mail.internet.MimeUtility; import javax.mail.internet.ParseException; import org.apache.james.core.MailImpl; @@ -48,7 +47,6 @@ import org.apache.mailet.base.DateFormats; import org.apache.mailet.base.GenericMailet; import org.apache.mailet.base.RFC2822Headers; -import com.google.common.base.Optional; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -475,28 +473,6 @@ public abstract class AbstractRedirect extends GenericMailet { */ protected abstract void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail originalMail) throws MessagingException; - protected Optional<String> getNewSubject(String subjectPrefix, Mail originalMail) throws MessagingException { - String subject = getInitParameters().getSubject(); - if (!Strings.isNullOrEmpty(subjectPrefix) || subject != null) { - String newSubject = Strings.nullToEmpty(subject); - if (subject == null) { - newSubject = Strings.nullToEmpty(originalMail.getMessage().getSubject()); - } else { - if (getInitParameters().isDebug()) { - log("subject set to: " + subject); - } - } - - if (subjectPrefix != null) { - newSubject = subjectPrefix + newSubject; - if (getInitParameters().isDebug()) { - log("subjectPrefix set to: " + subjectPrefix); - } - } - return Optional.of(newSubject); - } - return Optional.absent(); - } /** * Sets the "In-Reply-To:" header of <i>newMail</i> to the "Message-Id:" of * <i>originalMail</i>, if <i>isReply</i> is true. @@ -867,58 +843,6 @@ public abstract class AbstractRedirect extends GenericMailet { } /** - * It changes the subject of the supplied message to to supplied value but - * it also tries to preserve the original charset information.<br> - * <p/> - * This method was needed to avoid sending the subject using a charset - * (usually the default charset on the server) which doesn't contain the - * characters in the subject, resulting in the loss of these characters. The - * most simple method would be to either send it in ASCII unencoded or in - * UTF-8 if non-ASCII characters are present but unfortunately UTF-8 is not - * yet a MIME standard and not all email clients are supporting it. The - * optimal method would be to determine the best charset by analyzing the - * actual characters. That would require much more work (exept if an open - * source library already exists for this). However there is nothing to stop - * somebody to add a detection algorithm for a specific charset. <br> - * <p/> - * The current algorithm works correctly if only ASCII characters are added - * to an existing subject.<br> - * <p/> - * If the new value is ASCII only, then it doesn't apply any encoding to the - * subject header. (This is provided by MimeMessage.setSubject()).<br> - * <p/> - * Possible enhancement: under java 1.4 java.nio the system can determine if - * the suggested charset fits or not (if there is untranslatable - * characters). If the charset doesn't fit the new value, it can fall back - * to UTF-8.<br> - * - * @param message the message of which subject is changed - * @param newValue the new (unencoded) value of the subject. It must not be null. - * @throws MessagingException - according to the JavaMail doc most likely this is never - * thrown - */ - public void changeSubject(MimeMessage message, String newValue) throws MessagingException { - String rawSubject = message.getHeader(RFC2822Headers.SUBJECT, null); - Optional<String> mimeCharset = new CharsetFromSubjectMailHeader().parse(rawSubject); - if (!mimeCharset.isPresent()) { // most likely ASCII - // it uses the system charset or the value of the - // mail.mime.charset property if set - message.setSubject(newValue); - } else { // original charset determined - try { - message.setSubject(newValue, MimeUtility.javaCharset(mimeCharset.get())); - } catch (MessagingException e) { - // known, but unsupported encoding - // this should be logged, the admin may setup a more i18n - // capable JRE, but the log API cannot be accessed from here - // if (charset != null) log(charset + - // " charset unsupported by the JRE, email subject may be damaged"); - message.setSubject(newValue); // recover - } - } - } - - /** * Returns a new Collection built over <i>list</i> replacing special * addresses with real <code>MailAddress</code>-es.<br> * Manages <code>SpecialAddress.SENDER</code>, http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeader.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeader.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeader.java deleted file mode 100644 index 0e9b254..0000000 --- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeader.java +++ /dev/null @@ -1,65 +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.james.transport.mailets.redirect; - -import com.google.common.base.Optional; -import com.google.common.base.Strings; - -public class CharsetFromSubjectMailHeader { - - - /** - * It attempts to determine the charset used to encode an "unstructured" RFC - * 822 header (like Subject). The encoding is specified in RFC 2047. If it - * cannot determine or the the text is not encoded then it returns null. - * <p/> - * Here is an example raw text: Subject: - * =?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?= - * - * @param subject the raw (not decoded) value of the header. Null means that the - * header was not present (in this case it always return null). - * @return the MIME charset name or null if no encoding applied - */ - public Optional<String> parse(String subject) { - if (Strings.isNullOrEmpty(subject)) { - return Optional.absent(); - } - int iEncodingPrefix = subject.indexOf("=?"); - if (iEncodingPrefix == -1) { - return Optional.absent(); - } - int iCharsetBegin = iEncodingPrefix + 2; - int iSecondQuestionMark = subject.indexOf('?', iCharsetBegin); - if (iSecondQuestionMark == -1) { - return Optional.absent(); - } - if (iSecondQuestionMark == iCharsetBegin) { - return Optional.absent(); - } - int iThirdQuestionMark = subject.indexOf('?', iSecondQuestionMark + 1); - if (iThirdQuestionMark == -1) { - return Optional.absent(); - } - if (subject.indexOf("?=", iThirdQuestionMark + 1) == -1) { - return Optional.absent(); - } - return Optional.of(subject.substring(iCharsetBegin, iSecondQuestionMark)); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/82625a9b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeaderTest.java ---------------------------------------------------------------------- diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeaderTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeaderTest.java deleted file mode 100644 index 19f0e9a..0000000 --- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/redirect/CharsetFromSubjectMailHeaderTest.java +++ /dev/null @@ -1,85 +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.james.transport.mailets.redirect; - -import static org.assertj.guava.api.Assertions.assertThat; - -import org.junit.Test; - -import com.google.common.base.Optional; - -public class CharsetFromSubjectMailHeaderTest { - - @Test - public void parseShouldReturnAbsentWhenRawTextIsNull() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse(null); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnAbsentWhenRawTextIsEmpty() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse(""); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnAbsentWhenRawTextDoesNotContainEncodingPrefix() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse("iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?="); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnAbsentWhenRawTextDoesNotContainSecondQuestionMark() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2"); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnAbsentWhenRawTextDoesNotContainCharset() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=??"); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnAbsentWhenRawTextDoesNotContainThirdQuestionMark() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2?"); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnAbsentWhenRawTextDoesNotContainClosingTag() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel"); - - assertThat(charset).isAbsent(); - } - - @Test - public void parseShouldReturnCharsetWhenRawTextIsWellFormatted() { - Optional<String> charset = new CharsetFromSubjectMailHeader().parse("=?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?="); - - assertThat(charset).contains("iso-8859-2"); - } -} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
