You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2017/09/01 01:18:14 UTC

[01/27] james-project git commit: JAMES-2132 MDN Original Message ID field is optional. Value is Compulsory

Repository: james-project
Updated Branches:
  refs/heads/master 6553f4b50 -> 8d9287ff9


JAMES-2132 MDN Original Message ID field is optional. Value is Compulsory

As stated in https://tools.ietf.org/html/rfc8098#section-3.2.5:

   The Original-Message-ID field indicates the message-ID of the message
   for which the MDN is being issued.  It is obtained from the
   Message-ID header field of the message for which the MDN is issued.
   This field MUST be present if and only if the original message
   contained a Message-ID header field.  The syntax of the field is as
   follows:

   original-message-id-field =
             "Original-Message-ID" ":" msg-id

   The msg-id token is as specified in RFC-MSGFMT [RFC5322].


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d4303c56
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d4303c56
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d4303c56

Branch: refs/heads/master
Commit: d4303c56e4f089a8b0d1bc0ded7a2b066004b3c3
Parents: eb16708
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:31:00 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 11 +++--
 .../james/mdn/fields/OriginalMessageId.java     | 10 ++---
 .../org/apache/james/mdn/MDNFactoryTest.java    | 46 ++++++++++----------
 3 files changed, 31 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d4303c56/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 9dce948..1423074 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -82,13 +82,12 @@ public class MDNReport {
 
         public MDNReport build() {
             Preconditions.checkState(finalRecipientField.isPresent());
-            Preconditions.checkState(originalMessageIdField.isPresent());
             Preconditions.checkState(dispositionField.isPresent());
 
             return new MDNReport(reportingUserAgentField,
                 gatewayField, originalRecipientField,
                 finalRecipientField.get(),
-                originalMessageIdField.get(),
+                originalMessageIdField,
                 dispositionField.get());
         }
 
@@ -104,11 +103,11 @@ public class MDNReport {
     private final Optional<Gateway> gatewayField;
     private final Optional<OriginalRecipient> originalRecipientField;
     private final FinalRecipient finalRecipientField;
-    private final OriginalMessageId originalMessageIdField;
+    private final Optional<OriginalMessageId> originalMessageIdField;
     private final Disposition dispositionField;
 
     private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
-                      FinalRecipient finalRecipientField, OriginalMessageId originalMessageIdField, Disposition dispositionField) {
+                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField) {
         this.reportingUserAgentField = reportingUserAgentField;
         this.gatewayField = gatewayField;
         this.originalRecipientField = originalRecipientField;
@@ -129,7 +128,7 @@ public class MDNReport {
         return finalRecipientField;
     }
 
-    public OriginalMessageId getOriginalMessageIdField() {
+    public Optional<OriginalMessageId> getOriginalMessageIdField() {
         return originalMessageIdField;
     }
 
@@ -142,7 +141,7 @@ public class MDNReport {
             + gatewayField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + originalRecipientField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + finalRecipientField.formattedValue() + LINE_END
-            + originalMessageIdField.formattedValue() + LINE_END
+            + originalMessageIdField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + dispositionField.formattedValue() + LINE_END;
 
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4303c56/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
index f72d7cb..83666dc 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
@@ -19,21 +19,19 @@
 
 package org.apache.james.mdn.fields;
 
-import java.util.Optional;
-
 public class OriginalMessageId implements Field {
-    private final Optional<String> originalMessageId;
+    private final String originalMessageId;
 
-    public OriginalMessageId(Optional<String> originalMessageId) {
+    public OriginalMessageId(String originalMessageId) {
         this.originalMessageId = originalMessageId;
     }
 
-    public Optional<String> getOriginalMessageId() {
+    public String getOriginalMessageId() {
         return originalMessageId;
     }
 
     @Override
     public String formattedValue() {
-        return "Original-Message-ID: " + originalMessageId.orElse("");
+        return "Original-Message-ID: " + originalMessageId;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d4303c56/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 0cd3cde..9749d81 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -58,7 +58,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -87,7 +87,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -116,7 +116,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -145,7 +145,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -174,7 +174,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -203,7 +203,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -232,7 +232,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -261,7 +261,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -289,7 +289,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -316,7 +316,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -342,7 +342,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -370,7 +370,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -398,7 +398,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -427,7 +427,7 @@ public class MDNFactoryTest {
                 Optional.empty()))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -455,7 +455,7 @@ public class MDNFactoryTest {
                 "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -468,7 +468,7 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatNullOriginalMessageId() {
+    public void generateMDNReportShouldFormatWhenMissingOriginalMessageId() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
             .sendingMode(DispositionSendingMode.Automatic)
@@ -483,7 +483,6 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.empty()))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -492,7 +491,6 @@ public class MDNFactoryTest {
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: \r\n" +
                 "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
     }
 
@@ -526,7 +524,7 @@ public class MDNFactoryTest {
             .gatewayField(new Gateway("host.com"))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -557,7 +555,7 @@ public class MDNFactoryTest {
             .gatewayField(new Gateway("postal", "5 rue Charles mercier"))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -587,7 +585,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("roomNumber", "385"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -616,7 +614,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(OriginalRecipient.ofUnknown("#$%*"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -645,7 +643,7 @@ public class MDNFactoryTest {
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient("roomNumber", "781"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -675,7 +673,7 @@ public class MDNFactoryTest {
                 "UA_name",
                 Optional.of("UA_product")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build();
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[19/27] james-project git commit: JAMES-2132 MultipleError fields can be added to a MDN report

Posted by bt...@apache.org.
JAMES-2132 MultipleError fields can be added to a MDN report

https://tools.ietf.org/html/rfc8098#section-3.1

Describes the MDN structure as:

   disposition-notification-content = [ reporting-ua-field CRLF ]
             [ mdn-gateway-field CRLF ]
             [ original-recipient-field CRLF ]
             final-recipient-field CRLF
             [ original-message-id-field CRLF ]
             disposition-field CRLF
             *( error-field CRLF )
             *( extension-field CRLF )


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/6643ef28
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/6643ef28
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/6643ef28

Branch: refs/heads/master
Commit: 6643ef28e70044bf61bc89ffcd39bff0c0e67d46
Parents: 633d2eb
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 21:30:08 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:14:40 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 36 ++++++++++++------
 .../org/apache/james/mdn/MDNFactoryTest.java    | 40 ++++++++++++++++++--
 2 files changed, 62 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6643ef28/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 1d3beee..72eade2 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.mdn;
 
+import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -46,7 +47,7 @@ public class MDNReport {
         private Optional<FinalRecipient> finalRecipientField = Optional.empty();
         private Optional<OriginalMessageId> originalMessageIdField = Optional.empty();
         private Optional<Disposition> dispositionField = Optional.empty();
-        private Optional<Error> errorField = Optional.empty();
+        private ImmutableList.Builder<Error> errorField = ImmutableList.builder();
         private ImmutableList.Builder<ExtensionField> extensionFields = ImmutableList.builder();
 
         public Builder reportingUserAgentField(ReportingUserAgent reportingUserAgentField) {
@@ -74,9 +75,13 @@ public class MDNReport {
             return this;
         }
 
+        public Builder addErrorField(Error errorField) {
+            this.errorField.add(errorField);
+            return this;
+        }
 
-        public Builder errorField(Error errorField) {
-            this.errorField = Optional.of(errorField);
+        public Builder addErrorFields(Error... errorField) {
+            this.errorField.add(errorField);
             return this;
         }
 
@@ -114,7 +119,7 @@ public class MDNReport {
                 finalRecipientField.get(),
                 originalMessageIdField,
                 dispositionField.get(),
-                errorField,
+                errorField.build(),
                 extensionFields.build());
         }
 
@@ -130,19 +135,19 @@ public class MDNReport {
     private final FinalRecipient finalRecipientField;
     private final Optional<OriginalMessageId> originalMessageIdField;
     private final Disposition dispositionField;
-    private final Optional<Error> errorField;
+    private final ImmutableList<Error> errorFields;
     private final ImmutableList<ExtensionField> extensionFields;
 
     private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
-                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField, Optional<Error> errorField,
-                      ImmutableList<ExtensionField> extensionFields) {
+                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField,
+                      ImmutableList<Error> errorFields, ImmutableList<ExtensionField> extensionFields) {
         this.reportingUserAgentField = reportingUserAgentField;
         this.gatewayField = gatewayField;
         this.originalRecipientField = originalRecipientField;
         this.finalRecipientField = finalRecipientField;
         this.originalMessageIdField = originalMessageIdField;
         this.dispositionField = dispositionField;
-        this.errorField = errorField;
+        this.errorFields = errorFields;
         this.extensionFields = extensionFields;
     }
 
@@ -170,8 +175,8 @@ public class MDNReport {
         return gatewayField;
     }
 
-    public Optional<Error> getErrorField() {
-        return errorField;
+    public List<Error> getErrorFields() {
+        return errorFields;
     }
 
     public String formattedValue() {
@@ -181,10 +186,19 @@ public class MDNReport {
             + finalRecipientField.formattedValue() + LINE_END
             + originalMessageIdField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + dispositionField.formattedValue() + LINE_END
-            + errorField.map(value -> value.formattedValue() + LINE_END).orElse("")
+            + formatErrors()
             + formattedExtensionValue();
     }
 
+    private String formatErrors() {
+        if (errorFields.isEmpty()) {
+            return "";
+        }
+        return errorFields.stream()
+            .map(Error::formattedValue)
+            .collect(Collectors.joining(LINE_END)) + LINE_END;
+    }
+
     private String formattedExtensionValue() {
         if (extensionFields.isEmpty()) {
             return "";

http://git-wip-us.apache.org/repos/asf/james-project/blob/6643ef28/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 7d7ac83..c9235a8 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -607,7 +607,7 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatErrorFields() {
+    public void generateMDNReportShouldFormatErrorField() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
             .sendingMode(DispositionSendingMode.Automatic)
@@ -624,7 +624,7 @@ public class MDNFactoryTest {
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
-            .errorField(new Error(Text.fromRawText("An error message")))
+            .addErrorField(new Error(Text.fromRawText("An error message")))
             .build()
             .formattedValue();
 
@@ -638,6 +638,40 @@ public class MDNFactoryTest {
     }
 
     @Test
+    public void generateMDNReportShouldFormatErrorFields() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .addErrorFields(
+                new Error(Text.fromRawText("An error message")),
+                new Error(Text.fromRawText("A second error message")))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "Error: An error message\r\n" +
+                "Error: A second error message\r\n");
+    }
+
+    @Test
     public void generateMDNReportShouldFormatErrorFieldsOnSeveralLines() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
@@ -655,7 +689,7 @@ public class MDNFactoryTest {
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
-            .errorField(new Error(Text.fromRawText("An error message\non several lines")))
+            .addErrorField(new Error(Text.fromRawText("An error message\non several lines")))
             .build()
             .formattedValue();
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[21/27] james-project git commit: JAMES-2132 Provide state of the art beans

Posted by bt...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java b/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
new file mode 100644
index 0000000..a408b51
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class DispositionModifierTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(DispositionModifier.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNull() {
+        expectedException.expect(NullPointerException.class);
+
+        new DispositionModifier(null);
+    }
+
+    @Test
+    public void shouldThrowOnMultiLine() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new DispositionModifier("multi\nline");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/sending/mode/DispositionSendingModeTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/sending/mode/DispositionSendingModeTest.java b/mdn/src/test/java/org/apache/james/mdn/sending/mode/DispositionSendingModeTest.java
new file mode 100644
index 0000000..8b0f185
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/sending/mode/DispositionSendingModeTest.java
@@ -0,0 +1,49 @@
+/****************************************************************
+ * 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.mdn.sending.mode;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class DispositionSendingModeTest {
+    @Test
+    public void fromStringShouldReturnEmptyWhenUnknown() {
+        assertThat(DispositionSendingMode.fromString("unknown"))
+            .isEmpty();
+    }
+
+    @Test
+    public void fromStringShouldRetrieveAutomatic() {
+        assertThat(DispositionSendingMode.fromString(DispositionSendingMode.Automatic.getValue()))
+            .contains(DispositionSendingMode.Automatic);
+    }
+
+    @Test
+    public void fromStringShouldRetrieveManual() {
+        assertThat(DispositionSendingMode.fromString(DispositionSendingMode.Manual.getValue()))
+            .contains(DispositionSendingMode.Manual);
+    }
+    @Test
+    public void fromStringShouldNotBeCaseSensitive() {
+        assertThat(DispositionSendingMode.fromString("mdn-sent-automatically"))
+            .contains(DispositionSendingMode.Automatic);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/type/DispositionTypeTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/type/DispositionTypeTest.java b/mdn/src/test/java/org/apache/james/mdn/type/DispositionTypeTest.java
new file mode 100644
index 0000000..fa8a532
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/type/DispositionTypeTest.java
@@ -0,0 +1,62 @@
+/****************************************************************
+ * 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.mdn.type;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class DispositionTypeTest {
+    @Test
+    public void fromStringShouldReturnEmptyWhenUnknown() {
+        assertThat(DispositionType.fromString("unknown"))
+            .isEmpty();
+    }
+
+    @Test
+    public void fromStringShouldRetrieveDeleted() {
+        assertThat(DispositionType.fromString(DispositionType.Deleted.getValue()))
+            .contains(DispositionType.Deleted);
+    }
+
+    @Test
+    public void fromStringShouldRetrieveDispatched() {
+        assertThat(DispositionType.fromString(DispositionType.Dispatched.getValue()))
+            .contains(DispositionType.Dispatched);
+    }
+
+    @Test
+    public void fromStringShouldRetrieveDisplayed() {
+        assertThat(DispositionType.fromString(DispositionType.Displayed.getValue()))
+            .contains(DispositionType.Displayed);
+    }
+
+    @Test
+    public void fromStringShouldRetrieveProcessed() {
+        assertThat(DispositionType.fromString(DispositionType.Processed.getValue()))
+            .contains(DispositionType.Processed);
+    }
+
+    @Test
+    public void fromStringShouldNotBeCaseSensitive() {
+        assertThat(DispositionType.fromString("Deleted"))
+            .contains(DispositionType.Deleted);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index 8cd47ef..2dd88b8 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -124,7 +124,7 @@ public class RejectAction implements MailAction {
                 .reportingUserAgentField(
                     new ReportingUserAgent(
                         reporting_UA_name,
-                        Optional.ofNullable(reporting_UA_product)))
+                        reporting_UA_product))
                 .finalRecipientField(new FinalRecipient(Text.fromRawText(final_recipient)))
                 .originalRecipientField(Optional.ofNullable(original_recipient).map(Text::fromRawText).map(OriginalRecipient::new))
                 .originalMessageIdField(new OriginalMessageId(original_message_id))


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[18/27] james-project git commit: JAMES-2132 Add MDN support for extensions

Posted by bt...@apache.org.
JAMES-2132 Add MDN support for extensions

https://tools.ietf.org/html/rfc8098#section-3.3 states:

   Additional MDN fields may be defined in the future by later revisions
   or extensions to this specification.  MDN field names MUST be
   registered with the Internet Assigned Numbers Authority (IANA) using
   the "Specification Required" registration policy.  (See Section 10
   for a registration form.)  MDN Extension-fields may be defined for
   the following reasons:

   a.  To allow additional information from foreign disposition reports
       to be tunneled through Internet MDNs.  The names of such MDN
       fields should begin with an indication of the foreign environment
       name (e.g., X400-Physical-Forwarding-Address).

   b.  To allow transmission of diagnostic information that is specific
       to a particular Mail User Agent (MUA).  The names of such MDN
       fields should begin with an indication of the MUA implementation
       that produced the MDN (e.g., Foomail-information).


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/034eef67
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/034eef67
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/034eef67

Branch: refs/heads/master
Commit: 034eef67f4a52fdbef265954c3ea1a8e76b863a0
Parents: ea2b452
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 20:47:57 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 39 ++++++++++--
 .../apache/james/mdn/fields/ExtensionField.java | 35 ++++++++++
 .../org/apache/james/mdn/MDNFactoryTest.java    | 67 ++++++++++++++++++++
 3 files changed, 136 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/034eef67/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 127f0f4..1d3beee 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -20,9 +20,11 @@
 package org.apache.james.mdn;
 
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.Error;
+import org.apache.james.mdn.fields.ExtensionField;
 import org.apache.james.mdn.fields.FinalRecipient;
 import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
@@ -30,9 +32,13 @@ import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 
 public class MDNReport {
 
+    public static final String LINE_END = "\r\n";
+    public static final String EXTENSION_DELIMITER = LINE_END;
+
     public static class Builder {
         private Optional<ReportingUserAgent> reportingUserAgentField = Optional.empty();
         private Optional<Gateway> gatewayField = Optional.empty();
@@ -41,6 +47,7 @@ public class MDNReport {
         private Optional<OriginalMessageId> originalMessageIdField = Optional.empty();
         private Optional<Disposition> dispositionField = Optional.empty();
         private Optional<Error> errorField = Optional.empty();
+        private ImmutableList.Builder<ExtensionField> extensionFields = ImmutableList.builder();
 
         public Builder reportingUserAgentField(ReportingUserAgent reportingUserAgentField) {
             this.reportingUserAgentField = Optional.of(reportingUserAgentField);
@@ -88,6 +95,16 @@ public class MDNReport {
             return this;
         }
 
+        public Builder withExtensionField(ExtensionField extensionField) {
+            this.extensionFields.add(extensionField);
+            return this;
+        }
+
+        public Builder withExtensionFields(ExtensionField... extensionField) {
+            this.extensionFields.add(extensionField);
+            return this;
+        }
+
         public MDNReport build() {
             Preconditions.checkState(finalRecipientField.isPresent());
             Preconditions.checkState(dispositionField.isPresent());
@@ -96,7 +113,9 @@ public class MDNReport {
                 gatewayField, originalRecipientField,
                 finalRecipientField.get(),
                 originalMessageIdField,
-                dispositionField.get(), errorField);
+                dispositionField.get(),
+                errorField,
+                extensionFields.build());
         }
 
     }
@@ -105,8 +124,6 @@ public class MDNReport {
         return new Builder();
     }
 
-    public static final String LINE_END = "\r\n";
-
     private final Optional<ReportingUserAgent> reportingUserAgentField;
     private final Optional<Gateway> gatewayField;
     private final Optional<OriginalRecipient> originalRecipientField;
@@ -114,9 +131,11 @@ public class MDNReport {
     private final Optional<OriginalMessageId> originalMessageIdField;
     private final Disposition dispositionField;
     private final Optional<Error> errorField;
+    private final ImmutableList<ExtensionField> extensionFields;
 
     private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
-                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField, Optional<Error> errorField) {
+                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField, Optional<Error> errorField,
+                      ImmutableList<ExtensionField> extensionFields) {
         this.reportingUserAgentField = reportingUserAgentField;
         this.gatewayField = gatewayField;
         this.originalRecipientField = originalRecipientField;
@@ -124,6 +143,7 @@ public class MDNReport {
         this.originalMessageIdField = originalMessageIdField;
         this.dispositionField = dispositionField;
         this.errorField = errorField;
+        this.extensionFields = extensionFields;
     }
 
     public Optional<ReportingUserAgent> getReportingUserAgentField() {
@@ -161,7 +181,16 @@ public class MDNReport {
             + finalRecipientField.formattedValue() + LINE_END
             + originalMessageIdField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + dispositionField.formattedValue() + LINE_END
-            + errorField.map(value -> value.formattedValue() + LINE_END).orElse("");
+            + errorField.map(value -> value.formattedValue() + LINE_END).orElse("")
+            + formattedExtensionValue();
+    }
 
+    private String formattedExtensionValue() {
+        if (extensionFields.isEmpty()) {
+            return "";
+        }
+        return extensionFields.stream()
+            .map(ExtensionField::formattedValue)
+            .collect(Collectors.joining(EXTENSION_DELIMITER)) + LINE_END;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/034eef67/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java b/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
new file mode 100644
index 0000000..65d9e84
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
@@ -0,0 +1,35 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+public class ExtensionField implements Field {
+    private final String fieldName;
+    private final String rawValue;
+
+    public ExtensionField(String fieldName, String rawValue) {
+        this.fieldName = fieldName;
+        this.rawValue = rawValue;
+    }
+
+    @Override
+    public String formattedValue() {
+        return fieldName + ": " +rawValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/034eef67/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 24b81f1..7d7ac83 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -26,6 +26,7 @@ import java.util.Optional;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.Error;
+import org.apache.james.mdn.fields.ExtensionField;
 import org.apache.james.mdn.fields.FinalRecipient;
 import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
@@ -667,4 +668,70 @@ public class MDNFactoryTest {
                 "Error: An error message\r\n" +
                 " on several lines\r\n");
     }
+
+    @Test
+    public void generateMDNReportShouldFormatOneExtension() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+         .withExtensionField(new ExtensionField("X-OPENPAAS-IP", "177.177.177.77"))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "X-OPENPAAS-IP: 177.177.177.77\r\n");
+    }
+
+
+    @Test
+    public void generateMDNReportShouldFormatManyExtensions() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .withExtensionFields(
+                new ExtensionField("X-OPENPAAS-IP", "177.177.177.77"),
+                new ExtensionField("X-OPENPAAS-PORT", "8000"))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "X-OPENPAAS-IP: 177.177.177.77\r\n" +
+                "X-OPENPAAS-PORT: 8000\r\n");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[22/27] james-project git commit: JAMES-2132 Provide state of the art beans

Posted by bt...@apache.org.
JAMES-2132 Provide state of the art beans

 - toString, equals and hashcode
 - builder test
 - Edge case of constructors tested
 - Display of each field tested
 - value -> enum tested


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4020b750
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4020b750
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4020b750

Branch: refs/heads/master
Commit: 4020b75031f487d54e8bc13d9aa879b43b63164c
Parents: 879fe83
Author: benwa <bt...@linagora.com>
Authored: Tue Aug 29 14:09:08 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:16:10 2017 +0700

----------------------------------------------------------------------
 mdn/pom.xml                                     |   8 +-
 .../java/org/apache/james/mdn/MDNReport.java    |  33 +++-
 .../apache/james/mdn/fields/Disposition.java    |  28 ++-
 .../java/org/apache/james/mdn/fields/Error.java |  25 +++
 .../apache/james/mdn/fields/ExtensionField.java |  29 +++
 .../apache/james/mdn/fields/FinalRecipient.java |  25 +++
 .../org/apache/james/mdn/fields/Gateway.java    |  31 +++-
 .../james/mdn/fields/OriginalMessageId.java     |  27 +++
 .../james/mdn/fields/OriginalRecipient.java     |  25 ++-
 .../james/mdn/fields/ReportingUserAgent.java    |  35 +++-
 .../java/org/apache/james/mdn/fields/Text.java  |  18 ++
 .../james/mdn/modifier/DispositionModifier.java |  38 +++-
 .../org/apache/james/mdn/MDNFactoryTest.java    |  90 +++-------
 .../org/apache/james/mdn/MDNReportTest.java     | 150 ++++++++++++++++
 .../action/mode/DispositionActionModeTest.java  |  49 +++++
 .../james/mdn/fields/DispositionTest.java       | 177 +++++++++++++++++++
 .../org/apache/james/mdn/fields/ErrorTest.java  |  62 +++++++
 .../james/mdn/fields/ExtensionFieldTest.java    |  71 ++++++++
 .../james/mdn/fields/FinalRecipientTest.java    | 101 +++++++++++
 .../apache/james/mdn/fields/GatewayTest.java    | 102 +++++++++++
 .../james/mdn/fields/OriginalMessageIdTest.java |  62 +++++++
 .../james/mdn/fields/OriginalRecipientTest.java |  95 ++++++++++
 .../mdn/fields/ReportingUserAgentTest.java      |  93 ++++++++++
 .../org/apache/james/mdn/fields/TextTest.java   |  97 ++++++++++
 .../mdn/modifier/DispositionModifierTest.java   |  53 ++++++
 .../mode/DispositionSendingModeTest.java        |  49 +++++
 .../james/mdn/type/DispositionTypeTest.java     |  62 +++++++
 .../transport/mailets/jsieve/RejectAction.java  |   2 +-
 28 files changed, 1556 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/pom.xml
----------------------------------------------------------------------
diff --git a/mdn/pom.xml b/mdn/pom.xml
index 0a7be2b..3094c9d 100644
--- a/mdn/pom.xml
+++ b/mdn/pom.xml
@@ -29,7 +29,6 @@
 
     <artifactId>james-mdn</artifactId>
 
-
     <name>Apache James :: MDN</name>
     <description>Provides parser and representations for MDN messages</description>
 
@@ -44,10 +43,15 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 
-
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 72eade2..06b66b2 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -20,6 +20,7 @@
 package org.apache.james.mdn;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -32,6 +33,7 @@ import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
@@ -138,7 +140,8 @@ public class MDNReport {
     private final ImmutableList<Error> errorFields;
     private final ImmutableList<ExtensionField> extensionFields;
 
-    private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
+    @VisibleForTesting
+    MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
                       FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField,
                       ImmutableList<Error> errorFields, ImmutableList<ExtensionField> extensionFields) {
         this.reportingUserAgentField = reportingUserAgentField;
@@ -207,4 +210,32 @@ public class MDNReport {
             .map(ExtensionField::formattedValue)
             .collect(Collectors.joining(EXTENSION_DELIMITER)) + LINE_END;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof MDNReport) {
+            MDNReport that = (MDNReport) o;
+
+            return Objects.equals(this.reportingUserAgentField, that.reportingUserAgentField)
+                && Objects.equals(this.dispositionField, that.dispositionField)
+                && Objects.equals(this.errorFields, that.errorFields)
+                && Objects.equals(this.finalRecipientField, that.finalRecipientField)
+                && Objects.equals(this.gatewayField, that.gatewayField)
+                && Objects.equals(this.originalMessageIdField, that.originalMessageIdField)
+                && Objects.equals(this.extensionFields, that.extensionFields)
+                && Objects.equals(this.originalRecipientField, that.originalRecipientField);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(reportingUserAgentField, gatewayField, originalMessageIdField, originalRecipientField,
+            dispositionField, errorFields, extensionFields, finalRecipientField);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
index 157b4b7..815dcdc 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
@@ -20,6 +20,7 @@
 package org.apache.james.mdn.fields;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -28,6 +29,7 @@ import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
@@ -86,7 +88,8 @@ public class Disposition implements Field {
     private final DispositionType type;
     private final List<DispositionModifier> modifiers;
 
-    private Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type, List<DispositionModifier> modifiers) {
+    @VisibleForTesting
+    Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type, List<DispositionModifier> modifiers) {
         this.actionMode = actionMode;
         this.sendingMode = sendingMode;
         this.type = type;
@@ -124,4 +127,27 @@ public class Disposition implements Field {
             .map(DispositionModifier::getValue)
             .collect(Collectors.joining(","));
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Disposition) {
+            Disposition that = (Disposition) o;
+
+            return Objects.equals(actionMode, that.actionMode)
+                && Objects.equals(sendingMode, that.sendingMode)
+                && Objects.equals(type, that.type)
+                && Objects.equals(modifiers, that.modifiers);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(actionMode, sendingMode, type, modifiers);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Error.java b/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
index 64dface..7001364 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
@@ -19,6 +19,10 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
 /**
  * Implements the optional MDN Error field defined in RFC-8098
  *
@@ -30,6 +34,7 @@ public class Error implements Field {
     private final Text text;
 
     public Error(Text text) {
+        Preconditions.checkNotNull(text);
         this.text = text;
     }
 
@@ -41,4 +46,24 @@ public class Error implements Field {
     public String formattedValue() {
         return FIELD_NAME + ": " + text.formatted();
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Error) {
+            Error error = (Error) o;
+
+            return Objects.equals(text, error.text);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(text);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java b/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
index 9b6e6bc..893d1e6 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
@@ -19,6 +19,10 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
 /**
  * Implements extension fields allowed by RFC-8098
  *
@@ -29,6 +33,10 @@ public class ExtensionField implements Field {
     private final String rawValue;
 
     public ExtensionField(String fieldName, String rawValue) {
+        Preconditions.checkNotNull(fieldName);
+        Preconditions.checkNotNull(rawValue);
+        Preconditions.checkArgument(!fieldName.contains("\n"), "Field name can not be multiline");
+
         this.fieldName = fieldName;
         this.rawValue = rawValue;
     }
@@ -37,4 +45,25 @@ public class ExtensionField implements Field {
     public String formattedValue() {
         return fieldName + ": " +rawValue;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof ExtensionField) {
+            ExtensionField that = (ExtensionField) o;
+
+            return Objects.equals(fieldName, that.fieldName)
+                && Objects.equals(rawValue, that.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(fieldName, rawValue);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
index b613747..8f87170 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
+
 import org.apache.james.mdn.Constants;
 
 import com.google.common.base.Preconditions;
@@ -37,6 +39,8 @@ public class FinalRecipient implements Field {
     public FinalRecipient(String addressType, Text finalRecipient) {
         Preconditions.checkNotNull(finalRecipient);
         Preconditions.checkNotNull(addressType);
+        Preconditions.checkArgument(!addressType.contains("\n"), "Address type can not be multiline");
+
         this.finalRecipient = finalRecipient;
         this.addressType = addressType;
     }
@@ -53,4 +57,25 @@ public class FinalRecipient implements Field {
     public String formattedValue() {
         return FIELD_NAME + ": " + addressType + "; " + finalRecipient.formatted();
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof FinalRecipient) {
+            FinalRecipient that = (FinalRecipient) o;
+
+            return Objects.equals(finalRecipient, that.finalRecipient)
+                && Objects.equals(addressType, that.addressType);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(finalRecipient, addressType);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
index 493aa6b..f11bc7a 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
@@ -19,17 +19,25 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
 /**
  * MDN-Gateway field as specified in https://tools.ietf.org/html/rfc8098#section-3.2.2
  */
 public class Gateway implements Field {
-    private static final String DNS = "dns";
+    public static final String DNS = "dns";
     public static final String FIELD_NAME = "MDN-Gateway";
 
     private final String nameType;
     private final Text name;
 
     public Gateway(String nameType, Text name) {
+        Preconditions.checkNotNull(nameType);
+        Preconditions.checkNotNull(name);
+        Preconditions.checkArgument(!nameType.contains("\n"));
+
         this.nameType = nameType;
         this.name = name;
     }
@@ -50,4 +58,25 @@ public class Gateway implements Field {
     public Text getName() {
         return name;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Gateway) {
+            Gateway gateway = (Gateway) o;
+
+            return Objects.equals(nameType, gateway.nameType)
+                && Objects.equals(name, gateway.name);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(nameType, name);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
index 96a1245..8d0c6f1 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
@@ -19,6 +19,10 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
 /**
  * Optional Original-Message−Id as defined in RFC-8098
  *
@@ -29,6 +33,9 @@ public class OriginalMessageId implements Field {
     private final String originalMessageId;
 
     public OriginalMessageId(String originalMessageId) {
+        Preconditions.checkNotNull(originalMessageId);
+        Preconditions.checkArgument(!originalMessageId.contains("\n"));
+
         this.originalMessageId = originalMessageId;
     }
 
@@ -40,4 +47,24 @@ public class OriginalMessageId implements Field {
     public String formattedValue() {
         return FIELD_NAME + ": " + originalMessageId;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof OriginalMessageId) {
+            OriginalMessageId that = (OriginalMessageId) o;
+
+            return Objects.equals(originalMessageId, that.originalMessageId);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(originalMessageId);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
index ccb69c2..d1c7d33 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
+
 import org.apache.james.mdn.Constants;
 
 import com.google.common.base.Preconditions;
@@ -28,7 +30,7 @@ import com.google.common.base.Preconditions;
  *
  * https://tools.ietf.org/html/rfc8098#section-3.2.3
  */
-public class OriginalRecipient implements Field{
+public class OriginalRecipient implements Field {
     private static final String UNKNOWN = "unknown";
     private static final String FIELD_NAME = "Original-Recipient";
 
@@ -59,7 +61,28 @@ public class OriginalRecipient implements Field{
     }
 
     @Override
+    public final boolean equals(Object o) {
+        if (o instanceof OriginalRecipient) {
+            OriginalRecipient that = (OriginalRecipient) o;
+
+            return Objects.equals(this.originalRecipient, that.originalRecipient)
+                && Objects.equals(this.addressType, that.addressType);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(originalRecipient, addressType);
+    }
+
+    @Override
     public String formattedValue() {
         return FIELD_NAME + ": " + addressType + "; " + originalRecipient.formatted();
     }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
index 663a27a..0772049 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -19,8 +19,10 @@
 
 package org.apache.james.mdn.fields;
 
+import java.util.Objects;
 import java.util.Optional;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
 /**
@@ -33,9 +35,19 @@ public class ReportingUserAgent implements Field {
     private final String userAgentName;
     private final Optional<String> userAgentProduct;
 
-    public ReportingUserAgent(String userAgentName, Optional<String> userAgentProduct) {
+    public ReportingUserAgent(String userAgentName) {
+        this(userAgentName, Optional.empty());
+    }
+
+    public ReportingUserAgent(String userAgentName, String userAgentProduct) {
+        this(userAgentName, Optional.of(userAgentProduct));
+    }
+
+    @VisibleForTesting
+    ReportingUserAgent(String userAgentName, Optional<String> userAgentProduct) {
         Preconditions.checkNotNull(userAgentName);
         Preconditions.checkNotNull(userAgentProduct);
+
         this.userAgentName = userAgentName;
         this.userAgentProduct = userAgentProduct;
     }
@@ -53,4 +65,25 @@ public class ReportingUserAgent implements Field {
         return FIELD_NAME + ": " + userAgentName + "; "
             + userAgentProduct.orElse("");
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof ReportingUserAgent) {
+            ReportingUserAgent that = (ReportingUserAgent) o;
+
+            return Objects.equals(this.userAgentName, that.userAgentName)
+                && Objects.equals(this.userAgentProduct, that.userAgentProduct);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(userAgentName, userAgentProduct);
+    }
+
+    @Override
+    public String toString() {
+        return formattedValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Text.java b/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
index 7473e08..d3592cf 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
@@ -20,11 +20,14 @@
 package org.apache.james.mdn.fields;
 
 import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 
 public class Text {
 
     public static Text fromRawText(String rawText) {
+        Preconditions.checkNotNull(rawText);
         return new Text(replaceLineBreaksByContinuation(rawText));
     }
 
@@ -44,4 +47,19 @@ public class Text {
     public String formatted() {
         return content;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof Text) {
+            Text that = (Text) o;
+
+            return Objects.equal(this.content, that.content);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hashCode(content);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
index f4a2b70..f7e9171 100644
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
@@ -19,6 +19,10 @@
 
 package org.apache.james.mdn.modifier;
 
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
 /**
  * Interface <code>DispositionModifier</code> marks a type encapsulating
  * disposition modifier information as defined by RFC 8098.
@@ -26,20 +30,42 @@ package org.apache.james.mdn.modifier;
  * https://tools.ietf.org/html/rfc8098#section-3.2.6.3
  */
 public class DispositionModifier {
-    public static DispositionModifier Error = new DispositionModifier("error");
-    public static DispositionModifier Expired = new DispositionModifier("expired");
-    public static DispositionModifier Failed = new DispositionModifier("failed");
-    public static DispositionModifier MailboxTerminated = new DispositionModifier("mailbox-terminated");
-    public static DispositionModifier Superseded = new DispositionModifier("superseded");
-    public static DispositionModifier Warning = new DispositionModifier("warning");
+    public static final DispositionModifier Error = new DispositionModifier("error");
+    public static final DispositionModifier Expired = new DispositionModifier("expired");
+    public static final DispositionModifier Failed = new DispositionModifier("failed");
+    public static final DispositionModifier MailboxTerminated = new DispositionModifier("mailbox-terminated");
+    public static final DispositionModifier Superseded = new DispositionModifier("superseded");
+    public static final DispositionModifier Warning = new DispositionModifier("warning");
 
     private final String value;
 
     public DispositionModifier(String value) {
+        Preconditions.checkNotNull(value);
+        Preconditions.checkArgument(!value.contains("\n"), "Multiline Disposition modifier are forbiden");
         this.value = value;
     }
 
     public String getValue() {
         return value;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof DispositionModifier) {
+            DispositionModifier that = (DispositionModifier) o;
+
+            return Objects.equals(this.value, that.value);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(value);
+    }
+
+    @Override
+    public String toString() {
+        return getValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index c9235a8..eaad55c 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -21,8 +21,6 @@ package org.apache.james.mdn;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import java.util.Optional;
-
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.Error;
@@ -36,15 +34,10 @@ import org.apache.james.mdn.fields.Text;
 import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 
 public class MDNFactoryTest {
 
-    @Rule
-    public ExpectedException expectedException = ExpectedException.none();
-
     @Test
     public void generateMDNReportShouldFormatAutomaticActions() {
         Disposition disposition = Disposition.builder()
@@ -58,7 +51,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -87,7 +80,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -116,7 +109,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -145,7 +138,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -174,7 +167,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -203,7 +196,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -231,7 +224,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -259,7 +252,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -286,7 +279,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -313,9 +306,7 @@ public class MDNFactoryTest {
             .build();
 
         String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.empty()))
+            .reportingUserAgentField(new ReportingUserAgent("UA_name"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -344,7 +335,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
@@ -371,7 +362,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .dispositionField(disposition)
@@ -386,19 +377,6 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportThrowOnNullDisposition() {
-        expectedException.expect(IllegalStateException.class);
-
-        MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .build();
-    }
-
-    @Test
     public void generateMDNReportShouldFormatGateway() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
@@ -411,7 +389,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .gatewayField(new Gateway(Text.fromRawText("host.com")))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
@@ -442,7 +420,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .gatewayField(new Gateway("postal", Text.fromRawText("5 rue Charles mercier")))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
@@ -473,7 +451,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient("roomNumber", Text.fromRawText("385")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -502,7 +480,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .gatewayField(new Gateway("postal", Text.fromRawText("8 rue Charles mercier\n 36555 Saint Coincoin\n France")))
             .finalRecipientField(new FinalRecipient("postal", Text.fromRawText("5 rue Mercier\n 36555 Saint Coincoin\n France")))
             .originalRecipientField(new OriginalRecipient("postal", Text.fromRawText("3 rue Mercier\n 36555 Saint Coincoin\n France")))
@@ -539,7 +517,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(OriginalRecipient.ofUnknown(Text.fromRawText("#$%*")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -568,7 +546,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient("roomNumber", Text.fromRawText("781")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -585,28 +563,6 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldThrowWhenMissingFinalField() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        expectedException.expect(IllegalStateException.class);
-
-        MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.of("UA_product")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build();
-    }
-
-    @Test
     public void generateMDNReportShouldFormatErrorField() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
@@ -619,7 +575,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -650,7 +606,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -684,7 +640,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -716,7 +672,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -748,7 +704,7 @@ public class MDNFactoryTest {
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
-                Optional.of("UA_product")))
+                "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/MDNReportTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNReportTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNReportTest.java
new file mode 100644
index 0000000..4d21946
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNReportTest.java
@@ -0,0 +1,150 @@
+/****************************************************************
+ * 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.mdn;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Optional;
+
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.Error;
+import org.apache.james.mdn.fields.ExtensionField;
+import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.Gateway;
+import org.apache.james.mdn.fields.OriginalMessageId;
+import org.apache.james.mdn.fields.OriginalRecipient;
+import org.apache.james.mdn.fields.ReportingUserAgent;
+import org.apache.james.mdn.fields.Text;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.collect.ImmutableList;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class MDNReportTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContact() {
+        EqualsVerifier.forClass(MDNReport.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void generateMDNReportThrowOnNullDisposition() {
+        expectedException.expect(IllegalStateException.class);
+
+        MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .build();
+    }
+
+    @Test
+    public void generateMDNReportShouldThrowWhenMissingFinalField() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        expectedException.expect(IllegalStateException.class);
+
+        MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build();
+    }
+
+    @Test
+    public void shouldBuildWithMinimalSubset() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .build();
+
+        FinalRecipient finalRecipientField = new FinalRecipient(Text.fromRawText("any@domain.com"));
+        MDNReport mdnReport = MDNReport.builder()
+            .finalRecipientField(finalRecipientField)
+            .dispositionField(disposition)
+            .build();
+
+        assertThat(mdnReport)
+            .isEqualTo(new MDNReport(
+                Optional.empty(), Optional.empty(), Optional.empty(), finalRecipientField, Optional.empty(), disposition,
+                ImmutableList.of(), ImmutableList.of()));
+    }
+
+    @Test
+    public void shouldBuildWithMaximalSubset() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .build();
+        FinalRecipient finalRecipientField = new FinalRecipient(Text.fromRawText("any@domain.com"));
+        ExtensionField extensionField1 = new ExtensionField("name1", "value1");
+        ExtensionField extensionField2 = new ExtensionField("name2", "value2");
+        Gateway gateway = new Gateway(Text.fromRawText("address"));
+        OriginalMessageId originalMessageIdField = new OriginalMessageId("msgId");
+        OriginalRecipient originalRecipientField = new OriginalRecipient(Text.fromRawText("address"));
+        ReportingUserAgent reportingUserAgentField = new ReportingUserAgent("name");
+        Error errorField1 = new Error(Text.fromRawText("error 1"));
+        Error errorField2 = new Error(Text.fromRawText("error 2"));
+
+        MDNReport mdnReport = MDNReport.builder()
+            .withExtensionField(extensionField1)
+            .withExtensionField(extensionField2)
+            .finalRecipientField(finalRecipientField)
+            .dispositionField(disposition)
+            .gatewayField(gateway)
+            .originalMessageIdField(originalMessageIdField)
+            .originalRecipientField(originalRecipientField)
+            .reportingUserAgentField(reportingUserAgentField)
+            .addErrorField(errorField1)
+            .addErrorField(errorField2)
+            .build();
+
+        assertThat(mdnReport)
+            .isEqualTo(new MDNReport(
+                Optional.of(reportingUserAgentField), Optional.of(gateway), Optional.of(originalRecipientField),
+                finalRecipientField, Optional.of(originalMessageIdField), disposition,
+                ImmutableList.of(errorField1, errorField2), ImmutableList.of(extensionField1, extensionField2)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/action/mode/DispositionActionModeTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/action/mode/DispositionActionModeTest.java b/mdn/src/test/java/org/apache/james/mdn/action/mode/DispositionActionModeTest.java
new file mode 100644
index 0000000..219dff2
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/action/mode/DispositionActionModeTest.java
@@ -0,0 +1,49 @@
+/****************************************************************
+ * 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.mdn.action.mode;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class DispositionActionModeTest {
+    @Test
+    public void fromStringShouldReturnEmptyWhenUnknown() {
+        assertThat(DispositionActionMode.fromString("unknown"))
+            .isEmpty();
+    }
+
+    @Test
+    public void fromStringShouldRetrieveAutomatic() {
+        assertThat(DispositionActionMode.fromString(DispositionActionMode.Automatic.getValue()))
+            .contains(DispositionActionMode.Automatic);
+    }
+
+    @Test
+    public void fromStringShouldRetrieveManual() {
+        assertThat(DispositionActionMode.fromString(DispositionActionMode.Manual.getValue()))
+            .contains(DispositionActionMode.Manual);
+    }
+    @Test
+    public void fromStringShouldNotBeCaseSensitive() {
+        assertThat(DispositionActionMode.fromString("autoMatic-action"))
+            .contains(DispositionActionMode.Automatic);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/DispositionTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/DispositionTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/DispositionTest.java
new file mode 100644
index 0000000..817d731
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/DispositionTest.java
@@ -0,0 +1,177 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.collect.ImmutableList;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class DispositionTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(Disposition.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldBuildMinimalSubSet() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .build();
+
+        ImmutableList<DispositionModifier> modifiers = ImmutableList.of();
+        assertThat(disposition)
+            .isEqualTo(new Disposition(
+                DispositionActionMode.Automatic,
+                DispositionSendingMode.Automatic,
+                DispositionType.Processed,
+                modifiers));
+    }
+
+    @Test
+    public void buildShouldThrowOnMissingActionMode() {
+        expectedException.expect(IllegalStateException.class);
+
+        Disposition.builder()
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .build();
+    }
+
+    @Test
+    public void buildShouldThrowOnMissingSendingMode() {
+        expectedException.expect(IllegalStateException.class);
+
+        Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .type(DispositionType.Processed)
+            .build();
+    }
+
+    @Test
+    public void buildShouldThrowOnMissingType() {
+        expectedException.expect(IllegalStateException.class);
+
+        Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .build();
+    }
+
+    @Test
+    public void shouldBuildWithAllOptions() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifiers(DispositionModifier.Expired, DispositionModifier.Warning)
+            .build();
+
+        ImmutableList<DispositionModifier> modifiers = ImmutableList.of(DispositionModifier.Expired, DispositionModifier.Warning);
+        assertThat(disposition)
+            .isEqualTo(new Disposition(
+                DispositionActionMode.Automatic,
+                DispositionSendingMode.Automatic,
+                DispositionType.Processed,
+                modifiers));
+    }
+
+    @Test
+    public void formattedValueShouldDisplayAllOptions() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifiers(DispositionModifier.Expired, DispositionModifier.Warning)
+            .build();
+
+        assertThat(disposition.formattedValue())
+            .isEqualTo("Disposition: automatic-action/MDN-sent-automatically;processed/expired,warning");
+    }
+
+    @Test
+    public void formattedValueShouldDisplaySingleModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifiers(DispositionModifier.Expired)
+            .build();
+
+        assertThat(disposition.formattedValue())
+            .isEqualTo("Disposition: automatic-action/MDN-sent-automatically;processed/expired");
+    }
+
+
+    @Test
+    public void formattedValueShouldDisplayNoModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .build();
+
+        assertThat(disposition.formattedValue())
+            .isEqualTo("Disposition: automatic-action/MDN-sent-automatically;processed");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayManualActionMode() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifiers(DispositionModifier.Expired)
+            .build();
+
+        assertThat(disposition.formattedValue())
+            .isEqualTo("Disposition: manual-action/MDN-sent-automatically;processed/expired");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayManualSendingMode() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Processed)
+            .addModifiers(DispositionModifier.Expired)
+            .build();
+
+        assertThat(disposition.formattedValue())
+            .isEqualTo("Disposition: automatic-action/MDN-sent-manually;processed/expired");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/ErrorTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/ErrorTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/ErrorTest.java
new file mode 100644
index 0000000..294b90b
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/ErrorTest.java
@@ -0,0 +1,62 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class ErrorTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(Error.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNullText() {
+        expectedException.expect(NullPointerException.class);
+
+        new Error(null);
+    }
+
+    @Test
+    public void formattedValueShouldDisplayMessage() {
+        assertThat(new Error(Text.fromRawText("Message"))
+            .formattedValue())
+            .isEqualTo("Error: Message");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayMultiLineMessage() {
+        assertThat(new Error(Text.fromRawText("Multi\nline\nMessage"))
+            .formattedValue())
+            .isEqualTo("Error: Multi\r\n line\r\n Message");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/ExtensionFieldTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/ExtensionFieldTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/ExtensionFieldTest.java
new file mode 100644
index 0000000..7c9e877
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/ExtensionFieldTest.java
@@ -0,0 +1,71 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class ExtensionFieldTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(ExtensionField.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNullFieldName() {
+        expectedException.expect(NullPointerException.class);
+
+        String fieldName = null;
+        new ExtensionField(fieldName, "rawValue");
+    }
+
+    @Test
+    public void shouldThrowOnNullRawValue() {
+        expectedException.expect(NullPointerException.class);
+
+        String rawValue = null;
+        new ExtensionField("name", rawValue);
+    }
+
+    @Test
+    public void shouldThrowOnMultilineName() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new ExtensionField("name\nmultiline", "rawValue");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayNameAndRawValue() {
+        assertThat(new ExtensionField("name", "rawValue")
+            .formattedValue())
+            .isEqualTo("name: rawValue");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
new file mode 100644
index 0000000..c424a0c
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.mdn.Constants;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class FinalRecipientTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(FinalRecipient.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNullAddress() {
+        expectedException.expect(NullPointerException.class);
+
+        new FinalRecipient(null);
+    }
+
+    @Test
+    public void shouldThrowOnNullAddressWithType() {
+        expectedException.expect(NullPointerException.class);
+
+        new FinalRecipient("customType", null);
+    }
+
+    @Test
+    public void shouldThrowOnNullType() {
+        expectedException.expect(NullPointerException.class);
+
+        String addressType = null;
+        new FinalRecipient(addressType, Text.fromRawText("address"));
+    }
+
+    @Test
+    public void shouldThrowOnMultilineType() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String addressType = "a\nb";
+        new FinalRecipient(addressType, Text.fromRawText("address"));
+    }
+
+    @Test
+    public void typeShouldDefaultToRfc822() {
+        Text address = Text.fromRawText("address");
+        assertThat(new FinalRecipient(address))
+            .isEqualTo(new FinalRecipient(Constants.RFC_822, address));
+    }
+
+    @Test
+    public void formattedValueShouldDisplayAddress() {
+        assertThat(new FinalRecipient(Text.fromRawText("Plop"))
+            .formattedValue())
+            .isEqualTo("Final-Recipient: rfc822; Plop");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayCustomType() {
+        assertThat(new FinalRecipient("postal", Text.fromRawText("Plop"))
+            .formattedValue())
+            .isEqualTo("Final-Recipient: postal; Plop");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayMultilineAddress() {
+        assertThat(new FinalRecipient(Text.fromRawText("Plop\nGlark"))
+            .formattedValue())
+            .isEqualTo("Final-Recipient: rfc822; Plop\r\n" +
+                " Glark");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
new file mode 100644
index 0000000..b5041fd
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
@@ -0,0 +1,102 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class GatewayTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(Gateway.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNullName() {
+        expectedException.expect(NullPointerException.class);
+
+        Text name = null;
+        new Gateway(name);
+    }
+
+    @Test
+    public void shouldThrowOnNullNameWhenType() {
+        expectedException.expect(NullPointerException.class);
+
+        Text name = null;
+        new Gateway("type", name);
+    }
+
+    @Test
+    public void shouldThrowOnNullType() {
+        expectedException.expect(NullPointerException.class);
+
+        String nameType = null;
+        new Gateway(nameType, Text.fromRawText("name"));
+    }
+
+    @Test
+    public void shouldThrowOnMultilineType() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String nameType = "name\ntype";
+        new Gateway(nameType, Text.fromRawText("name"));
+    }
+
+    @Test
+    public void addressTypeSHouldDefaultToDNS() {
+        Text address = Text.fromRawText("address");
+        assertThat(new Gateway(address))
+            .isEqualTo(new Gateway(Gateway.DNS, address));
+    }
+
+    @Test
+    public void formattedValueShouldDisplayAddress() {
+        assertThat(new Gateway(Text.fromRawText("address"))
+            .formattedValue())
+            .isEqualTo("MDN-Gateway: dns;address");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayMultilineAddress() {
+        assertThat(new Gateway(Text.fromRawText("address\nmultiline"))
+            .formattedValue())
+            .isEqualTo("MDN-Gateway: dns;address\r\n" +
+                " multiline");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayCustomAddress() {
+        assertThat(new Gateway("custom", Text.fromRawText("address"))
+            .formattedValue())
+            .isEqualTo("MDN-Gateway: custom;address");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
new file mode 100644
index 0000000..58f12c1
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
@@ -0,0 +1,62 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class OriginalMessageIdTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(OriginalMessageId.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNullMessageId() {
+        expectedException.expect(NullPointerException.class);
+
+        new OriginalMessageId(null);
+    }
+
+    @Test
+    public void shouldThrowOnMultiLineMessageId() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new OriginalMessageId("message\nid");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayMessageId() {
+        assertThat(new OriginalMessageId("msgId")
+            .formattedValue())
+            .isEqualTo("Original-Message-ID: msgId");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
new file mode 100644
index 0000000..7a37e54
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
@@ -0,0 +1,95 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.mdn.Constants;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class OriginalRecipientTest {
+    public static final Text ADDRESS = Text.fromRawText("address");
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() throws Exception {
+        EqualsVerifier.forClass(OriginalRecipient.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void shouldThrowOnNullAddress() {
+        expectedException.expect(NullPointerException.class);
+
+        Text originalRecipient = null;
+        new OriginalRecipient(originalRecipient);
+    }
+
+    @Test
+    public void shouldThrowOnNullAddressWhenCustomType() {
+        expectedException.expect(NullPointerException.class);
+
+        Text originalRecipient = null;
+        new OriginalRecipient("customType", originalRecipient);
+    }
+
+    @Test
+    public void shouldThrowOnNullAddressType() {
+        expectedException.expect(NullPointerException.class);
+
+        String addressType = null;
+        new OriginalRecipient(addressType, ADDRESS);
+    }
+
+    @Test
+    public void addressTypeShouldDefaultToRfc822() {
+        assertThat(new OriginalRecipient(ADDRESS))
+            .isEqualTo(new OriginalRecipient(Constants.RFC_822, ADDRESS));
+    }
+
+    @Test
+    public void formattedValueShouldDisplayAddress() {
+        assertThat(new OriginalRecipient(ADDRESS)
+            .formattedValue())
+            .isEqualTo("Original-Recipient: rfc822; address");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayCustomType() {
+        assertThat(new OriginalRecipient("custom", ADDRESS)
+            .formattedValue())
+            .isEqualTo("Original-Recipient: custom; address");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayMultilineAddress() {
+        assertThat(new OriginalRecipient(Text.fromRawText("multiline\naddress"))
+            .formattedValue())
+            .isEqualTo("Original-Recipient: rfc822; multiline\r\n" +
+                " address");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
new file mode 100644
index 0000000..74f3a97
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
@@ -0,0 +1,93 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Optional;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class ReportingUserAgentTest {
+    public static final String USER_AGENT_NAME = "name";
+    public static final String USER_AGENT_PRODUCT = "product";
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContact() {
+        EqualsVerifier.forClass(ReportingUserAgent.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void productShouldBeOptional() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME))
+            .isEqualTo(new ReportingUserAgent(USER_AGENT_NAME, Optional.empty()));
+    }
+
+    @Test
+    public void productShouldBePresentWhenSpecified() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME, USER_AGENT_PRODUCT))
+            .isEqualTo(new ReportingUserAgent(USER_AGENT_NAME, Optional.of(USER_AGENT_PRODUCT)));
+    }
+
+    @Test
+    public void shouldThrowOnNullName() {
+        expectedException.expect(NullPointerException.class);
+
+        String userAgentName = null;
+        new ReportingUserAgent(userAgentName);
+    }
+
+    @Test
+    public void shouldThrowOnNullNameWhenSpecifyingProduct() {
+        expectedException.expect(NullPointerException.class);
+
+        String userAgentName = null;
+        new ReportingUserAgent(userAgentName, USER_AGENT_PRODUCT);
+    }
+
+    @Test
+    public void shouldThrowOnNullProduct() {
+        expectedException.expect(NullPointerException.class);
+
+        String userAgentProduct = null;
+        new ReportingUserAgent(USER_AGENT_NAME, userAgentProduct);
+    }
+
+    @Test
+    public void formattedValueShouldDisplayNameWhenProductMissing() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME).formattedValue())
+            .isEqualTo("Reporting-UA: name; ");
+    }
+
+    @Test
+    public void formattedValueShouldDisplayProduct() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME, USER_AGENT_PRODUCT).formattedValue())
+            .isEqualTo("Reporting-UA: name; product");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/4020b750/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
new file mode 100644
index 0000000..938b6fe
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
@@ -0,0 +1,97 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class TextTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContact() {
+        EqualsVerifier.forClass(Text.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void fromRawTextShouldThrowOnNull() {
+        expectedException.expect(NullPointerException.class);
+
+        Text.fromRawText(null);
+    }
+
+    @Test
+    public void formattedShouldRenderEmptyStrings() {
+        Text text = Text.fromRawText("");
+
+        assertThat(text.formatted()).isEqualTo("");
+    }
+
+    @Test
+    public void formattedShouldKeepSpaces() {
+        Text text = Text.fromRawText("text with spaces");
+
+        assertThat(text.formatted()).isEqualTo("text with spaces");
+    }
+
+    @Test
+    public void formattedShouldWrapLines() {
+        Text text = Text.fromRawText("text with spaces\r\non several lines");
+
+        assertThat(text.formatted()).isEqualTo("text with spaces\r\n on several lines");
+    }
+
+    @Test
+    public void formattedShouldPreserveLineWrapping() {
+        Text text = Text.fromRawText("text with spaces\r\n on several lines");
+
+        assertThat(text.formatted()).isEqualTo("text with spaces\r\n on several lines");
+    }
+
+    @Test
+    public void formattedShouldTrimExtraSpacesAfterWrapping() {
+        Text text = Text.fromRawText("text with spaces\r\n  on several lines");
+
+        assertThat(text.formatted()).isEqualTo("text with spaces\r\n on several lines");
+    }
+
+    @Test
+    public void formattedShouldTrimExtraSpacesBeforeWrapping() {
+        Text text = Text.fromRawText("text with spaces  \r\non several lines");
+
+        assertThat(text.formatted()).isEqualTo("text with spaces\r\n on several lines");
+    }
+
+    @Test
+    public void formattedShouldPreserveFoldingSpaces() {
+        Text text = Text.fromRawText("text with folding    spaces");
+
+        assertThat(text.formatted()).isEqualTo("text with folding    spaces");
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[05/27] james-project git commit: JAMES-2132 Strong typing and builders for MDN reports

Posted by bt...@apache.org.
JAMES-2132 Strong typing and builders for MDN reports


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/13762596
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/13762596
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/13762596

Branch: refs/heads/master
Commit: 13762596b6fa3044af39382058f0120c7e301d85
Parents: 3d8120e
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 11:55:39 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/Constants.java    |  24 +
 .../java/org/apache/james/mdn/Disposition.java  | 181 --------
 .../java/org/apache/james/mdn/MDNFactory.java   |  69 +--
 .../java/org/apache/james/mdn/MDNReport.java    | 135 ++++++
 .../apache/james/mdn/fields/Disposition.java    | 119 +++++
 .../java/org/apache/james/mdn/fields/Field.java |  24 +
 .../apache/james/mdn/fields/FinalRecipient.java |  43 ++
 .../james/mdn/fields/OriginalMessageId.java     |  39 ++
 .../james/mdn/fields/OriginalRecipient.java     |  39 ++
 .../james/mdn/fields/ReportingUserAgent.java    |  46 ++
 .../org/apache/james/mdn/MDNFactoryTest.java    | 456 ++++++++++++++-----
 .../transport/mailets/jsieve/RejectAction.java  |  35 +-
 12 files changed, 841 insertions(+), 369 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/Constants.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/Constants.java b/mdn/src/main/java/org/apache/james/mdn/Constants.java
new file mode 100644
index 0000000..5e07c00
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/Constants.java
@@ -0,0 +1,24 @@
+/****************************************************************
+ * 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.mdn;
+
+public interface Constants {
+    String RFC_822 = "rfc822";
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
deleted file mode 100644
index 381376f..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/Disposition.java
+++ /dev/null
@@ -1,181 +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.mdn;
-
-import org.apache.james.mdn.action.mode.DispositionActionMode;
-import org.apache.james.mdn.modifier.DispositionModifier;
-import org.apache.james.mdn.sending.mode.DispositionSendingMode;
-import org.apache.james.mdn.type.DispositionType;
-
-/**
- * Class <code>Disposition</code> encapsulating
- * disposition information as defined by RFC 2298.
- */
-public class Disposition
-{
-    private DispositionActionMode fieldActionMode;
-    private DispositionSendingMode fieldSendingMode;
-    private DispositionType fieldDispositionType;
-    private DispositionModifier[] fieldDispositionModifiers;
-
-    /**
-     * Default Construcor
-     */
-    private Disposition()
-    {
-        super();
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param actionMode
-     * @param sendingMode
-     * @param type
-     */
-    public Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type)
-    {
-        this();
-        setActionMode(actionMode);
-        setSendingMode(sendingMode);
-        setDispositionType(type);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param actionMode
-     * @param sendingMode
-     * @param type
-     * @param modifiers
-     */
-    public Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type,
-            DispositionModifier[] modifiers)
-    {
-        this(actionMode, sendingMode, type);
-        setDispositionModifiers(modifiers);
-    }
-
-    /**
-     * Answer the Disposition Mode.
-     * 
-     * @return Returns the dispostionMode.
-     */
-    protected DispositionActionMode getActionMode()
-    {
-        return fieldActionMode;
-    }
-
-    /**
-     * Set the Disposition Mode.
-     * 
-     * @param dispostionMode The dispostionMode to set.
-     */
-    protected void setActionMode(DispositionActionMode dispostionMode)
-    {
-        fieldActionMode = dispostionMode;
-    }
-
-    /**
-     * Answer the Disposition Modifiers.
-     * 
-     * @return Returns the dispostionModifiers.
-     */
-    protected DispositionModifier[] getDispositionModifiers()
-    {
-        return fieldDispositionModifiers;
-    }
-
-    /**
-     * Set the Disposition Modifiers.
-     * 
-     * @param dispostionModifiers The dispostionModifiers to set.
-     */
-    protected void setDispositionModifiers(DispositionModifier[] dispostionModifiers)
-    {
-        fieldDispositionModifiers = dispostionModifiers;
-    }
-
-    /**
-     * Answer the Disposition Type.
-     * 
-     * @return Returns the dispostionType.
-     */
-    protected DispositionType getDispositionType()
-    {
-        return fieldDispositionType;
-    }
-
-    /**
-     * Set the Disposition Type.
-     * 
-     * @param dispostionType The dispostionType to set.
-     */
-    protected void setDispositionType(DispositionType dispostionType)
-    {
-        fieldDispositionType = dispostionType;
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        StringBuilder builder = new StringBuilder(64);
-        builder.append("Disposition: ");
-        builder.append(getActionMode() == null ? "" : getActionMode().getValue());
-        builder.append('/');
-        builder.append(getSendingMode() == null ? "" : getSendingMode().getValue());
-        builder.append(';');
-        builder.append(getDispositionType() == null ? "" : getDispositionType().getValue());
-        if (null != getDispositionModifiers()
-                && getDispositionModifiers().length > 0)
-        {
-            builder.append('/');
-            for (int i = 0; i < getDispositionModifiers().length; i++)
-            {
-                if (i > 0)
-                    builder.append(',');
-                builder.append(getDispositionModifiers()[i].getValue());
-            }
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Answer the Sending Mode.
-     * 
-     * @return Returns the sendingMode.
-     */
-    protected DispositionSendingMode getSendingMode()
-    {
-        return fieldSendingMode;
-    }
-
-    /**
-     * Set the Sending Mode.
-     * 
-     * @param sendingMode The sendingMode to set.
-     */
-    protected void setSendingMode(DispositionSendingMode sendingMode)
-    {
-        fieldSendingMode = sendingMode;
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
index 31aae2b..57ff29a 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
@@ -28,39 +28,19 @@ import org.apache.mailet.base.mail.MimeMultipartReport;
  * Class <code>MDNFactory</code> creates MimeMultipartReports containing
  * Message Delivery Notifications as specified by RFC 2298.
  */
-public class MDNFactory
-{
-
-    /**
-     * Default Constructor
-     */
-    private MDNFactory()
-    {
-        super();
-    }
+public class MDNFactory {
     
     /**
      * Answers a MimeMultipartReport containing a
      * Message Delivery Notification as specified by RFC 2298.
      * 
      * @param humanText
-     * @param reporting_UA_name
-     * @param reporting_UA_product
-     * @param original_recipient
-     * @param final_recipient
-     * @param original_message_id
-     * @param disposition
+     * @param mdnReport
      * @return MimeMultipartReport
      * @throws MessagingException
      */
-    static public MimeMultipartReport create(String humanText,
-            String reporting_UA_name,
-            String reporting_UA_product,
-            String original_recipient,
-            String final_recipient,
-            String original_message_id,
-            Disposition disposition) throws MessagingException
-    {
+    public static MimeMultipartReport create(String humanText,
+            MDNReport mdnReport) throws MessagingException {
         // Create the message parts. According to RFC 2298, there are two
         // compulsory parts and one optional part...
         MimeMultipartReport multiPart = new MimeMultipartReport();
@@ -72,15 +52,8 @@ public class MDNFactory
         multiPart.addBodyPart(humanPart);
 
         // Part 2: MDN Report Part
-        String mdnReport = generateMDNReport(reporting_UA_name,
-            reporting_UA_product,
-            original_recipient,
-            final_recipient,
-            original_message_id,
-            disposition);
-
         MimeBodyPart mdnPart = new MimeBodyPart();
-        mdnPart.setContent(mdnReport, "message/disposition-notification");
+        mdnPart.setContent(mdnReport.formattedValue(), "message/disposition-notification");
         multiPart.addBodyPart(mdnPart);
 
         // Part 3: The optional third part, the original message is omitted.
@@ -92,36 +65,4 @@ public class MDNFactory
         return multiPart;
     }
 
-    public static String generateMDNReport(String reporting_UA_name, String reporting_UA_product, String original_recipient,
-                                                   String final_recipient, String original_message_id, Disposition disposition) {
-        // 1) reporting-ua-field
-        StringBuilder mdnReport = new StringBuilder(128);
-        mdnReport.append("Reporting-UA: ");
-        mdnReport.append((reporting_UA_name == null ? "" : reporting_UA_name));
-        mdnReport.append("; ");
-        mdnReport.append((reporting_UA_product == null ? "" : reporting_UA_product));
-        mdnReport.append("\r\n");
-        // 2) original-recipient-field
-        if (null != original_recipient)
-        {
-            mdnReport.append("Original-Recipient: ");
-            mdnReport.append("rfc822; ");
-            mdnReport.append(original_recipient);
-            mdnReport.append("\r\n");
-        }
-        // 3) final-recipient-field
-        mdnReport.append("Final-Recepient: ");
-        mdnReport.append("rfc822; ");
-        mdnReport.append((final_recipient == null ? "" : final_recipient));
-        mdnReport.append("\r\n");
-        // 4) original-message-id-field
-        mdnReport.append("Original-Message-ID: ");
-        mdnReport.append((original_message_id == null ? "" : original_message_id));
-        mdnReport.append("\r\n");
-        // 5) disposition-field
-        mdnReport.append(disposition.toString());
-        mdnReport.append("\r\n");
-        return mdnReport.toString();
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
new file mode 100644
index 0000000..966ad06
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -0,0 +1,135 @@
+/****************************************************************
+ * 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.mdn;
+
+import java.util.Optional;
+
+import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.OriginalMessageId;
+import org.apache.james.mdn.fields.OriginalRecipient;
+import org.apache.james.mdn.fields.ReportingUserAgent;
+
+import com.google.common.base.Preconditions;
+
+public class MDNReport {
+
+    public static class Builder {
+        private Optional<ReportingUserAgent> reportingUserAgentField = Optional.empty();
+        private Optional<OriginalRecipient> originalRecipientField = Optional.empty();
+        private Optional<FinalRecipient> finalRecipientField = Optional.empty();
+        private Optional<OriginalMessageId> originalMessageIdField = Optional.empty();
+        private Optional<Disposition> dispositionField = Optional.empty();
+
+        public Builder reportingUserAgentField(ReportingUserAgent reportingUserAgentField) {
+            this.reportingUserAgentField = Optional.of(reportingUserAgentField);
+            return this;
+        }
+
+        public Builder originalRecipientField(OriginalRecipient originalRecipientField) {
+            this.originalRecipientField = Optional.of(originalRecipientField);
+            return this;
+        }
+
+        public Builder originalRecipientField(Optional<OriginalRecipient> originalRecipientField) {
+            this.originalRecipientField = originalRecipientField;
+            return this;
+        }
+
+        public Builder finalRecipientField(FinalRecipient finalRecipientField) {
+            this.finalRecipientField = Optional.of(finalRecipientField);
+            return this;
+        }
+
+        public Builder originalMessageIdField(OriginalMessageId originalMessageIdField) {
+            this.originalMessageIdField = Optional.of(originalMessageIdField);
+            return this;
+        }
+
+        public Builder dispositionField(Disposition dispositionField) {
+            this.dispositionField = Optional.of(dispositionField);
+            return this;
+        }
+
+        public MDNReport build() {
+            Preconditions.checkState(reportingUserAgentField.isPresent());
+            Preconditions.checkState(finalRecipientField.isPresent());
+            Preconditions.checkState(originalMessageIdField.isPresent());
+            Preconditions.checkState(dispositionField.isPresent());
+
+            return new MDNReport(reportingUserAgentField.get(),
+                originalRecipientField,
+                finalRecipientField.get(),
+                originalMessageIdField.get(),
+                dispositionField.get());
+        }
+
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final String LINE_END = "\r\n";
+
+    private final ReportingUserAgent reportingUserAgentField;
+    private final Optional<OriginalRecipient> originalRecipientField;
+    private final FinalRecipient finalRecipientField;
+    private final OriginalMessageId originalMessageIdField;
+    private final Disposition dispositionField;
+
+    private MDNReport(ReportingUserAgent reportingUserAgentField, Optional<OriginalRecipient> originalRecipientField,
+                     FinalRecipient finalRecipientField, OriginalMessageId originalMessageIdField, Disposition dispositionField) {
+        this.reportingUserAgentField = reportingUserAgentField;
+        this.originalRecipientField = originalRecipientField;
+        this.finalRecipientField = finalRecipientField;
+        this.originalMessageIdField = originalMessageIdField;
+        this.dispositionField = dispositionField;
+    }
+
+    public ReportingUserAgent getReportingUserAgentField() {
+        return reportingUserAgentField;
+    }
+
+    public Optional<OriginalRecipient> getOriginalRecipientField() {
+        return originalRecipientField;
+    }
+
+    public FinalRecipient getFinalRecipientField() {
+        return finalRecipientField;
+    }
+
+    public OriginalMessageId getOriginalMessageIdField() {
+        return originalMessageIdField;
+    }
+
+    public Disposition getDispositionField() {
+        return dispositionField;
+    }
+
+    public String formattedValue() {
+        return reportingUserAgentField.formattedValue() + LINE_END
+            + originalRecipientField.map(value -> value.formattedValue() + "\r\n").orElse("")
+            + finalRecipientField.formattedValue() + "\r\n"
+            + originalMessageIdField.formattedValue() + "\r\n"
+            + dispositionField.formattedValue() + "\r\n";
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
new file mode 100644
index 0000000..85a0474
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
@@ -0,0 +1,119 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
+
+import com.google.common.collect.ImmutableList;
+
+public class Disposition implements Field {
+    public static class Builder {
+        private Optional<DispositionActionMode> actionMode = Optional.empty();
+        private Optional<DispositionSendingMode> sendingMode = Optional.empty();
+        private Optional<DispositionType> type = Optional.empty();
+        private ImmutableList.Builder<DispositionModifier> modifiers = ImmutableList.builder();
+
+        public Builder actionMode(DispositionActionMode actionMode) {
+            this.actionMode = Optional.of(actionMode);
+            return this;
+        }
+
+        public Builder sendingMode(DispositionSendingMode sendingMode) {
+            this.sendingMode = Optional.of(sendingMode);
+            return this;
+        }
+
+        public Builder type(DispositionType type) {
+            this.type = Optional.of(type);
+            return this;
+        }
+
+        public Builder addModifier(DispositionModifier modifier) {
+            this.modifiers.add(modifier);
+            return this;
+        }
+
+        public Builder addModifiers(DispositionModifier... modifiers) {
+            this.modifiers.add(modifiers);
+            return this;
+        }
+
+        public Disposition build() {
+            return new Disposition(actionMode, sendingMode, type, modifiers.build());
+        }
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    private final Optional<DispositionActionMode> actionMode;
+    private final Optional<DispositionSendingMode> sendingMode;
+    private final Optional<DispositionType> type;
+    private final List<DispositionModifier> modifiers;
+
+    private Disposition(Optional<DispositionActionMode> actionMode, Optional<DispositionSendingMode> sendingMode, Optional<DispositionType> type, List<DispositionModifier> modifiers) {
+        this.actionMode = actionMode;
+        this.sendingMode = sendingMode;
+        this.type = type;
+        this.modifiers = ImmutableList.copyOf(modifiers);
+    }
+
+    public Optional<DispositionActionMode> getActionMode() {
+        return actionMode;
+    }
+
+    public Optional<DispositionSendingMode> getSendingMode() {
+        return sendingMode;
+    }
+
+    public Optional<DispositionType> getType() {
+        return type;
+    }
+
+    public List<DispositionModifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public String formattedValue() {
+        return "Disposition: "
+            + actionMode.map(DispositionActionMode::getValue).orElse("") + "/"
+            + sendingMode.map(DispositionSendingMode::getValue).orElse("") + ";"
+            + type.map(DispositionType::getValue).orElse("")
+            + formattedModifiers();
+    }
+
+    private CharSequence formattedModifiers() {
+        if (modifiers.isEmpty()) {
+            return "";
+        }
+        return "/" + modifiers.stream()
+            .map(DispositionModifier::getValue)
+            .collect(Collectors.joining(","));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Field.java b/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
new file mode 100644
index 0000000..bef0139
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
@@ -0,0 +1,24 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+public interface Field {
+    String formattedValue();
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
new file mode 100644
index 0000000..a9799d2
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import java.util.Optional;
+
+import org.apache.james.mdn.Constants;
+
+public class FinalRecipient implements Field {
+    public static final String FIELD_NAME = "Final-Recepient";
+
+    private final Optional<String> finalRecipient;
+
+    public FinalRecipient(Optional<String> finalRecipient) {
+        this.finalRecipient = finalRecipient;
+    }
+
+    public Optional<String> getFinalRecipient() {
+        return finalRecipient;
+    }
+
+    @Override
+    public String formattedValue() {
+        return FIELD_NAME + ": " + Constants.RFC_822 + "; " + finalRecipient.orElse("");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
new file mode 100644
index 0000000..f72d7cb
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import java.util.Optional;
+
+public class OriginalMessageId implements Field {
+    private final Optional<String> originalMessageId;
+
+    public OriginalMessageId(Optional<String> originalMessageId) {
+        this.originalMessageId = originalMessageId;
+    }
+
+    public Optional<String> getOriginalMessageId() {
+        return originalMessageId;
+    }
+
+    @Override
+    public String formattedValue() {
+        return "Original-Message-ID: " + originalMessageId.orElse("");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
new file mode 100644
index 0000000..a44c055
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import org.apache.james.mdn.Constants;
+
+public class OriginalRecipient implements Field{
+    private final String originalRecipient;
+
+    public OriginalRecipient(String originalRecipient) {
+        this.originalRecipient = originalRecipient;
+    }
+
+    public String getOriginalRecipient() {
+        return originalRecipient;
+    }
+
+    @Override
+    public String formattedValue() {
+        return "Original-Recipient: " + Constants.RFC_822 + "; " + originalRecipient;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
new file mode 100644
index 0000000..0072434
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -0,0 +1,46 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import java.util.Optional;
+
+public class ReportingUserAgent implements Field {
+    private final Optional<String> userAgentName;
+    private final Optional<String> userAgentProduct;
+
+    public ReportingUserAgent(Optional<String> userAgentName, Optional<String> userAgentProduct) {
+        this.userAgentName = userAgentName;
+        this.userAgentProduct = userAgentProduct;
+    }
+
+    public Optional<String> getUserAgentName() {
+        return userAgentName;
+    }
+
+    public Optional<String> getUserAgentProduct() {
+        return userAgentProduct;
+    }
+
+    @Override
+    public String formattedValue() {
+        return "Reporting-UA: " + userAgentName.orElse("") + "; "
+            + userAgentProduct.orElse("");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 5272252..0837fdd 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -21,7 +21,14 @@ package org.apache.james.mdn;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.util.Optional;
+
 import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.OriginalMessageId;
+import org.apache.james.mdn.fields.OriginalRecipient;
+import org.apache.james.mdn.fields.ReportingUserAgent;
 import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
@@ -36,12 +43,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatAutomaticActions() {
-        Disposition disposition = new Disposition(DispositionActionMode.Automatic, DispositionSendingMode.Automatic, DispositionType.Processed);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -53,12 +72,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatManualActions() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Processed);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -70,12 +101,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDenied() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Denied);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Denied)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -87,12 +130,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDispatcher() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Dispatched);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+        .actionMode(DispositionActionMode.Manual)
+        .sendingMode(DispositionSendingMode.Manual)
+        .type(DispositionType.Dispatched)
+        .addModifier(DispositionModifier.Error)
+        .addModifier(DispositionModifier.Failed)
+        .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -104,12 +159,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDisplayed() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Displayed);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+        .actionMode(DispositionActionMode.Manual)
+        .sendingMode(DispositionSendingMode.Manual)
+        .type(DispositionType.Displayed)
+        .addModifier(DispositionModifier.Error)
+        .addModifier(DispositionModifier.Failed)
+        .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -121,12 +188,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeFailed() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Failed);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Failed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -138,12 +217,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDeleted() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -155,13 +246,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatAllModifier() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
-            DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifiers(DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
+                DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -172,13 +274,51 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatNoModifier() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {};
-        disposition.setDispositionModifiers(dispostionModifiers);
+    public void generateMDNReportShouldFormatOneModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/error\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNoModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -190,13 +330,21 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNoModifierNullType() {
-        DispositionType type = null;
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, type);
-        DispositionModifier[] dispostionModifiers = {};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -208,13 +356,23 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullActionMode() {
-        DispositionActionMode actionMode = null;
-        Disposition disposition = new Disposition(actionMode, DispositionSendingMode.Manual, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -226,13 +384,23 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullSendingMode() {
-        DispositionSendingMode sendingMode = null;
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, sendingMode, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -244,13 +412,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullUserAgentName() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String reporting_ua_name = null;
-        String report = MDNFactory.generateMDNReport(reporting_ua_name, "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.empty(),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: ; UA_product\r\n" +
@@ -262,13 +441,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullUserAgentProduct() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String reporting_ua_product = null;
-        String report = MDNFactory.generateMDNReport("UA_name", reporting_ua_product, "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.empty()))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; \r\n" +
@@ -280,13 +470,23 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullOriginalRecipient() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String original_recipient = null;
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", original_recipient,
-            "final_recipient", "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -297,13 +497,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullFinalRecipient() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String final_recipient = null;
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            final_recipient, "original_message_id", disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.empty()))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -315,13 +526,24 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullOriginalMessageId() {
-        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
-        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
-        disposition.setDispositionModifiers(dispostionModifiers);
-
-        String original_message_id = null;
-        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", original_message_id, disposition);
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.empty()))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
@@ -334,8 +556,14 @@ public class MDNFactoryTest {
     @Test
     public void generateMDNReportThrowOnNullDisposition() {
         Disposition disposition = null;
-        expectedException.expect(NullPointerException.class);
-        MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
-            "final_recipient", "original_message_id", disposition);
+        expectedException.expect(IllegalStateException.class);
+
+        MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                Optional.of("UA_name"),
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .build();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/13762596/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index d206303..4f50e12 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -22,6 +22,7 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Optional;
 
 import javax.mail.Address;
 import javax.mail.MessagingException;
@@ -29,9 +30,14 @@ import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 
-import org.apache.james.mdn.Disposition;
 import org.apache.james.mdn.MDNFactory;
+import org.apache.james.mdn.MDNReport;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.OriginalMessageId;
+import org.apache.james.mdn.fields.OriginalRecipient;
+import org.apache.james.mdn.fields.ReportingUserAgent;
 import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
@@ -108,17 +114,26 @@ public class RejectAction implements MailAction {
         }
 
         MailAddress soleRecipient = ActionUtils.getSoleRecipient(aMail);
-        String final_recipient = soleRecipient.toString();
-
+        String final_recipient = soleRecipient.asString();
         String original_message_id = aMail.getMessage().getMessageID();
 
-        DispositionModifier modifiers[] = {DispositionModifier.Error};
-        Disposition disposition = new Disposition(DispositionActionMode.Automatic,
-                DispositionSendingMode.Automatic, DispositionType.Deleted, modifiers);
-
-        MimeMultipart multiPart = MDNFactory.create(humanText.toString(),
-                reporting_UA_name, reporting_UA_product, original_recipient,
-                final_recipient, original_message_id, disposition);
+        MimeMultipart multiPart = MDNFactory.create(
+            humanText.toString(),
+            MDNReport.builder()
+                .reportingUserAgentField(
+                    new ReportingUserAgent(
+                        Optional.ofNullable(reporting_UA_name),
+                        Optional.ofNullable(reporting_UA_product)))
+                .finalRecipientField(new FinalRecipient(Optional.of(final_recipient)))
+                .originalRecipientField(Optional.ofNullable(original_recipient).map(OriginalRecipient::new))
+                .originalMessageIdField(new OriginalMessageId(Optional.of(original_message_id)))
+                .dispositionField(Disposition.builder()
+                    .actionMode(DispositionActionMode.Automatic)
+                    .sendingMode(DispositionSendingMode.Automatic)
+                    .type(DispositionType.Deleted)
+                    .addModifier(DispositionModifier.Error)
+                    .build())
+                .build());
 
         // Send the message
         MimeMessage reply = (MimeMessage) aMail.getMessage().reply(false);


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[07/27] james-project git commit: JAMES-2132 improve package structure

Posted by bt...@apache.org.
JAMES-2132 improve package structure


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/bbc0bfad
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/bbc0bfad
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/bbc0bfad

Branch: refs/heads/master
Commit: bbc0bfad8572165d39f2cca776097ef1b0910902
Parents: 976a303
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 10:49:20 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../apache/james/mdn/ActionModeAutomatic.java   | 42 -----------------
 .../org/apache/james/mdn/ActionModeManual.java  | 47 --------------------
 .../java/org/apache/james/mdn/Disposition.java  |  5 +++
 .../apache/james/mdn/DispositionActionMode.java | 29 ------------
 .../apache/james/mdn/DispositionModifier.java   | 29 ------------
 .../james/mdn/DispositionSendingMode.java       | 29 ------------
 .../org/apache/james/mdn/DispositionType.java   | 29 ------------
 .../org/apache/james/mdn/ModifierError.java     | 44 ------------------
 .../org/apache/james/mdn/ModifierExpired.java   | 45 -------------------
 .../org/apache/james/mdn/ModifierFailed.java    | 45 -------------------
 .../james/mdn/ModifierMailboxTerminated.java    | 45 -------------------
 .../apache/james/mdn/ModifierSuperseded.java    | 45 -------------------
 .../org/apache/james/mdn/ModifierWarning.java   | 45 -------------------
 .../apache/james/mdn/SendingModeAutomatic.java  | 45 -------------------
 .../org/apache/james/mdn/SendingModeManual.java | 45 -------------------
 .../java/org/apache/james/mdn/TypeDeleted.java  | 45 -------------------
 .../java/org/apache/james/mdn/TypeDenied.java   | 44 ------------------
 .../org/apache/james/mdn/TypeDispatched.java    | 43 ------------------
 .../org/apache/james/mdn/TypeDisplayed.java     | 44 ------------------
 .../java/org/apache/james/mdn/TypeFailed.java   | 44 ------------------
 .../org/apache/james/mdn/TypeProcessed.java     | 44 ------------------
 .../mdn/action/mode/ActionModeAutomatic.java    | 42 +++++++++++++++++
 .../james/mdn/action/mode/ActionModeManual.java | 47 ++++++++++++++++++++
 .../mdn/action/mode/DispositionActionMode.java  | 29 ++++++++++++
 .../james/mdn/modifier/DispositionModifier.java | 29 ++++++++++++
 .../james/mdn/modifier/ModifierError.java       | 44 ++++++++++++++++++
 .../james/mdn/modifier/ModifierExpired.java     | 45 +++++++++++++++++++
 .../james/mdn/modifier/ModifierFailed.java      | 45 +++++++++++++++++++
 .../mdn/modifier/ModifierMailboxTerminated.java | 45 +++++++++++++++++++
 .../james/mdn/modifier/ModifierSuperseded.java  | 45 +++++++++++++++++++
 .../james/mdn/modifier/ModifierWarning.java     | 45 +++++++++++++++++++
 .../sending/mode/DispositionSendingMode.java    | 29 ++++++++++++
 .../mdn/sending/mode/SendingModeAutomatic.java  | 45 +++++++++++++++++++
 .../mdn/sending/mode/SendingModeManual.java     | 45 +++++++++++++++++++
 .../apache/james/mdn/type/DispositionType.java  | 29 ++++++++++++
 .../org/apache/james/mdn/type/TypeDeleted.java  | 45 +++++++++++++++++++
 .../org/apache/james/mdn/type/TypeDenied.java   | 44 ++++++++++++++++++
 .../apache/james/mdn/type/TypeDispatched.java   | 43 ++++++++++++++++++
 .../apache/james/mdn/type/TypeDisplayed.java    | 44 ++++++++++++++++++
 .../org/apache/james/mdn/type/TypeFailed.java   | 44 ++++++++++++++++++
 .../apache/james/mdn/type/TypeProcessed.java    | 44 ++++++++++++++++++
 .../transport/mailets/jsieve/RejectAction.java  | 11 +++--
 42 files changed, 838 insertions(+), 834 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java
deleted file mode 100644
index 31bdf91..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java
+++ /dev/null
@@ -1,42 +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.mdn;
-
-
-/**
- * Class <code>ActionModeAutomatic</code>
- */
-public class ActionModeAutomatic implements DispositionActionMode {
-
-    /**
-     * Default Constructor
-     */
-    public ActionModeAutomatic() {
-        super();
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return "automatic-action";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java b/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java
deleted file mode 100644
index ab71030..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java
+++ /dev/null
@@ -1,47 +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.mdn;
-
-
-/**
- * Class <code>ActionModeManual</code>
- */
-public class ActionModeManual
-        implements
-            DispositionActionMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public ActionModeManual()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "manual-action";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
index b74ef4d..9fcc8a5 100644
--- a/mdn/src/main/java/org/apache/james/mdn/Disposition.java
+++ b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
@@ -19,6 +19,11 @@
 
 package org.apache.james.mdn;
 
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
+
 /**
  * Class <code>Disposition</code> encapsulating
  * disposition information as defined by RFC 2298.

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java b/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java
deleted file mode 100644
index 969f31f..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java
+++ /dev/null
@@ -1,29 +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.mdn;
-
-/**
- * Interface <code>DispositionActionMode</code> marks a type encapsulating
- * disposition action mode information as defined by RFC 2298.
- */
-public interface DispositionActionMode
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java
deleted file mode 100644
index 041b525..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java
+++ /dev/null
@@ -1,29 +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.mdn;
-
-/**
- * Interface <code>DispositionModifier</code> marks a type encapsulating
- * disposition modifier information as defined by RFC 2298.
- */
-public interface DispositionModifier
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java b/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java
deleted file mode 100644
index 2f3e815..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java
+++ /dev/null
@@ -1,29 +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.mdn;
-
-/**
- * Interface <code>DispositionSendingMode</code> marks a type encapsulating
- * disposition sending mode information as defined by RFC 2298.
- */
-public interface DispositionSendingMode
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/DispositionType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionType.java b/mdn/src/main/java/org/apache/james/mdn/DispositionType.java
deleted file mode 100644
index af2dacd..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/DispositionType.java
+++ /dev/null
@@ -1,29 +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.mdn;
-
-/**
- * Interface <code>DispositionType</code> marks a type encapsulating
- * disposition type information as defined by RFC 2298.
- */
-public interface DispositionType
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ModifierError.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierError.java b/mdn/src/main/java/org/apache/james/mdn/ModifierError.java
deleted file mode 100644
index b1692f8..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ModifierError.java
+++ /dev/null
@@ -1,44 +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.mdn;
-
-
-/**
- * Class <code>ModifierError</code>
- */
-public class ModifierError implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierError()
-    {
-        super();
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "error";
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java b/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java
deleted file mode 100644
index 9d7c678..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>ModifierExpired</code>
- */    
-public class ModifierExpired implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierExpired()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "expired";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java b/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java
deleted file mode 100644
index b2a7fe0..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>ModifierFailed</code>
- */    
-public class ModifierFailed implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierFailed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "failed";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java b/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java
deleted file mode 100644
index 0c0d10d..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>ModifierMailboxTerminated</code>
- */    
-public class ModifierMailboxTerminated implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierMailboxTerminated()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "mailbox-terminated";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java b/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java
deleted file mode 100644
index dfeabfb..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>ModifierSuperseded</code>
- */    
-public class ModifierSuperseded implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierSuperseded()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "superseded";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java b/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java
deleted file mode 100644
index 95cbe4f..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>ModifierWarning</code>
- */    
-public class ModifierWarning implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierWarning()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "warning";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java
deleted file mode 100644
index c716628..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>SendingModeAutomatic</code>
- */
-public class SendingModeAutomatic implements DispositionSendingMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public SendingModeAutomatic()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "MDN-sent-automatically";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java b/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java
deleted file mode 100644
index a86a71e..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>SendingModeManual</code>
- */
-public class SendingModeManual implements DispositionSendingMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public SendingModeManual()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "MDN-sent-manually";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java b/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java
deleted file mode 100644
index 4c6d30a..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java
+++ /dev/null
@@ -1,45 +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.mdn;
-
-
-/**
- * Class <code>TypeDeleted</code>
- */
-public class TypeDeleted implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDeleted()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "deleted";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java b/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java
deleted file mode 100644
index eddab50..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java
+++ /dev/null
@@ -1,44 +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.mdn;
-
-
-/**
- * Class <code>TypeDenied</code>
- */    
-public class TypeDenied implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDenied()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "denied";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java b/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java
deleted file mode 100644
index a814c24..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java
+++ /dev/null
@@ -1,43 +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.mdn;
-
-
-/**
- * Class <code>TypeDispatched</code>
- */
-public class TypeDispatched implements DispositionType
-{
-    /**
-     * Default Constructor
-     */
-    public TypeDispatched()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "dispatched";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java b/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java
deleted file mode 100644
index d82589e..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java
+++ /dev/null
@@ -1,44 +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.mdn;
-
-
-/**
- * Class <code>TypeDisplayed</code>
- */
-public class TypeDisplayed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDisplayed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "displayed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java b/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java
deleted file mode 100644
index 8d6ba3d..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java
+++ /dev/null
@@ -1,44 +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.mdn;
-
-
-/**
- * Class <code>TypeFailed</code>
- */    
-public class TypeFailed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeFailed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "failed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java b/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java
deleted file mode 100644
index b377c86..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java
+++ /dev/null
@@ -1,44 +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.mdn;
-
-
-/**
- * Class <code>TypeProcessed</code>
- */    
-public class TypeProcessed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeProcessed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "processed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java
new file mode 100644
index 0000000..d4b4459
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.mdn.action.mode;
+
+
+/**
+ * Class <code>ActionModeAutomatic</code>
+ */
+public class ActionModeAutomatic implements DispositionActionMode {
+
+    /**
+     * Default Constructor
+     */
+    public ActionModeAutomatic() {
+        super();
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "automatic-action";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java
new file mode 100644
index 0000000..1a2a7b7
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java
@@ -0,0 +1,47 @@
+/****************************************************************
+ * 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.mdn.action.mode;
+
+
+/**
+ * Class <code>ActionModeManual</code>
+ */
+public class ActionModeManual
+        implements
+            DispositionActionMode
+{
+
+    /**
+     * Default Constructor
+     */
+    public ActionModeManual()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "manual-action";
+    }         
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
new file mode 100644
index 0000000..b855e08
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn.action.mode;
+
+/**
+ * Interface <code>DispositionActionMode</code> marks a type encapsulating
+ * disposition action mode information as defined by RFC 2298.
+ */
+public interface DispositionActionMode
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
new file mode 100644
index 0000000..66ab46a
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+/**
+ * Interface <code>DispositionModifier</code> marks a type encapsulating
+ * disposition modifier information as defined by RFC 2298.
+ */
+public interface DispositionModifier
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java
new file mode 100644
index 0000000..2a6feed
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+
+/**
+ * Class <code>ModifierError</code>
+ */
+public class ModifierError implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierError()
+    {
+        super();
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "error";
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java
new file mode 100644
index 0000000..9a73b0e
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+
+/**
+ * Class <code>ModifierExpired</code>
+ */    
+public class ModifierExpired implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierExpired()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "expired";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java
new file mode 100644
index 0000000..53edbe2
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+
+/**
+ * Class <code>ModifierFailed</code>
+ */    
+public class ModifierFailed implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierFailed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "failed";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java
new file mode 100644
index 0000000..b2c6ade
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+
+/**
+ * Class <code>ModifierMailboxTerminated</code>
+ */    
+public class ModifierMailboxTerminated implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierMailboxTerminated()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "mailbox-terminated";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java
new file mode 100644
index 0000000..11786f9
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+
+/**
+ * Class <code>ModifierSuperseded</code>
+ */    
+public class ModifierSuperseded implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierSuperseded()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "superseded";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java
new file mode 100644
index 0000000..de8d1c6
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.modifier;
+
+
+/**
+ * Class <code>ModifierWarning</code>
+ */    
+public class ModifierWarning implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierWarning()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "warning";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
new file mode 100644
index 0000000..741c661
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn.sending.mode;
+
+/**
+ * Interface <code>DispositionSendingMode</code> marks a type encapsulating
+ * disposition sending mode information as defined by RFC 2298.
+ */
+public interface DispositionSendingMode
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java
new file mode 100644
index 0000000..f847007
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.sending.mode;
+
+
+/**
+ * Class <code>SendingModeAutomatic</code>
+ */
+public class SendingModeAutomatic implements DispositionSendingMode
+{
+
+    /**
+     * Default Constructor
+     */
+    public SendingModeAutomatic()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "MDN-sent-automatically";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java
new file mode 100644
index 0000000..1087082
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.sending.mode;
+
+
+/**
+ * Class <code>SendingModeManual</code>
+ */
+public class SendingModeManual implements DispositionSendingMode
+{
+
+    /**
+     * Default Constructor
+     */
+    public SendingModeManual()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "MDN-sent-manually";
+    }         
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
new file mode 100644
index 0000000..c02ba2e
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn.type;
+
+/**
+ * Interface <code>DispositionType</code> marks a type encapsulating
+ * disposition type information as defined by RFC 2298.
+ */
+public interface DispositionType
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java
new file mode 100644
index 0000000..028e644
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn.type;
+
+
+/**
+ * Class <code>TypeDeleted</code>
+ */
+public class TypeDeleted implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeDeleted()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "deleted";
+    }         
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java
new file mode 100644
index 0000000..3430f65
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn.type;
+
+
+/**
+ * Class <code>TypeDenied</code>
+ */    
+public class TypeDenied implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeDenied()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "denied";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java
new file mode 100644
index 0000000..5bf9190
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.mdn.type;
+
+
+/**
+ * Class <code>TypeDispatched</code>
+ */
+public class TypeDispatched implements DispositionType
+{
+    /**
+     * Default Constructor
+     */
+    public TypeDispatched()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "dispatched";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java
new file mode 100644
index 0000000..48e9323
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn.type;
+
+
+/**
+ * Class <code>TypeDisplayed</code>
+ */
+public class TypeDisplayed implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeDisplayed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "displayed";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java
new file mode 100644
index 0000000..067c892
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn.type;
+
+
+/**
+ * Class <code>TypeFailed</code>
+ */    
+public class TypeFailed implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeFailed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "failed";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java
new file mode 100644
index 0000000..ed1895b
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn.type;
+
+
+/**
+ * Class <code>TypeProcessed</code>
+ */    
+public class TypeProcessed implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeProcessed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "processed";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc0bfad/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index 460f9f7..c2ee308 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -29,14 +29,13 @@ import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 
-
-import org.apache.james.mdn.ActionModeAutomatic;
 import org.apache.james.mdn.Disposition;
-import org.apache.james.mdn.DispositionModifier;
 import org.apache.james.mdn.MDNFactory;
-import org.apache.james.mdn.ModifierError;
-import org.apache.james.mdn.SendingModeAutomatic;
-import org.apache.james.mdn.TypeDeleted;
+import org.apache.james.mdn.action.mode.ActionModeAutomatic;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.modifier.ModifierError;
+import org.apache.james.mdn.sending.mode.SendingModeAutomatic;
+import org.apache.james.mdn.type.TypeDeleted;
 import org.apache.jsieve.mail.Action;
 import org.apache.jsieve.mail.ActionReject;
 import org.apache.mailet.Mail;


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[12/27] james-project git commit: JAMES-2132 Correct MDN Disposition structure

Posted by bt...@apache.org.
JAMES-2132 Correct MDN Disposition structure

https://tools.ietf.org/html/rfc8098#section-3.2.6 states:

   disposition-field =
             "Disposition" ":" OWS disposition-mode OWS ";"
             OWS disposition-type
             [ OWS "/" OWS disposition-modifier
             *( OWS "," OWS disposition-modifier ) ] OWS

   disposition-mode = action-mode OWS "/" OWS sending-mode

action-mode sending-mode and disposition-type are compulsory


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/fdd5cf34
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/fdd5cf34
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/fdd5cf34

Branch: refs/heads/master
Commit: fdd5cf34820116119782db85c9a0b1ca4398a842
Parents: d4303c5
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:36:48 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 .../apache/james/mdn/fields/Disposition.java    | 25 +++---
 .../org/apache/james/mdn/MDNFactoryTest.java    | 82 --------------------
 2 files changed, 14 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/fdd5cf34/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
index 85a0474..a3c802e 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
@@ -28,6 +28,7 @@ import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 public class Disposition implements Field {
@@ -63,7 +64,11 @@ public class Disposition implements Field {
         }
 
         public Disposition build() {
-            return new Disposition(actionMode, sendingMode, type, modifiers.build());
+            Preconditions.checkState(actionMode.isPresent());
+            Preconditions.checkState(sendingMode.isPresent());
+            Preconditions.checkState(type.isPresent());
+
+            return new Disposition(actionMode.get(), sendingMode.get(), type.get(), modifiers.build());
         }
     }
 
@@ -71,27 +76,27 @@ public class Disposition implements Field {
         return new Builder();
     }
 
-    private final Optional<DispositionActionMode> actionMode;
-    private final Optional<DispositionSendingMode> sendingMode;
-    private final Optional<DispositionType> type;
+    private final DispositionActionMode actionMode;
+    private final DispositionSendingMode sendingMode;
+    private final DispositionType type;
     private final List<DispositionModifier> modifiers;
 
-    private Disposition(Optional<DispositionActionMode> actionMode, Optional<DispositionSendingMode> sendingMode, Optional<DispositionType> type, List<DispositionModifier> modifiers) {
+    private Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type, List<DispositionModifier> modifiers) {
         this.actionMode = actionMode;
         this.sendingMode = sendingMode;
         this.type = type;
         this.modifiers = ImmutableList.copyOf(modifiers);
     }
 
-    public Optional<DispositionActionMode> getActionMode() {
+    public DispositionActionMode getActionMode() {
         return actionMode;
     }
 
-    public Optional<DispositionSendingMode> getSendingMode() {
+    public DispositionSendingMode getSendingMode() {
         return sendingMode;
     }
 
-    public Optional<DispositionType> getType() {
+    public DispositionType getType() {
         return type;
     }
 
@@ -102,9 +107,7 @@ public class Disposition implements Field {
     @Override
     public String formattedValue() {
         return "Disposition: "
-            + actionMode.map(DispositionActionMode::getValue).orElse("") + "/"
-            + sendingMode.map(DispositionSendingMode::getValue).orElse("") + ";"
-            + type.map(DispositionType::getValue).orElse("")
+            + actionMode.getValue() + "/" + sendingMode.getValue() + ";" + type.getValue()
             + formattedModifiers();
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/fdd5cf34/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 9749d81..968c788 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -330,88 +330,6 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatNoModifierNullType() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatNullActionMode() {
-        Disposition disposition = Disposition.builder()
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: /MDN-sent-manually;deleted/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatNullSendingMode() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/;deleted/error,failed\r\n");
-    }
-
-    @Test
     public void generateMDNReportShouldFormatNullUserAgentProduct() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[25/27] james-project git commit: JAMES-2132 More functional style on MDN reports formatting

Posted by bt...@apache.org.
JAMES-2132 More functional style on MDN reports formatting


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/599bec32
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/599bec32
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/599bec32

Branch: refs/heads/master
Commit: 599bec32c02a181f3713c0849d15dc0f10974609
Parents: 1f443cd
Author: benwa <bt...@linagora.com>
Authored: Wed Aug 30 16:15:53 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:16:14 2017 +0700

----------------------------------------------------------------------
 mdn/pom.xml                                     |  4 ++
 .../java/org/apache/james/mdn/MDNReport.java    | 47 +++++++++-----------
 2 files changed, 26 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/599bec32/mdn/pom.xml
----------------------------------------------------------------------
diff --git a/mdn/pom.xml b/mdn/pom.xml
index 7eb7d4b..9e8441a 100644
--- a/mdn/pom.xml
+++ b/mdn/pom.xml
@@ -34,6 +34,10 @@
 
     <dependencies>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>james-server-util-java8</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/599bec32/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 9682485..2d84c86 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -23,16 +23,19 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.Error;
 import org.apache.james.mdn.fields.ExtensionField;
+import org.apache.james.mdn.fields.Field;
 import org.apache.james.mdn.fields.FinalRecipient;
 import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
 import org.apache.james.mdn.fields.Text;
+import org.apache.james.util.OptionalUtils;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
@@ -217,34 +220,28 @@ public class MDNReport {
     }
 
     public String formattedValue() {
-        return reportingUserAgentField.map(value -> value.formattedValue() + LINE_END).orElse("")
-            + gatewayField.map(value -> value.formattedValue() + LINE_END).orElse("")
-            + originalRecipientField.map(value -> value.formattedValue() + LINE_END).orElse("")
-            + finalRecipientField.formattedValue() + LINE_END
-            + originalMessageIdField.map(value -> value.formattedValue() + LINE_END).orElse("")
-            + dispositionField.formattedValue() + LINE_END
-            + formatErrors()
-            + formattedExtensionValue();
-    }
-
-    private String formatErrors() {
-        if (errorFields.isEmpty()) {
-            return "";
-        }
-        return errorFields.stream()
-            .map(Error::formattedValue)
+        Stream<Optional<? extends Field>> definedFields =
+            Stream.of(
+                reportingUserAgentField,
+                gatewayField,
+                originalRecipientField,
+                Optional.of(finalRecipientField),
+                originalMessageIdField,
+                Optional.of(dispositionField));
+        Stream<Optional<? extends Field>> errors =
+            errorFields.stream().map(Optional::of);
+        Stream<Optional<? extends Field>> extentions =
+            extensionFields.stream().map(Optional::of);
+
+        return Stream.concat(
+            definedFields,
+            Stream.concat(errors,
+                extentions))
+            .flatMap(OptionalUtils::toStream)
+            .map(Field::formattedValue)
             .collect(Collectors.joining(LINE_END)) + LINE_END;
     }
 
-    private String formattedExtensionValue() {
-        if (extensionFields.isEmpty()) {
-            return "";
-        }
-        return extensionFields.stream()
-            .map(ExtensionField::formattedValue)
-            .collect(Collectors.joining(EXTENSION_DELIMITER)) + LINE_END;
-    }
-
     @Override
     public final boolean equals(Object o) {
         if (o instanceof MDNReport) {


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[23/27] james-project git commit: JAMES-2132 Introduce a MDN top level object

Posted by bt...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index 0d4cbba..63d2f84 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -25,11 +25,11 @@ import java.util.Collection;
 
 import javax.mail.Address;
 import javax.mail.MessagingException;
+import javax.mail.Multipart;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
 
-import org.apache.james.mdn.MDNFactory;
+import org.apache.james.mdn.MDN;
 import org.apache.james.mdn.MDNReport;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.fields.Disposition;
@@ -112,25 +112,28 @@ public class RejectAction implements MailAction {
         String final_recipient = soleRecipient.asString();
         String original_message_id = aMail.getMessage().getMessageID();
 
-        MimeMultipart multiPart = MDNFactory.create(
-            humanText.toString(),
-            MDNReport.builder()
-                .reportingUserAgentField(reporting_UA_name, reporting_UA_product)
-                .finalRecipientField(final_recipient)
-                .originalRecipientField(original_recipient)
-                .originalMessageIdField(original_message_id)
-                .dispositionField(Disposition.builder()
-                    .actionMode(DispositionActionMode.Automatic)
-                    .sendingMode(DispositionSendingMode.Automatic)
-                    .type(DispositionType.Deleted)
-                    .addModifier(DispositionModifier.Error)
+        Multipart multipart = MDN.builder()
+            .humanReadableText(humanText.toString())
+            .report(
+                MDNReport.builder()
+                    .reportingUserAgentField(reporting_UA_name, reporting_UA_product)
+                    .finalRecipientField(final_recipient)
+                    .originalRecipientField(original_recipient)
+                    .originalMessageIdField(original_message_id)
+                    .dispositionField(Disposition.builder()
+                        .actionMode(DispositionActionMode.Automatic)
+                        .sendingMode(DispositionSendingMode.Automatic)
+                        .type(DispositionType.Deleted)
+                        .addModifier(DispositionModifier.Error)
+                        .build())
                     .build())
-                .build());
+            .build()
+            .asMultipart();
 
         // Send the message
         MimeMessage reply = (MimeMessage) aMail.getMessage().reply(false);
         reply.setFrom(soleRecipient.toInternetAddress());
-        reply.setContent(multiPart);
+        reply.setContent(multipart);
         reply.saveChanges();
         Address[] recipientAddresses = reply.getAllRecipients();
         if (null != recipientAddresses)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[16/27] james-project git commit: JAMES-2132 Fix typo s/Recepient/Recipient/g

Posted by bt...@apache.org.
JAMES-2132 Fix typo s/Recepient/Recipient/g


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ea2b452a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ea2b452a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ea2b452a

Branch: refs/heads/master
Commit: ea2b452a54154f99565ea004af2cd3f665841b6c
Parents: beae701
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 20:28:23 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 .../apache/james/mdn/fields/FinalRecipient.java |  2 +-
 .../james/mdn/fields/OriginalRecipient.java     |  3 +-
 .../org/apache/james/mdn/MDNFactoryTest.java    | 40 ++++++++++----------
 3 files changed, 23 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ea2b452a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
index fa4cd42..d8ce484 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -24,7 +24,7 @@ import org.apache.james.mdn.Constants;
 import com.google.common.base.Preconditions;
 
 public class FinalRecipient implements Field {
-    public static final String FIELD_NAME = "Final-Recepient";
+    public static final String FIELD_NAME = "Final-Recipient";
 
     private final Text finalRecipient;
     private final String addressType;

http://git-wip-us.apache.org/repos/asf/james-project/blob/ea2b452a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
index f8e084d..9c53e7e 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -25,6 +25,7 @@ import com.google.common.base.Preconditions;
 
 public class OriginalRecipient implements Field{
     private static final String UNKNOWN = "unknown";
+    private static final String FIELD_NAME = "Original-Recipient";
 
     public static OriginalRecipient ofUnknown(Text address) {
         return new OriginalRecipient(UNKNOWN, address);
@@ -54,6 +55,6 @@ public class OriginalRecipient implements Field{
 
     @Override
     public String formattedValue() {
-        return "Original-Recipient: " + addressType + "; " + originalRecipient.formatted();
+        return FIELD_NAME + ": " + addressType + "; " + originalRecipient.formatted();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ea2b452a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index d34e13a..24b81f1 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -68,7 +68,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
@@ -97,7 +97,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;processed/error,failed\r\n");
     }
@@ -126,7 +126,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;dispatched/error,failed\r\n");
     }
@@ -155,7 +155,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;displayed/error,failed\r\n");
     }
@@ -184,7 +184,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;deleted/error,failed\r\n");
     }
@@ -213,7 +213,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;deleted/error,expired,failed,mailbox-terminated,superseded,warning\r\n");
     }
@@ -241,7 +241,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;deleted/error\r\n");
     }
@@ -269,7 +269,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;deleted/new\r\n");
     }
@@ -296,7 +296,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-manually;deleted\r\n");
     }
@@ -325,7 +325,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; \r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
     }
@@ -352,7 +352,7 @@ public class MDNFactoryTest {
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
     }
@@ -380,7 +380,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
     }
 
@@ -423,7 +423,7 @@ public class MDNFactoryTest {
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "MDN-Gateway: dns;host.com\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
@@ -454,7 +454,7 @@ public class MDNFactoryTest {
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "MDN-Gateway: postal;5 rue Charles mercier\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
@@ -483,7 +483,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: roomNumber; 385\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
@@ -518,7 +518,7 @@ public class MDNFactoryTest {
                 "Original-Recipient: postal; 3 rue Mercier\r\n" +
                 " 36555 Saint Coincoin\r\n" +
                 " France\r\n" +
-                "Final-Recepient: postal; 5 rue Mercier\r\n" +
+                "Final-Recipient: postal; 5 rue Mercier\r\n" +
                 " 36555 Saint Coincoin\r\n" +
                 " France\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
@@ -549,7 +549,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: unknown; #$%*\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
@@ -578,7 +578,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: roomNumber; 781\r\n" +
+                "Final-Recipient: roomNumber; 781\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
@@ -630,7 +630,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
                 "Error: An error message\r\n");
@@ -661,7 +661,7 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
                 "Error: An error message\r\n" +


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[03/27] james-project git commit: JAMES-2132 moving MDN to a separated project

Posted by bt...@apache.org.
JAMES-2132 moving MDN to a separated project


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/976a3037
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/976a3037
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/976a3037

Branch: refs/heads/master
Commit: 976a303759c6819db674a21f02e24ea352c6f6a4
Parents: 6553f4b
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 10:46:48 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 mdn/pom.xml                                     |  44 +++++
 .../apache/james/mdn/ActionModeAutomatic.java   |  42 +++++
 .../org/apache/james/mdn/ActionModeManual.java  |  47 +++++
 .../java/org/apache/james/mdn/Disposition.java  | 176 +++++++++++++++++++
 .../apache/james/mdn/DispositionActionMode.java |  29 +++
 .../apache/james/mdn/DispositionModifier.java   |  29 +++
 .../james/mdn/DispositionSendingMode.java       |  29 +++
 .../org/apache/james/mdn/DispositionType.java   |  29 +++
 .../java/org/apache/james/mdn/MDNFactory.java   | 115 ++++++++++++
 .../org/apache/james/mdn/ModifierError.java     |  44 +++++
 .../org/apache/james/mdn/ModifierExpired.java   |  45 +++++
 .../org/apache/james/mdn/ModifierFailed.java    |  45 +++++
 .../james/mdn/ModifierMailboxTerminated.java    |  45 +++++
 .../apache/james/mdn/ModifierSuperseded.java    |  45 +++++
 .../org/apache/james/mdn/ModifierWarning.java   |  45 +++++
 .../apache/james/mdn/SendingModeAutomatic.java  |  45 +++++
 .../org/apache/james/mdn/SendingModeManual.java |  45 +++++
 .../java/org/apache/james/mdn/TypeDeleted.java  |  45 +++++
 .../java/org/apache/james/mdn/TypeDenied.java   |  44 +++++
 .../org/apache/james/mdn/TypeDispatched.java    |  43 +++++
 .../org/apache/james/mdn/TypeDisplayed.java     |  44 +++++
 .../java/org/apache/james/mdn/TypeFailed.java   |  44 +++++
 .../org/apache/james/mdn/TypeProcessed.java     |  44 +++++
 pom.xml                                         |   6 +
 server/mailet/mailets/pom.xml                   |   4 +
 .../transport/mailets/jsieve/RejectAction.java  |  15 +-
 .../mailets/jsieve/mdn/ActionModeAutomatic.java |  42 -----
 .../mailets/jsieve/mdn/ActionModeManual.java    |  47 -----
 .../mailets/jsieve/mdn/Disposition.java         | 176 -------------------
 .../jsieve/mdn/DispositionActionMode.java       |  29 ---
 .../mailets/jsieve/mdn/DispositionModifier.java |  29 ---
 .../jsieve/mdn/DispositionSendingMode.java      |  29 ---
 .../mailets/jsieve/mdn/DispositionType.java     |  29 ---
 .../mailets/jsieve/mdn/MDNFactory.java          | 115 ------------
 .../mailets/jsieve/mdn/ModifierError.java       |  44 -----
 .../mailets/jsieve/mdn/ModifierExpired.java     |  45 -----
 .../mailets/jsieve/mdn/ModifierFailed.java      |  45 -----
 .../jsieve/mdn/ModifierMailboxTerminated.java   |  45 -----
 .../mailets/jsieve/mdn/ModifierSuperseded.java  |  45 -----
 .../mailets/jsieve/mdn/ModifierWarning.java     |  45 -----
 .../jsieve/mdn/SendingModeAutomatic.java        |  45 -----
 .../mailets/jsieve/mdn/SendingModeManual.java   |  45 -----
 .../mailets/jsieve/mdn/TypeDeleted.java         |  45 -----
 .../mailets/jsieve/mdn/TypeDenied.java          |  44 -----
 .../mailets/jsieve/mdn/TypeDispatched.java      |  43 -----
 .../mailets/jsieve/mdn/TypeDisplayed.java       |  44 -----
 .../mailets/jsieve/mdn/TypeFailed.java          |  44 -----
 .../mailets/jsieve/mdn/TypeProcessed.java       |  44 -----
 48 files changed, 1181 insertions(+), 1126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/pom.xml
----------------------------------------------------------------------
diff --git a/mdn/pom.xml b/mdn/pom.xml
new file mode 100644
index 0000000..39f58a9
--- /dev/null
+++ b/mdn/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>james-project</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>james-mdn</artifactId>
+
+
+    <name>Apache James :: MDN</name>
+    <description>Provides parser and representations for MDN messages</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mailet-base</artifactId>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java
new file mode 100644
index 0000000..31bdf91
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ActionModeAutomatic.java
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ActionModeAutomatic</code>
+ */
+public class ActionModeAutomatic implements DispositionActionMode {
+
+    /**
+     * Default Constructor
+     */
+    public ActionModeAutomatic() {
+        super();
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "automatic-action";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java b/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java
new file mode 100644
index 0000000..ab71030
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ActionModeManual.java
@@ -0,0 +1,47 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ActionModeManual</code>
+ */
+public class ActionModeManual
+        implements
+            DispositionActionMode
+{
+
+    /**
+     * Default Constructor
+     */
+    public ActionModeManual()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "manual-action";
+    }         
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
new file mode 100644
index 0000000..b74ef4d
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
@@ -0,0 +1,176 @@
+/****************************************************************
+ * 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.mdn;
+
+/**
+ * Class <code>Disposition</code> encapsulating
+ * disposition information as defined by RFC 2298.
+ */
+public class Disposition
+{
+    private DispositionActionMode fieldActionMode;
+    private DispositionSendingMode fieldSendingMode;
+    private DispositionType fieldDispositionType;
+    private DispositionModifier[] fieldDispositionModifiers;
+
+    /**
+     * Default Construcor
+     */
+    private Disposition()
+    {
+        super();
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param actionMode
+     * @param sendingMode
+     * @param type
+     */
+    public Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type)
+    {
+        this();
+        setActionMode(actionMode);
+        setSendingMode(sendingMode);
+        setDispositionType(type);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param actionMode
+     * @param sendingMode
+     * @param type
+     * @param modifiers
+     */
+    public Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type,
+            DispositionModifier[] modifiers)
+    {
+        this(actionMode, sendingMode, type);
+        setDispositionModifiers(modifiers);
+    }
+
+    /**
+     * Answer the Disposition Mode.
+     * 
+     * @return Returns the dispostionMode.
+     */
+    protected DispositionActionMode getActionMode()
+    {
+        return fieldActionMode;
+    }
+
+    /**
+     * Set the Disposition Mode.
+     * 
+     * @param dispostionMode The dispostionMode to set.
+     */
+    protected void setActionMode(DispositionActionMode dispostionMode)
+    {
+        fieldActionMode = dispostionMode;
+    }
+
+    /**
+     * Answer the Disposition Modifiers.
+     * 
+     * @return Returns the dispostionModifiers.
+     */
+    protected DispositionModifier[] getDispositionModifiers()
+    {
+        return fieldDispositionModifiers;
+    }
+
+    /**
+     * Set the Disposition Modifiers.
+     * 
+     * @param dispostionModifiers The dispostionModifiers to set.
+     */
+    protected void setDispositionModifiers(DispositionModifier[] dispostionModifiers)
+    {
+        fieldDispositionModifiers = dispostionModifiers;
+    }
+
+    /**
+     * Answer the Disposition Type.
+     * 
+     * @return Returns the dispostionType.
+     */
+    protected DispositionType getDispositionType()
+    {
+        return fieldDispositionType;
+    }
+
+    /**
+     * Set the Disposition Type.
+     * 
+     * @param dispostionType The dispostionType to set.
+     */
+    protected void setDispositionType(DispositionType dispostionType)
+    {
+        fieldDispositionType = dispostionType;
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder(64);
+        builder.append("Disposition: ");
+        builder.append(getActionMode() == null ? "" : getActionMode().toString());
+        builder.append('/');
+        builder.append(getSendingMode() == null ? "" : getSendingMode().toString());
+        builder.append(';');
+        builder.append(getDispositionType() == null ? "" : getDispositionType().toString());
+        if (null != getDispositionModifiers()
+                && getDispositionModifiers().length > 0)
+        {
+            builder.append('/');
+            for (int i = 0; i < getDispositionModifiers().length; i++)
+            {
+                if (i > 0)
+                    builder.append(',');
+                builder.append(getDispositionModifiers()[i]);
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Answer the Sending Mode.
+     * 
+     * @return Returns the sendingMode.
+     */
+    protected DispositionSendingMode getSendingMode()
+    {
+        return fieldSendingMode;
+    }
+
+    /**
+     * Set the Sending Mode.
+     * 
+     * @param sendingMode The sendingMode to set.
+     */
+    protected void setSendingMode(DispositionSendingMode sendingMode)
+    {
+        fieldSendingMode = sendingMode;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java b/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java
new file mode 100644
index 0000000..969f31f
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/DispositionActionMode.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn;
+
+/**
+ * Interface <code>DispositionActionMode</code> marks a type encapsulating
+ * disposition action mode information as defined by RFC 2298.
+ */
+public interface DispositionActionMode
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java
new file mode 100644
index 0000000..041b525
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/DispositionModifier.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn;
+
+/**
+ * Interface <code>DispositionModifier</code> marks a type encapsulating
+ * disposition modifier information as defined by RFC 2298.
+ */
+public interface DispositionModifier
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java b/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java
new file mode 100644
index 0000000..2f3e815
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/DispositionSendingMode.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn;
+
+/**
+ * Interface <code>DispositionSendingMode</code> marks a type encapsulating
+ * disposition sending mode information as defined by RFC 2298.
+ */
+public interface DispositionSendingMode
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/DispositionType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/DispositionType.java b/mdn/src/main/java/org/apache/james/mdn/DispositionType.java
new file mode 100644
index 0000000..af2dacd
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/DispositionType.java
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.mdn;
+
+/**
+ * Interface <code>DispositionType</code> marks a type encapsulating
+ * disposition type information as defined by RFC 2298.
+ */
+public interface DispositionType
+{
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
new file mode 100644
index 0000000..bc3312f
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
@@ -0,0 +1,115 @@
+/****************************************************************
+ * 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.mdn;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeBodyPart;
+
+import org.apache.mailet.base.mail.MimeMultipartReport;
+
+/**
+ * Class <code>MDNFactory</code> creates MimeMultipartReports containing
+ * Message Delivery Notifications as specified by RFC 2298.
+ */
+public class MDNFactory
+{
+
+    /**
+     * Default Constructor
+     */
+    private MDNFactory()
+    {
+        super();
+    }
+    
+    /**
+     * Answers a MimeMultipartReport containing a
+     * Message Delivery Notification as specified by RFC 2298.
+     * 
+     * @param humanText
+     * @param reporting_UA_name
+     * @param reporting_UA_product
+     * @param original_recipient
+     * @param final_recipient
+     * @param original_message_id
+     * @param disposition
+     * @return MimeMultipartReport
+     * @throws MessagingException
+     */
+    static public MimeMultipartReport create(String humanText,
+            String reporting_UA_name,
+            String reporting_UA_product,
+            String original_recipient,
+            String final_recipient,
+            String original_message_id,
+            Disposition disposition) throws MessagingException
+    {
+        // Create the message parts. According to RFC 2298, there are two
+        // compulsory parts and one optional part...
+        MimeMultipartReport multiPart = new MimeMultipartReport();
+        multiPart.setReportType("disposition-notification");
+        
+        // Part 1: The 'human-readable' part
+        MimeBodyPart humanPart = new MimeBodyPart();
+        humanPart.setText(humanText);
+        multiPart.addBodyPart(humanPart);
+
+        // Part 2: MDN Report Part
+        // 1) reporting-ua-field
+        StringBuilder mdnReport = new StringBuilder(128);
+        mdnReport.append("Reporting-UA: ");
+        mdnReport.append((reporting_UA_name == null ? "" : reporting_UA_name));
+        mdnReport.append("; ");
+        mdnReport.append((reporting_UA_product == null ? "" : reporting_UA_product));
+        mdnReport.append("\r\n");
+        // 2) original-recipient-field
+        if (null != original_recipient)
+        {
+            mdnReport.append("Original-Recipient: ");
+            mdnReport.append("rfc822; ");
+            mdnReport.append(original_recipient);
+            mdnReport.append("\r\n");
+        }
+        // 3) final-recipient-field
+        mdnReport.append("Final-Recepient: ");
+        mdnReport.append("rfc822; ");
+        mdnReport.append((final_recipient == null ? "" : final_recipient));
+        mdnReport.append("\r\n");
+        // 4) original-message-id-field
+        mdnReport.append("Original-Message-ID: ");
+        mdnReport.append((original_message_id == null ? "" : original_message_id));
+        mdnReport.append("\r\n");
+        // 5) disposition-field
+        mdnReport.append(disposition.toString());
+        mdnReport.append("\r\n");
+        MimeBodyPart mdnPart = new MimeBodyPart();
+        mdnPart.setContent(mdnReport.toString(), "message/disposition-notification");
+        multiPart.addBodyPart(mdnPart);
+
+        // Part 3: The optional third part, the original message is omitted.
+        // We don't want to propogate over-sized, virus infected or
+        // other undesirable mail!
+        // There is the option of adding a Text/RFC822-Headers part, which
+        // includes only the RFC 822 headers of the failed message. This is
+        // described in RFC 1892. It would be a useful addition!        
+        return multiPart;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ModifierError.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierError.java b/mdn/src/main/java/org/apache/james/mdn/ModifierError.java
new file mode 100644
index 0000000..b1692f8
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ModifierError.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ModifierError</code>
+ */
+public class ModifierError implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierError()
+    {
+        super();
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "error";
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java b/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java
new file mode 100644
index 0000000..9d7c678
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ModifierExpired.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ModifierExpired</code>
+ */    
+public class ModifierExpired implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierExpired()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "expired";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java b/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java
new file mode 100644
index 0000000..b2a7fe0
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ModifierFailed.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ModifierFailed</code>
+ */    
+public class ModifierFailed implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierFailed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "failed";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java b/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java
new file mode 100644
index 0000000..0c0d10d
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ModifierMailboxTerminated.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ModifierMailboxTerminated</code>
+ */    
+public class ModifierMailboxTerminated implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierMailboxTerminated()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "mailbox-terminated";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java b/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java
new file mode 100644
index 0000000..dfeabfb
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ModifierSuperseded.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ModifierSuperseded</code>
+ */    
+public class ModifierSuperseded implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierSuperseded()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "superseded";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java b/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java
new file mode 100644
index 0000000..95cbe4f
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/ModifierWarning.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>ModifierWarning</code>
+ */    
+public class ModifierWarning implements DispositionModifier
+{
+
+    /**
+     * Default Constructor
+     */
+    public ModifierWarning()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "warning";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java
new file mode 100644
index 0000000..c716628
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/SendingModeAutomatic.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>SendingModeAutomatic</code>
+ */
+public class SendingModeAutomatic implements DispositionSendingMode
+{
+
+    /**
+     * Default Constructor
+     */
+    public SendingModeAutomatic()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "MDN-sent-automatically";
+    }        
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java b/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java
new file mode 100644
index 0000000..a86a71e
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/SendingModeManual.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>SendingModeManual</code>
+ */
+public class SendingModeManual implements DispositionSendingMode
+{
+
+    /**
+     * Default Constructor
+     */
+    public SendingModeManual()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "MDN-sent-manually";
+    }         
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java b/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java
new file mode 100644
index 0000000..4c6d30a
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/TypeDeleted.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>TypeDeleted</code>
+ */
+public class TypeDeleted implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeDeleted()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "deleted";
+    }         
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java b/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java
new file mode 100644
index 0000000..eddab50
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/TypeDenied.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>TypeDenied</code>
+ */    
+public class TypeDenied implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeDenied()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "denied";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java b/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java
new file mode 100644
index 0000000..a814c24
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/TypeDispatched.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>TypeDispatched</code>
+ */
+public class TypeDispatched implements DispositionType
+{
+    /**
+     * Default Constructor
+     */
+    public TypeDispatched()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "dispatched";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java b/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java
new file mode 100644
index 0000000..d82589e
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/TypeDisplayed.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>TypeDisplayed</code>
+ */
+public class TypeDisplayed implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeDisplayed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "displayed";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java b/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java
new file mode 100644
index 0000000..8d6ba3d
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/TypeFailed.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>TypeFailed</code>
+ */    
+public class TypeFailed implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeFailed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "failed";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java b/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java
new file mode 100644
index 0000000..b377c86
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/TypeProcessed.java
@@ -0,0 +1,44 @@
+/****************************************************************
+ * 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.mdn;
+
+
+/**
+ * Class <code>TypeProcessed</code>
+ */    
+public class TypeProcessed implements DispositionType
+{
+
+    /**
+     * Default Constructor
+     */
+    public TypeProcessed()
+    {
+        super();
+    }
+    
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "processed";
+    }         
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9e229bf..20ddced 100644
--- a/pom.xml
+++ b/pom.xml
@@ -527,6 +527,7 @@
         <module>backends-common</module>
         <module>mailbox</module>
         <module>mailet</module>
+        <module>mdn</module>
         <module>metrics</module>
         <module>mpt</module>
         <module>protocols</module>
@@ -944,6 +945,11 @@
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
+                <artifactId>james-mdn</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
                 <artifactId>james-server-cassandra-guice</artifactId>
                 <version>${project.version}</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml
index bf5dda9..4f3164f 100644
--- a/server/mailet/mailets/pom.xml
+++ b/server/mailet/mailets/pom.xml
@@ -96,6 +96,10 @@
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
+            <artifactId>james-mdn</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
             <artifactId>james-server-core</artifactId>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index 2cd5dc0..460f9f7 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -29,13 +29,14 @@ import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 
-import org.apache.james.transport.mailets.jsieve.mdn.ActionModeAutomatic;
-import org.apache.james.transport.mailets.jsieve.mdn.Disposition;
-import org.apache.james.transport.mailets.jsieve.mdn.DispositionModifier;
-import org.apache.james.transport.mailets.jsieve.mdn.MDNFactory;
-import org.apache.james.transport.mailets.jsieve.mdn.ModifierError;
-import org.apache.james.transport.mailets.jsieve.mdn.SendingModeAutomatic;
-import org.apache.james.transport.mailets.jsieve.mdn.TypeDeleted;
+
+import org.apache.james.mdn.ActionModeAutomatic;
+import org.apache.james.mdn.Disposition;
+import org.apache.james.mdn.DispositionModifier;
+import org.apache.james.mdn.MDNFactory;
+import org.apache.james.mdn.ModifierError;
+import org.apache.james.mdn.SendingModeAutomatic;
+import org.apache.james.mdn.TypeDeleted;
 import org.apache.jsieve.mail.Action;
 import org.apache.jsieve.mail.ActionReject;
 import org.apache.mailet.Mail;

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeAutomatic.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeAutomatic.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeAutomatic.java
deleted file mode 100644
index 30f6df7..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeAutomatic.java
+++ /dev/null
@@ -1,42 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ActionModeAutomatic</code>
- */
-public class ActionModeAutomatic implements DispositionActionMode {
-
-    /**
-     * Default Constructor
-     */
-    public ActionModeAutomatic() {
-        super();
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return "automatic-action";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeManual.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeManual.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeManual.java
deleted file mode 100644
index 6d553e1..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ActionModeManual.java
+++ /dev/null
@@ -1,47 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ActionModeManual</code>
- */
-public class ActionModeManual
-        implements
-            DispositionActionMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public ActionModeManual()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "manual-action";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/Disposition.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/Disposition.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/Disposition.java
deleted file mode 100644
index e047d66..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/Disposition.java
+++ /dev/null
@@ -1,176 +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.jsieve.mdn;
-
-/**
- * Class <code>Disposition</code> encapsulating
- * disposition information as defined by RFC 2298.
- */
-public class Disposition
-{
-    private DispositionActionMode fieldActionMode;
-    private DispositionSendingMode fieldSendingMode;
-    private DispositionType fieldDispositionType;
-    private DispositionModifier[] fieldDispositionModifiers;
-
-    /**
-     * Default Construcor
-     */
-    private Disposition()
-    {
-        super();
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param actionMode
-     * @param sendingMode
-     * @param type
-     */
-    public Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type)
-    {
-        this();
-        setActionMode(actionMode);
-        setSendingMode(sendingMode);
-        setDispositionType(type);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param actionMode
-     * @param sendingMode
-     * @param type
-     * @param modifiers
-     */
-    public Disposition(DispositionActionMode actionMode, DispositionSendingMode sendingMode, DispositionType type,
-            DispositionModifier[] modifiers)
-    {
-        this(actionMode, sendingMode, type);
-        setDispositionModifiers(modifiers);
-    }
-
-    /**
-     * Answer the Disposition Mode.
-     * 
-     * @return Returns the dispostionMode.
-     */
-    protected DispositionActionMode getActionMode()
-    {
-        return fieldActionMode;
-    }
-
-    /**
-     * Set the Disposition Mode.
-     * 
-     * @param dispostionMode The dispostionMode to set.
-     */
-    protected void setActionMode(DispositionActionMode dispostionMode)
-    {
-        fieldActionMode = dispostionMode;
-    }
-
-    /**
-     * Answer the Disposition Modifiers.
-     * 
-     * @return Returns the dispostionModifiers.
-     */
-    protected DispositionModifier[] getDispositionModifiers()
-    {
-        return fieldDispositionModifiers;
-    }
-
-    /**
-     * Set the Disposition Modifiers.
-     * 
-     * @param dispostionModifiers The dispostionModifiers to set.
-     */
-    protected void setDispositionModifiers(DispositionModifier[] dispostionModifiers)
-    {
-        fieldDispositionModifiers = dispostionModifiers;
-    }
-
-    /**
-     * Answer the Disposition Type.
-     * 
-     * @return Returns the dispostionType.
-     */
-    protected DispositionType getDispositionType()
-    {
-        return fieldDispositionType;
-    }
-
-    /**
-     * Set the Disposition Type.
-     * 
-     * @param dispostionType The dispostionType to set.
-     */
-    protected void setDispositionType(DispositionType dispostionType)
-    {
-        fieldDispositionType = dispostionType;
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        StringBuilder builder = new StringBuilder(64);
-        builder.append("Disposition: ");
-        builder.append(getActionMode() == null ? "" : getActionMode().toString());
-        builder.append('/');
-        builder.append(getSendingMode() == null ? "" : getSendingMode().toString());
-        builder.append(';');
-        builder.append(getDispositionType() == null ? "" : getDispositionType().toString());
-        if (null != getDispositionModifiers()
-                && getDispositionModifiers().length > 0)
-        {
-            builder.append('/');
-            for (int i = 0; i < getDispositionModifiers().length; i++)
-            {
-                if (i > 0)
-                    builder.append(',');
-                builder.append(getDispositionModifiers()[i]);
-            }
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Answer the Sending Mode.
-     * 
-     * @return Returns the sendingMode.
-     */
-    protected DispositionSendingMode getSendingMode()
-    {
-        return fieldSendingMode;
-    }
-
-    /**
-     * Set the Sending Mode.
-     * 
-     * @param sendingMode The sendingMode to set.
-     */
-    protected void setSendingMode(DispositionSendingMode sendingMode)
-    {
-        fieldSendingMode = sendingMode;
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionActionMode.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionActionMode.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionActionMode.java
deleted file mode 100644
index 422b898..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionActionMode.java
+++ /dev/null
@@ -1,29 +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.jsieve.mdn;
-
-/**
- * Interface <code>DispositionActionMode</code> marks a type encapsulating
- * disposition action mode information as defined by RFC 2298.
- */
-public interface DispositionActionMode
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionModifier.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionModifier.java
deleted file mode 100644
index 2a8b2a3..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionModifier.java
+++ /dev/null
@@ -1,29 +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.jsieve.mdn;
-
-/**
- * Interface <code>DispositionModifier</code> marks a type encapsulating
- * disposition modifier information as defined by RFC 2298.
- */
-public interface DispositionModifier
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionSendingMode.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionSendingMode.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionSendingMode.java
deleted file mode 100644
index 3b4055e..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionSendingMode.java
+++ /dev/null
@@ -1,29 +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.jsieve.mdn;
-
-/**
- * Interface <code>DispositionSendingMode</code> marks a type encapsulating
- * disposition sending mode information as defined by RFC 2298.
- */
-public interface DispositionSendingMode
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionType.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionType.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionType.java
deleted file mode 100644
index 004d8d1..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/DispositionType.java
+++ /dev/null
@@ -1,29 +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.jsieve.mdn;
-
-/**
- * Interface <code>DispositionType</code> marks a type encapsulating
- * disposition type information as defined by RFC 2298.
- */
-public interface DispositionType
-{
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/MDNFactory.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/MDNFactory.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/MDNFactory.java
deleted file mode 100644
index 0711909..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/MDNFactory.java
+++ /dev/null
@@ -1,115 +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.jsieve.mdn;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeBodyPart;
-
-import org.apache.mailet.base.mail.MimeMultipartReport;
-
-/**
- * Class <code>MDNFactory</code> creates MimeMultipartReports containing
- * Message Delivery Notifications as specified by RFC 2298.
- */
-public class MDNFactory
-{
-
-    /**
-     * Default Constructor
-     */
-    private MDNFactory()
-    {
-        super();
-    }
-    
-    /**
-     * Answers a MimeMultipartReport containing a
-     * Message Delivery Notification as specified by RFC 2298.
-     * 
-     * @param humanText
-     * @param reporting_UA_name
-     * @param reporting_UA_product
-     * @param original_recipient
-     * @param final_recipient
-     * @param original_message_id
-     * @param disposition
-     * @return MimeMultipartReport
-     * @throws MessagingException
-     */
-    static public MimeMultipartReport create(String humanText,
-            String reporting_UA_name,
-            String reporting_UA_product,
-            String original_recipient,
-            String final_recipient,
-            String original_message_id,
-            Disposition disposition) throws MessagingException
-    {
-        // Create the message parts. According to RFC 2298, there are two
-        // compulsory parts and one optional part...
-        MimeMultipartReport multiPart = new MimeMultipartReport();
-        multiPart.setReportType("disposition-notification");
-        
-        // Part 1: The 'human-readable' part
-        MimeBodyPart humanPart = new MimeBodyPart();
-        humanPart.setText(humanText);
-        multiPart.addBodyPart(humanPart);
-
-        // Part 2: MDN Report Part
-        // 1) reporting-ua-field
-        StringBuilder mdnReport = new StringBuilder(128);
-        mdnReport.append("Reporting-UA: ");
-        mdnReport.append((reporting_UA_name == null ? "" : reporting_UA_name));
-        mdnReport.append("; ");
-        mdnReport.append((reporting_UA_product == null ? "" : reporting_UA_product));
-        mdnReport.append("\r\n");
-        // 2) original-recipient-field
-        if (null != original_recipient)
-        {
-            mdnReport.append("Original-Recipient: ");
-            mdnReport.append("rfc822; ");
-            mdnReport.append(original_recipient);
-            mdnReport.append("\r\n");
-        }
-        // 3) final-recipient-field
-        mdnReport.append("Final-Recepient: ");
-        mdnReport.append("rfc822; ");
-        mdnReport.append((final_recipient == null ? "" : final_recipient));
-        mdnReport.append("\r\n");
-        // 4) original-message-id-field
-        mdnReport.append("Original-Message-ID: ");
-        mdnReport.append((original_message_id == null ? "" : original_message_id));
-        mdnReport.append("\r\n");
-        // 5) disposition-field
-        mdnReport.append(disposition.toString());
-        mdnReport.append("\r\n");
-        MimeBodyPart mdnPart = new MimeBodyPart();
-        mdnPart.setContent(mdnReport.toString(), "message/disposition-notification");
-        multiPart.addBodyPart(mdnPart);
-
-        // Part 3: The optional third part, the original message is omitted.
-        // We don't want to propogate over-sized, virus infected or
-        // other undesirable mail!
-        // There is the option of adding a Text/RFC822-Headers part, which
-        // includes only the RFC 822 headers of the failed message. This is
-        // described in RFC 1892. It would be a useful addition!        
-        return multiPart;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierError.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierError.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierError.java
deleted file mode 100644
index ae3c8d3..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierError.java
+++ /dev/null
@@ -1,44 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ModifierError</code>
- */
-public class ModifierError implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierError()
-    {
-        super();
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "error";
-    }
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[26/27] james-project git commit: JAMES-2132 Ease calling MDNReport builder

Posted by bt...@apache.org.
JAMES-2132 Ease calling MDNReport builder


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/7c8ecec6
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/7c8ecec6
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/7c8ecec6

Branch: refs/heads/master
Commit: 7c8ecec6dba5c93fa7afe8d2b3cf02864bf8a72d
Parents: 4020b75
Author: benwa <bt...@linagora.com>
Authored: Wed Aug 30 14:18:44 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:16:14 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 34 ++++++++++++++++++++
 .../james/mdn/fields/ReportingUserAgent.java    |  4 +--
 .../transport/mailets/jsieve/RejectAction.java  | 17 +++-------
 3 files changed, 39 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/7c8ecec6/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 06b66b2..9682485 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -32,6 +32,7 @@ import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
+import org.apache.james.mdn.fields.Text;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
@@ -52,11 +53,23 @@ public class MDNReport {
         private ImmutableList.Builder<Error> errorField = ImmutableList.builder();
         private ImmutableList.Builder<ExtensionField> extensionFields = ImmutableList.builder();
 
+        public Builder reportingUserAgentField(String userAgentName, String userAgentProduct) {
+            this.reportingUserAgentField = Optional.of(new ReportingUserAgent(userAgentName, Optional.ofNullable(userAgentProduct)));
+            return this;
+        }
+
         public Builder reportingUserAgentField(ReportingUserAgent reportingUserAgentField) {
             this.reportingUserAgentField = Optional.of(reportingUserAgentField);
             return this;
         }
 
+        public Builder originalRecipientField(String originalRecipient) {
+            this.originalRecipientField = Optional.ofNullable(originalRecipient)
+                .map(Text::fromRawText)
+                .map(OriginalRecipient::new);
+            return this;
+        }
+
         public Builder originalRecipientField(OriginalRecipient originalRecipientField) {
             this.originalRecipientField = Optional.of(originalRecipientField);
             return this;
@@ -67,6 +80,11 @@ public class MDNReport {
             return this;
         }
 
+        public Builder gatewayField(String gatewayDns) {
+            this.gatewayField = Optional.of(new Gateway(Text.fromRawText(gatewayDns)));
+            return this;
+        }
+
         public Builder gatewayField(Optional<Gateway> gatewayField) {
             this.gatewayField = gatewayField;
             return this;
@@ -77,6 +95,12 @@ public class MDNReport {
             return this;
         }
 
+        public Builder addErrorField(String message) {
+            this.errorField.add(new Error(Text.fromRawText(message)));
+            return this;
+        }
+
+
         public Builder addErrorField(Error errorField) {
             this.errorField.add(errorField);
             return this;
@@ -87,11 +111,21 @@ public class MDNReport {
             return this;
         }
 
+        public Builder finalRecipientField(String finalRecipientField) {
+            this.finalRecipientField = Optional.of(new FinalRecipient(Text.fromRawText(finalRecipientField)));
+            return this;
+        }
+
         public Builder finalRecipientField(FinalRecipient finalRecipientField) {
             this.finalRecipientField = Optional.of(finalRecipientField);
             return this;
         }
 
+        public Builder originalMessageIdField(String originalMessageIdField) {
+            this.originalMessageIdField = Optional.of(new OriginalMessageId(originalMessageIdField));
+            return this;
+        }
+
         public Builder originalMessageIdField(OriginalMessageId originalMessageIdField) {
             this.originalMessageIdField = Optional.of(originalMessageIdField);
             return this;

http://git-wip-us.apache.org/repos/asf/james-project/blob/7c8ecec6/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
index 0772049..62bc92b 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -22,7 +22,6 @@ package org.apache.james.mdn.fields;
 import java.util.Objects;
 import java.util.Optional;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
 /**
@@ -43,8 +42,7 @@ public class ReportingUserAgent implements Field {
         this(userAgentName, Optional.of(userAgentProduct));
     }
 
-    @VisibleForTesting
-    ReportingUserAgent(String userAgentName, Optional<String> userAgentProduct) {
+    public ReportingUserAgent(String userAgentName, Optional<String> userAgentProduct) {
         Preconditions.checkNotNull(userAgentName);
         Preconditions.checkNotNull(userAgentProduct);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/7c8ecec6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index 2dd88b8..0d4cbba 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -22,7 +22,6 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Optional;
 
 import javax.mail.Address;
 import javax.mail.MessagingException;
@@ -34,11 +33,6 @@ import org.apache.james.mdn.MDNFactory;
 import org.apache.james.mdn.MDNReport;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.fields.Disposition;
-import org.apache.james.mdn.fields.FinalRecipient;
-import org.apache.james.mdn.fields.OriginalMessageId;
-import org.apache.james.mdn.fields.OriginalRecipient;
-import org.apache.james.mdn.fields.ReportingUserAgent;
-import org.apache.james.mdn.fields.Text;
 import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
@@ -121,13 +115,10 @@ public class RejectAction implements MailAction {
         MimeMultipart multiPart = MDNFactory.create(
             humanText.toString(),
             MDNReport.builder()
-                .reportingUserAgentField(
-                    new ReportingUserAgent(
-                        reporting_UA_name,
-                        reporting_UA_product))
-                .finalRecipientField(new FinalRecipient(Text.fromRawText(final_recipient)))
-                .originalRecipientField(Optional.ofNullable(original_recipient).map(Text::fromRawText).map(OriginalRecipient::new))
-                .originalMessageIdField(new OriginalMessageId(original_message_id))
+                .reportingUserAgentField(reporting_UA_name, reporting_UA_product)
+                .finalRecipientField(final_recipient)
+                .originalRecipientField(original_recipient)
+                .originalMessageIdField(original_message_id)
                 .dispositionField(Disposition.builder()
                     .actionMode(DispositionActionMode.Automatic)
                     .sendingMode(DispositionSendingMode.Automatic)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[10/27] james-project git commit: JAMES-2132 Reporting-UA field is optional, userAgentName is compulsory

Posted by bt...@apache.org.
JAMES-2132 Reporting-UA field is optional, userAgentName is compulsory

https://tools.ietf.org/html/rfc8098#section-3.2.1 states:

   reporting-ua-field = "Reporting-UA" ":" OWS ua-name OWS
                        [ ";" OWS ua-product OWS ]

An MUA SHOULD send a "Reporting-UA" field unless specifically configured
not to do so.


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/860489c3
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/860489c3
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/860489c3

Branch: refs/heads/master
Commit: 860489c35265ab230ae5a32816110313110f9c14
Parents: 1376259
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:01:56 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 19 +++---
 .../james/mdn/fields/ReportingUserAgent.java    | 12 ++--
 .../org/apache/james/mdn/MDNFactoryTest.java    | 65 ++++++--------------
 .../transport/mailets/jsieve/RejectAction.java  |  2 +-
 4 files changed, 36 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/860489c3/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 966ad06..0b429da 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -69,12 +69,11 @@ public class MDNReport {
         }
 
         public MDNReport build() {
-            Preconditions.checkState(reportingUserAgentField.isPresent());
             Preconditions.checkState(finalRecipientField.isPresent());
             Preconditions.checkState(originalMessageIdField.isPresent());
             Preconditions.checkState(dispositionField.isPresent());
 
-            return new MDNReport(reportingUserAgentField.get(),
+            return new MDNReport(reportingUserAgentField,
                 originalRecipientField,
                 finalRecipientField.get(),
                 originalMessageIdField.get(),
@@ -89,13 +88,13 @@ public class MDNReport {
 
     public static final String LINE_END = "\r\n";
 
-    private final ReportingUserAgent reportingUserAgentField;
+    private final Optional<ReportingUserAgent> reportingUserAgentField;
     private final Optional<OriginalRecipient> originalRecipientField;
     private final FinalRecipient finalRecipientField;
     private final OriginalMessageId originalMessageIdField;
     private final Disposition dispositionField;
 
-    private MDNReport(ReportingUserAgent reportingUserAgentField, Optional<OriginalRecipient> originalRecipientField,
+    private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<OriginalRecipient> originalRecipientField,
                      FinalRecipient finalRecipientField, OriginalMessageId originalMessageIdField, Disposition dispositionField) {
         this.reportingUserAgentField = reportingUserAgentField;
         this.originalRecipientField = originalRecipientField;
@@ -104,7 +103,7 @@ public class MDNReport {
         this.dispositionField = dispositionField;
     }
 
-    public ReportingUserAgent getReportingUserAgentField() {
+    public Optional<ReportingUserAgent> getReportingUserAgentField() {
         return reportingUserAgentField;
     }
 
@@ -125,11 +124,11 @@ public class MDNReport {
     }
 
     public String formattedValue() {
-        return reportingUserAgentField.formattedValue() + LINE_END
-            + originalRecipientField.map(value -> value.formattedValue() + "\r\n").orElse("")
-            + finalRecipientField.formattedValue() + "\r\n"
-            + originalMessageIdField.formattedValue() + "\r\n"
-            + dispositionField.formattedValue() + "\r\n";
+        return reportingUserAgentField.map(value -> value.formattedValue() + LINE_END).orElse("")
+            + originalRecipientField.map(value -> value.formattedValue() + LINE_END).orElse("")
+            + finalRecipientField.formattedValue() + LINE_END
+            + originalMessageIdField.formattedValue() + LINE_END
+            + dispositionField.formattedValue() + LINE_END;
 
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/860489c3/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
index 0072434..9124061 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -21,16 +21,20 @@ package org.apache.james.mdn.fields;
 
 import java.util.Optional;
 
+import com.google.common.base.Preconditions;
+
 public class ReportingUserAgent implements Field {
-    private final Optional<String> userAgentName;
+    private final String userAgentName;
     private final Optional<String> userAgentProduct;
 
-    public ReportingUserAgent(Optional<String> userAgentName, Optional<String> userAgentProduct) {
+    public ReportingUserAgent(String userAgentName, Optional<String> userAgentProduct) {
+        Preconditions.checkNotNull(userAgentName);
+        Preconditions.checkNotNull(userAgentProduct);
         this.userAgentName = userAgentName;
         this.userAgentProduct = userAgentProduct;
     }
 
-    public Optional<String> getUserAgentName() {
+    public String getUserAgentName() {
         return userAgentName;
     }
 
@@ -40,7 +44,7 @@ public class ReportingUserAgent implements Field {
 
     @Override
     public String formattedValue() {
-        return "Reporting-UA: " + userAgentName.orElse("") + "; "
+        return "Reporting-UA: " + userAgentName + "; "
             + userAgentProduct.orElse("");
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/860489c3/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 0837fdd..41d6c4a 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -53,7 +53,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -82,7 +82,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -111,7 +111,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -140,7 +140,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -169,7 +169,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -198,7 +198,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -227,7 +227,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -256,7 +256,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -284,7 +284,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -311,7 +311,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -337,7 +337,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -365,7 +365,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -393,7 +393,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -411,35 +411,6 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatNullUserAgentName() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                Optional.empty(),
-                Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: ; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
-    }
-
-    @Test
     public void generateMDNReportShouldFormatNullUserAgentProduct() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
@@ -451,7 +422,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.empty()))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -480,7 +451,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
@@ -507,7 +478,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.empty()))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -536,7 +507,7 @@ public class MDNFactoryTest {
 
         String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
@@ -560,7 +531,7 @@ public class MDNFactoryTest {
 
         MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
-                Optional.of("UA_name"),
+                "UA_name",
                 Optional.of("UA_product")))
             .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))

http://git-wip-us.apache.org/repos/asf/james-project/blob/860489c3/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index 4f50e12..fb624bb 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -122,7 +122,7 @@ public class RejectAction implements MailAction {
             MDNReport.builder()
                 .reportingUserAgentField(
                     new ReportingUserAgent(
-                        Optional.ofNullable(reporting_UA_name),
+                        reporting_UA_name,
                         Optional.ofNullable(reporting_UA_product)))
                 .finalRecipientField(new FinalRecipient(Optional.of(final_recipient)))
                 .originalRecipientField(Optional.ofNullable(original_recipient).map(OriginalRecipient::new))


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[17/27] james-project git commit: JAMES-2132 Extract field names into constants

Posted by bt...@apache.org.
JAMES-2132 Extract field names into constants


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/633d2eb5
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/633d2eb5
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/633d2eb5

Branch: refs/heads/master
Commit: 633d2eb5cdd57bc195e9a1fc9ad1f2c6d33d63ca
Parents: 034eef6
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 20:59:19 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java   | 4 +++-
 .../main/java/org/apache/james/mdn/fields/OriginalMessageId.java | 3 ++-
 .../java/org/apache/james/mdn/fields/ReportingUserAgent.java     | 3 ++-
 3 files changed, 7 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/633d2eb5/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
index a3c802e..742893c 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
@@ -32,6 +32,8 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 public class Disposition implements Field {
+    public static final String FIELD_NAME = "Disposition";
+
     public static class Builder {
         private Optional<DispositionActionMode> actionMode = Optional.empty();
         private Optional<DispositionSendingMode> sendingMode = Optional.empty();
@@ -106,7 +108,7 @@ public class Disposition implements Field {
 
     @Override
     public String formattedValue() {
-        return "Disposition: "
+        return FIELD_NAME + ": "
             + actionMode.getValue() + "/" + sendingMode.getValue() + ";" + type.getValue()
             + formattedModifiers();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/633d2eb5/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
index 83666dc..220a905 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
@@ -20,6 +20,7 @@
 package org.apache.james.mdn.fields;
 
 public class OriginalMessageId implements Field {
+    private static final String FIELD_NAME = "Original-Message-ID";
     private final String originalMessageId;
 
     public OriginalMessageId(String originalMessageId) {
@@ -32,6 +33,6 @@ public class OriginalMessageId implements Field {
 
     @Override
     public String formattedValue() {
-        return "Original-Message-ID: " + originalMessageId;
+        return FIELD_NAME + ": " + originalMessageId;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/633d2eb5/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
index 9124061..492e56d 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -24,6 +24,7 @@ import java.util.Optional;
 import com.google.common.base.Preconditions;
 
 public class ReportingUserAgent implements Field {
+    private static final String FIELD_NAME = "Reporting-UA";
     private final String userAgentName;
     private final Optional<String> userAgentProduct;
 
@@ -44,7 +45,7 @@ public class ReportingUserAgent implements Field {
 
     @Override
     public String formattedValue() {
-        return "Reporting-UA: " + userAgentName + "; "
+        return FIELD_NAME + ": " + userAgentName + "; "
             + userAgentProduct.orElse("");
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[13/27] james-project git commit: JAMES-2132 Add error field

Posted by bt...@apache.org.
JAMES-2132 Add error field

RFC defines them in https://tools.ietf.org/html/rfc8098#section-3.2.7 as:

   The Error field is used to supply additional information in the form
   of text messages when the "error" disposition modifier appears.  The
   syntax is as follows:

   error-field = "Error" ":" *([FWS] text)


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c576fd1c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c576fd1c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c576fd1c

Branch: refs/heads/master
Commit: c576fd1c516641b6954857706075380a6177bc7d
Parents: 5ee43e6
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:57:21 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 25 +++++++-
 .../java/org/apache/james/mdn/fields/Error.java | 39 ++++++++++++
 .../java/org/apache/james/mdn/fields/Text.java  | 47 ++++++++++++++
 .../org/apache/james/mdn/MDNFactoryTest.java    | 65 ++++++++++++++++++++
 4 files changed, 173 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c576fd1c/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 1423074..127f0f4 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -22,6 +22,7 @@ package org.apache.james.mdn;
 import java.util.Optional;
 
 import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.Error;
 import org.apache.james.mdn.fields.FinalRecipient;
 import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
@@ -39,6 +40,7 @@ public class MDNReport {
         private Optional<FinalRecipient> finalRecipientField = Optional.empty();
         private Optional<OriginalMessageId> originalMessageIdField = Optional.empty();
         private Optional<Disposition> dispositionField = Optional.empty();
+        private Optional<Error> errorField = Optional.empty();
 
         public Builder reportingUserAgentField(ReportingUserAgent reportingUserAgentField) {
             this.reportingUserAgentField = Optional.of(reportingUserAgentField);
@@ -65,6 +67,12 @@ public class MDNReport {
             return this;
         }
 
+
+        public Builder errorField(Error errorField) {
+            this.errorField = Optional.of(errorField);
+            return this;
+        }
+
         public Builder finalRecipientField(FinalRecipient finalRecipientField) {
             this.finalRecipientField = Optional.of(finalRecipientField);
             return this;
@@ -88,7 +96,7 @@ public class MDNReport {
                 gatewayField, originalRecipientField,
                 finalRecipientField.get(),
                 originalMessageIdField,
-                dispositionField.get());
+                dispositionField.get(), errorField);
         }
 
     }
@@ -105,15 +113,17 @@ public class MDNReport {
     private final FinalRecipient finalRecipientField;
     private final Optional<OriginalMessageId> originalMessageIdField;
     private final Disposition dispositionField;
+    private final Optional<Error> errorField;
 
     private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
-                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField) {
+                      FinalRecipient finalRecipientField, Optional<OriginalMessageId> originalMessageIdField, Disposition dispositionField, Optional<Error> errorField) {
         this.reportingUserAgentField = reportingUserAgentField;
         this.gatewayField = gatewayField;
         this.originalRecipientField = originalRecipientField;
         this.finalRecipientField = finalRecipientField;
         this.originalMessageIdField = originalMessageIdField;
         this.dispositionField = dispositionField;
+        this.errorField = errorField;
     }
 
     public Optional<ReportingUserAgent> getReportingUserAgentField() {
@@ -136,13 +146,22 @@ public class MDNReport {
         return dispositionField;
     }
 
+    public Optional<Gateway> getGatewayField() {
+        return gatewayField;
+    }
+
+    public Optional<Error> getErrorField() {
+        return errorField;
+    }
+
     public String formattedValue() {
         return reportingUserAgentField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + gatewayField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + originalRecipientField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + finalRecipientField.formattedValue() + LINE_END
             + originalMessageIdField.map(value -> value.formattedValue() + LINE_END).orElse("")
-            + dispositionField.formattedValue() + LINE_END;
+            + dispositionField.formattedValue() + LINE_END
+            + errorField.map(value -> value.formattedValue() + LINE_END).orElse("");
 
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c576fd1c/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Error.java b/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
new file mode 100644
index 0000000..8a68299
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+public class Error implements Field {
+    public static final String FIELD_NAME = "Error";
+
+    private final Text text;
+
+    public Error(Text text) {
+        this.text = text;
+    }
+
+    public Text getText() {
+        return text;
+    }
+
+    @Override
+    public String formattedValue() {
+        return FIELD_NAME + ": " + text.formatted();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c576fd1c/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Text.java b/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
new file mode 100644
index 0000000..7473e08
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
@@ -0,0 +1,47 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+
+public class Text {
+
+    public static Text fromRawText(String rawText) {
+        return new Text(replaceLineBreaksByContinuation(rawText));
+    }
+
+    private static String replaceLineBreaksByContinuation(String rawText) {
+        return Joiner.on("\r\n ")
+            .join(Splitter.on("\n")
+                .trimResults()
+                .splitToList(rawText));
+    }
+
+    private final String content;
+
+    public Text(String content) {
+        this.content = content;
+    }
+
+    public String formatted() {
+        return content;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c576fd1c/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index ac51b08..01b71b7 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -25,11 +25,13 @@ import java.util.Optional;
 
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.Error;
 import org.apache.james.mdn.fields.FinalRecipient;
 import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
+import org.apache.james.mdn.fields.Text;
 import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
@@ -565,4 +567,67 @@ public class MDNFactoryTest {
             .dispositionField(disposition)
             .build();
     }
+
+    @Test
+    public void generateMDNReportShouldFormatErrorFields() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .errorField(new Error(Text.fromRawText("An error message")))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "Error: An error message\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatErrorFieldsOnSeveralLines() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .errorField(new Error(Text.fromRawText("An error message\non several lines")))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "Error: An error message\r\n" +
+                " on several lines\r\n");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[09/27] james-project git commit: JAMES-2132 adding MDN-Gateway field

Posted by bt...@apache.org.
JAMES-2132 adding MDN-Gateway field

https://tools.ietf.org/html/rfc8098#section-3.2.2 states:

   The MDN-Gateway field indicates the name of the gateway or MTA that
   translated a foreign (non-Internet) message disposition notification
   into this MDN.  This field MUST appear in any MDN that was translated
   by a gateway from a foreign system into MDN format and MUST NOT
   appear otherwise.

   mdn-gateway-field = "MDN-Gateway" ":" OWS mta-name-type OWS
                       ";" OWS mta-name OWS

   mta-name = *text

   For gateways into Internet Mail, the MTA-name-type will normally be
   "dns", and the mta-name will be the Internet domain name of the
   gateway.


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/bbc128a1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/bbc128a1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/bbc128a1

Branch: refs/heads/master
Commit: bbc128a1c488ccc3e47ae69ea4993ef1063b6066
Parents: 860489c
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:12:15 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/MDNReport.java    | 21 ++++++-
 .../org/apache/james/mdn/fields/Gateway.java    | 53 ++++++++++++++++
 .../org/apache/james/mdn/MDNFactoryTest.java    | 63 ++++++++++++++++++++
 3 files changed, 134 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc128a1/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
index 0b429da..9dce948 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNReport.java
@@ -23,6 +23,7 @@ import java.util.Optional;
 
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
@@ -33,6 +34,7 @@ public class MDNReport {
 
     public static class Builder {
         private Optional<ReportingUserAgent> reportingUserAgentField = Optional.empty();
+        private Optional<Gateway> gatewayField = Optional.empty();
         private Optional<OriginalRecipient> originalRecipientField = Optional.empty();
         private Optional<FinalRecipient> finalRecipientField = Optional.empty();
         private Optional<OriginalMessageId> originalMessageIdField = Optional.empty();
@@ -53,6 +55,16 @@ public class MDNReport {
             return this;
         }
 
+        public Builder gatewayField(Optional<Gateway> gatewayField) {
+            this.gatewayField = gatewayField;
+            return this;
+        }
+
+        public Builder gatewayField(Gateway gatewayField) {
+            this.gatewayField = Optional.of(gatewayField);
+            return this;
+        }
+
         public Builder finalRecipientField(FinalRecipient finalRecipientField) {
             this.finalRecipientField = Optional.of(finalRecipientField);
             return this;
@@ -74,7 +86,7 @@ public class MDNReport {
             Preconditions.checkState(dispositionField.isPresent());
 
             return new MDNReport(reportingUserAgentField,
-                originalRecipientField,
+                gatewayField, originalRecipientField,
                 finalRecipientField.get(),
                 originalMessageIdField.get(),
                 dispositionField.get());
@@ -89,14 +101,16 @@ public class MDNReport {
     public static final String LINE_END = "\r\n";
 
     private final Optional<ReportingUserAgent> reportingUserAgentField;
+    private final Optional<Gateway> gatewayField;
     private final Optional<OriginalRecipient> originalRecipientField;
     private final FinalRecipient finalRecipientField;
     private final OriginalMessageId originalMessageIdField;
     private final Disposition dispositionField;
 
-    private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<OriginalRecipient> originalRecipientField,
-                     FinalRecipient finalRecipientField, OriginalMessageId originalMessageIdField, Disposition dispositionField) {
+    private MDNReport(Optional<ReportingUserAgent> reportingUserAgentField, Optional<Gateway> gatewayField, Optional<OriginalRecipient> originalRecipientField,
+                      FinalRecipient finalRecipientField, OriginalMessageId originalMessageIdField, Disposition dispositionField) {
         this.reportingUserAgentField = reportingUserAgentField;
+        this.gatewayField = gatewayField;
         this.originalRecipientField = originalRecipientField;
         this.finalRecipientField = finalRecipientField;
         this.originalMessageIdField = originalMessageIdField;
@@ -125,6 +139,7 @@ public class MDNReport {
 
     public String formattedValue() {
         return reportingUserAgentField.map(value -> value.formattedValue() + LINE_END).orElse("")
+            + gatewayField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + originalRecipientField.map(value -> value.formattedValue() + LINE_END).orElse("")
             + finalRecipientField.formattedValue() + LINE_END
             + originalMessageIdField.formattedValue() + LINE_END

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc128a1/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
new file mode 100644
index 0000000..4647c99
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+/**
+ * MDN-Gateway field as specified in https://tools.ietf.org/html/rfc8098#section-3.2.2
+ */
+public class Gateway implements Field {
+    private static final String DNS = "dns";
+    public static final String FIELD_NAME = "MDN-Gateway";
+
+    private final String nameType;
+    private final String name;
+
+    public Gateway(String nameType, String name) {
+        this.nameType = nameType;
+        this.name = name;
+    }
+
+    public Gateway(String name) {
+        this(DNS, name);
+    }
+
+    @Override
+    public String formattedValue() {
+        return FIELD_NAME + ": " + nameType + ";" + name;
+    }
+
+    public String getNameType() {
+        return nameType;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbc128a1/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 41d6c4a..5fd3cee 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -26,6 +26,7 @@ import java.util.Optional;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.Gateway;
 import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
@@ -537,4 +538,66 @@ public class MDNFactoryTest {
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .build();
     }
+
+    @Test
+    public void generateMDNReportShouldFormatGateway() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .gatewayField(new Gateway("host.com"))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: dns;host.com\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+    
+    @Test
+    public void generateMDNReportShouldFormatGatewayWithExoticNameType() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .gatewayField(new Gateway("postal", "5 rue Charles mercier"))
+            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: postal;5 rue Charles mercier\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[04/27] james-project git commit: JAMES-2132 support various Address type

Posted by bt...@apache.org.
JAMES-2132 support various Address type

The address-type field indicates the type of the original recipient
   address.  If the message originated within the Internet, the address-
   type field will normally be "rfc822", and the address will be
   according to the syntax specified in RFC-MSGFMT [RFC5322].  The value
   "unknown" should be used if the Reporting MUA cannot determine the
   type of the original recipient address from the message envelope.


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/eb167089
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/eb167089
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/eb167089

Branch: refs/heads/master
Commit: eb1670891c34efd17a08ec99edaf8bea83af9ffa
Parents: bbc128a
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:21:33 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../apache/james/mdn/fields/FinalRecipient.java |  20 ++-
 .../james/mdn/fields/OriginalRecipient.java     |  24 ++-
 .../org/apache/james/mdn/MDNFactoryTest.java    | 167 ++++++++++++++-----
 3 files changed, 159 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/eb167089/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
index a9799d2..5d0772e 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -19,25 +19,33 @@
 
 package org.apache.james.mdn.fields;
 
-import java.util.Optional;
-
 import org.apache.james.mdn.Constants;
 
+import com.google.common.base.Preconditions;
+
 public class FinalRecipient implements Field {
     public static final String FIELD_NAME = "Final-Recepient";
 
-    private final Optional<String> finalRecipient;
+    private final String finalRecipient;
+    private final String addressType;
 
-    public FinalRecipient(Optional<String> finalRecipient) {
+    public FinalRecipient(String addressType, String finalRecipient) {
+        Preconditions.checkNotNull(finalRecipient);
+        Preconditions.checkNotNull(addressType);
         this.finalRecipient = finalRecipient;
+        this.addressType = addressType;
+    }
+
+    public FinalRecipient(String finalRecipient) {
+        this(Constants.RFC_822, finalRecipient);
     }
 
-    public Optional<String> getFinalRecipient() {
+    public String getFinalRecipient() {
         return finalRecipient;
     }
 
     @Override
     public String formattedValue() {
-        return FIELD_NAME + ": " + Constants.RFC_822 + "; " + finalRecipient.orElse("");
+        return FIELD_NAME + ": " + addressType + "; " + finalRecipient;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/eb167089/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
index a44c055..9c399ff 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -21,19 +21,39 @@ package org.apache.james.mdn.fields;
 
 import org.apache.james.mdn.Constants;
 
+import com.google.common.base.Preconditions;
+
 public class OriginalRecipient implements Field{
+    private static final String UNKNOWN = "unknown";
+
+    public static OriginalRecipient ofUnknown(String address) {
+        return new OriginalRecipient(UNKNOWN, address);
+    }
+
     private final String originalRecipient;
+    private final String addressType;
 
-    public OriginalRecipient(String originalRecipient) {
+    public OriginalRecipient(String addressType, String originalRecipient) {
+        Preconditions.checkNotNull(addressType);
+        Preconditions.checkNotNull(originalRecipient);
+        this.addressType = addressType;
         this.originalRecipient = originalRecipient;
     }
 
+    public OriginalRecipient(String originalRecipient) {
+        this(Constants.RFC_822, originalRecipient);
+    }
+
     public String getOriginalRecipient() {
         return originalRecipient;
     }
 
+    public String getAddressType() {
+        return addressType;
+    }
+
     @Override
     public String formattedValue() {
-        return "Original-Recipient: " + Constants.RFC_822 + "; " + originalRecipient;
+        return "Original-Recipient: " + addressType + "; " + originalRecipient;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/eb167089/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 5fd3cee..0cd3cde 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -56,7 +56,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -85,7 +85,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -114,7 +114,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -143,7 +143,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -172,7 +172,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -201,7 +201,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -230,7 +230,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -259,7 +259,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -287,7 +287,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -314,7 +314,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -340,7 +340,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -368,7 +368,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -396,7 +396,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -425,7 +425,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.empty()))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -454,7 +454,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
             .build()
@@ -468,7 +468,7 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatNullFinalRecipient() {
+    public void generateMDNReportShouldFormatNullOriginalMessageId() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
             .sendingMode(DispositionSendingMode.Automatic)
@@ -481,9 +481,9 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.empty()))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .originalMessageIdField(new OriginalMessageId(Optional.empty()))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -491,17 +491,30 @@ public class MDNFactoryTest {
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; \r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: \r\n" +
                 "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
     }
 
     @Test
-    public void generateMDNReportShouldFormatNullOriginalMessageId() {
+    public void generateMDNReportThrowOnNullDisposition() {
+        expectedException.expect(IllegalStateException.class);
+
+        MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .build();
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatGateway() {
         Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
+            .actionMode(DispositionActionMode.Automatic)
             .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Deleted)
+            .type(DispositionType.Processed)
             .addModifier(DispositionModifier.Error)
             .addModifier(DispositionModifier.Failed)
             .build();
@@ -510,37 +523,85 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .gatewayField(new Gateway("host.com"))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId(Optional.empty()))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
             .build()
             .formattedValue();
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: dns;host.com\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: \r\n" +
-                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
 
     @Test
-    public void generateMDNReportThrowOnNullDisposition() {
-        Disposition disposition = null;
-        expectedException.expect(IllegalStateException.class);
+    public void generateMDNReportShouldFormatGatewayWithExoticNameType() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
 
-        MDNReport.builder()
+        String report = MDNReport.builder()
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .gatewayField(new Gateway("postal", "5 rue Charles mercier"))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: postal;5 rue Charles mercier\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatExoticAddressTypeForOriginalRecipient() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
             .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
+            .originalRecipientField(new OriginalRecipient("roomNumber", "385"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: roomNumber; 385\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
 
     @Test
-    public void generateMDNReportShouldFormatGateway() {
+    public void generateMDNReportShouldFormatUnknownAddressTypeForOriginalRecipient() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
             .sendingMode(DispositionSendingMode.Automatic)
@@ -553,9 +614,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .gatewayField(new Gateway("host.com"))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient("final_recipient"))
+            .originalRecipientField(OriginalRecipient.ofUnknown("#$%*"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
             .build()
@@ -563,15 +623,14 @@ public class MDNFactoryTest {
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "MDN-Gateway: dns;host.com\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Original-Recipient: unknown; #$%*\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
-    
+
     @Test
-    public void generateMDNReportShouldFormatGatewayWithExoticNameType() {
+    public void generateMDNReportShouldFormatExoticFinalRecipientAddressType() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
             .sendingMode(DispositionSendingMode.Automatic)
@@ -584,8 +643,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .gatewayField(new Gateway("postal", "5 rue Charles mercier"))
-            .finalRecipientField(new FinalRecipient(Optional.of("final_recipient")))
+            .finalRecipientField(new FinalRecipient("roomNumber", "781"))
             .originalRecipientField(new OriginalRecipient("originalRecipient"))
             .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
             .dispositionField(disposition)
@@ -594,10 +652,31 @@ public class MDNFactoryTest {
 
         assertThat(report)
             .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "MDN-Gateway: postal;5 rue Charles mercier\r\n" +
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Final-Recepient: roomNumber; 781\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
                 "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
     }
+
+    @Test
+    public void generateMDNReportShouldThrowWhenMissingFinalField() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        expectedException.expect(IllegalStateException.class);
+
+        MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalMessageIdField(new OriginalMessageId(Optional.of("original_message_id")))
+            .dispositionField(disposition)
+            .build();
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[06/27] james-project git commit: JAMES-2132 Add tests

Posted by bt...@apache.org.
JAMES-2132 Add tests


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/811b8478
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/811b8478
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/811b8478

Branch: refs/heads/master
Commit: 811b84780732332776ebcfb2e0e372760c47a591
Parents: bbc0bfa
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 13:45:15 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 mdn/pom.xml                                     |   9 +
 .../java/org/apache/james/mdn/MDNFactory.java   |  34 +-
 .../org/apache/james/mdn/MDNFactoryTest.java    | 357 +++++++++++++++++++
 3 files changed, 389 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/811b8478/mdn/pom.xml
----------------------------------------------------------------------
diff --git a/mdn/pom.xml b/mdn/pom.xml
index 39f58a9..0a7be2b 100644
--- a/mdn/pom.xml
+++ b/mdn/pom.xml
@@ -38,6 +38,15 @@
             <groupId>org.apache.james</groupId>
             <artifactId>apache-mailet-base</artifactId>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+        </dependency>
     </dependencies>
 
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/811b8478/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
index bc3312f..31aae2b 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
@@ -72,6 +72,28 @@ public class MDNFactory
         multiPart.addBodyPart(humanPart);
 
         // Part 2: MDN Report Part
+        String mdnReport = generateMDNReport(reporting_UA_name,
+            reporting_UA_product,
+            original_recipient,
+            final_recipient,
+            original_message_id,
+            disposition);
+
+        MimeBodyPart mdnPart = new MimeBodyPart();
+        mdnPart.setContent(mdnReport, "message/disposition-notification");
+        multiPart.addBodyPart(mdnPart);
+
+        // Part 3: The optional third part, the original message is omitted.
+        // We don't want to propogate over-sized, virus infected or
+        // other undesirable mail!
+        // There is the option of adding a Text/RFC822-Headers part, which
+        // includes only the RFC 822 headers of the failed message. This is
+        // described in RFC 1892. It would be a useful addition!        
+        return multiPart;
+    }
+
+    public static String generateMDNReport(String reporting_UA_name, String reporting_UA_product, String original_recipient,
+                                                   String final_recipient, String original_message_id, Disposition disposition) {
         // 1) reporting-ua-field
         StringBuilder mdnReport = new StringBuilder(128);
         mdnReport.append("Reporting-UA: ");
@@ -99,17 +121,7 @@ public class MDNFactory
         // 5) disposition-field
         mdnReport.append(disposition.toString());
         mdnReport.append("\r\n");
-        MimeBodyPart mdnPart = new MimeBodyPart();
-        mdnPart.setContent(mdnReport.toString(), "message/disposition-notification");
-        multiPart.addBodyPart(mdnPart);
-
-        // Part 3: The optional third part, the original message is omitted.
-        // We don't want to propogate over-sized, virus infected or
-        // other undesirable mail!
-        // There is the option of adding a Text/RFC822-Headers part, which
-        // includes only the RFC 822 headers of the failed message. This is
-        // described in RFC 1892. It would be a useful addition!        
-        return multiPart;
+        return mdnReport.toString();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/811b8478/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
new file mode 100644
index 0000000..18337c6
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -0,0 +1,357 @@
+/****************************************************************
+ * 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.mdn;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.mdn.action.mode.ActionModeAutomatic;
+import org.apache.james.mdn.action.mode.ActionModeManual;
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.modifier.ModifierError;
+import org.apache.james.mdn.modifier.ModifierExpired;
+import org.apache.james.mdn.modifier.ModifierFailed;
+import org.apache.james.mdn.modifier.ModifierMailboxTerminated;
+import org.apache.james.mdn.modifier.ModifierSuperseded;
+import org.apache.james.mdn.modifier.ModifierWarning;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.sending.mode.SendingModeAutomatic;
+import org.apache.james.mdn.sending.mode.SendingModeManual;
+import org.apache.james.mdn.type.DispositionType;
+import org.apache.james.mdn.type.TypeDeleted;
+import org.apache.james.mdn.type.TypeDenied;
+import org.apache.james.mdn.type.TypeDispatched;
+import org.apache.james.mdn.type.TypeDisplayed;
+import org.apache.james.mdn.type.TypeFailed;
+import org.apache.james.mdn.type.TypeProcessed;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class MDNFactoryTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void generateMDNReportShouldFormatAutomaticActions() {
+        Disposition disposition = new Disposition(new ActionModeAutomatic(), new SendingModeAutomatic(), new TypeProcessed());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatManualActions() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeProcessed());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDenied() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDenied());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;denied/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDispatcher() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDispatched());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;dispatched/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDisplayed() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDisplayed());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;displayed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeFailed() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeFailed());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;failed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDeleted() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatAllModifier() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierExpired(), new ModifierFailed(),
+            new ModifierMailboxTerminated(), new ModifierSuperseded(), new ModifierWarning()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/error,expired,failed,mailbox-terminated,superseded,warning\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNoModifier() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNoModifierNullType() {
+        DispositionType type = null;
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), type);
+        DispositionModifier[] dispostionModifiers = {};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullActionMode() {
+        DispositionActionMode actionMode = null;
+        Disposition disposition = new Disposition(actionMode, new SendingModeManual(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: /MDN-sent-manually;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullSendingMode() {
+        DispositionSendingMode sendingMode = null;
+        Disposition disposition = new Disposition(new ActionModeManual(), sendingMode, new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullUserAgentName() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String reporting_ua_name = null;
+        String report = MDNFactory.generateMDNReport(reporting_ua_name, "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: ; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullUserAgentProduct() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String reporting_ua_product = null;
+        String report = MDNFactory.generateMDNReport("UA_name", reporting_ua_product, "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; \r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullOriginalRecipient() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String original_recipient = null;
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", original_recipient,
+            "final_recipient", "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullFinalRecipient() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String final_recipient = null;
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            final_recipient, "original_message_id", disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; \r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullOriginalMessageId() {
+        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
+        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        disposition.setDispositionModifiers(dispostionModifiers);
+
+        String original_message_id = null;
+        String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", original_message_id, disposition);
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recepient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: \r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportThrowOnNullDisposition() {
+        Disposition disposition = null;
+        expectedException.expect(NullPointerException.class);
+        MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
+            "final_recipient", "original_message_id", disposition);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[15/27] james-project git commit: JAMES-2132 Address should be Text

Posted by bt...@apache.org.
JAMES-2132 Address should be Text


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/beae701a
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/beae701a
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/beae701a

Branch: refs/heads/master
Commit: beae701acd50bb8ffc7249386e7be87c70fbef82
Parents: c576fd1
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 18:04:50 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 .../apache/james/mdn/fields/FinalRecipient.java |  10 +-
 .../org/apache/james/mdn/fields/Gateway.java    |  10 +-
 .../james/mdn/fields/OriginalRecipient.java     |  12 +-
 .../org/apache/james/mdn/MDNFactoryTest.java    | 121 ++++++++++++-------
 .../transport/mailets/jsieve/RejectAction.java  |   7 +-
 5 files changed, 99 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/beae701a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
index 5d0772e..fa4cd42 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -26,26 +26,26 @@ import com.google.common.base.Preconditions;
 public class FinalRecipient implements Field {
     public static final String FIELD_NAME = "Final-Recepient";
 
-    private final String finalRecipient;
+    private final Text finalRecipient;
     private final String addressType;
 
-    public FinalRecipient(String addressType, String finalRecipient) {
+    public FinalRecipient(String addressType, Text finalRecipient) {
         Preconditions.checkNotNull(finalRecipient);
         Preconditions.checkNotNull(addressType);
         this.finalRecipient = finalRecipient;
         this.addressType = addressType;
     }
 
-    public FinalRecipient(String finalRecipient) {
+    public FinalRecipient(Text finalRecipient) {
         this(Constants.RFC_822, finalRecipient);
     }
 
-    public String getFinalRecipient() {
+    public Text getFinalRecipient() {
         return finalRecipient;
     }
 
     @Override
     public String formattedValue() {
-        return FIELD_NAME + ": " + addressType + "; " + finalRecipient;
+        return FIELD_NAME + ": " + addressType + "; " + finalRecipient.formatted();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/beae701a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
index 4647c99..493aa6b 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
@@ -27,27 +27,27 @@ public class Gateway implements Field {
     public static final String FIELD_NAME = "MDN-Gateway";
 
     private final String nameType;
-    private final String name;
+    private final Text name;
 
-    public Gateway(String nameType, String name) {
+    public Gateway(String nameType, Text name) {
         this.nameType = nameType;
         this.name = name;
     }
 
-    public Gateway(String name) {
+    public Gateway(Text name) {
         this(DNS, name);
     }
 
     @Override
     public String formattedValue() {
-        return FIELD_NAME + ": " + nameType + ";" + name;
+        return FIELD_NAME + ": " + nameType + ";" + name.formatted();
     }
 
     public String getNameType() {
         return nameType;
     }
 
-    public String getName() {
+    public Text getName() {
         return name;
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/beae701a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
index 9c399ff..f8e084d 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -26,25 +26,25 @@ import com.google.common.base.Preconditions;
 public class OriginalRecipient implements Field{
     private static final String UNKNOWN = "unknown";
 
-    public static OriginalRecipient ofUnknown(String address) {
+    public static OriginalRecipient ofUnknown(Text address) {
         return new OriginalRecipient(UNKNOWN, address);
     }
 
-    private final String originalRecipient;
+    private final Text originalRecipient;
     private final String addressType;
 
-    public OriginalRecipient(String addressType, String originalRecipient) {
+    public OriginalRecipient(String addressType, Text originalRecipient) {
         Preconditions.checkNotNull(addressType);
         Preconditions.checkNotNull(originalRecipient);
         this.addressType = addressType;
         this.originalRecipient = originalRecipient;
     }
 
-    public OriginalRecipient(String originalRecipient) {
+    public OriginalRecipient(Text originalRecipient) {
         this(Constants.RFC_822, originalRecipient);
     }
 
-    public String getOriginalRecipient() {
+    public Text getOriginalRecipient() {
         return originalRecipient;
     }
 
@@ -54,6 +54,6 @@ public class OriginalRecipient implements Field{
 
     @Override
     public String formattedValue() {
-        return "Original-Recipient: " + addressType + "; " + originalRecipient;
+        return "Original-Recipient: " + addressType + "; " + originalRecipient.formatted();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/beae701a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 01b71b7..d34e13a 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -58,8 +58,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -87,8 +87,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -116,8 +116,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -145,8 +145,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -174,8 +174,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -203,8 +203,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -231,8 +231,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -259,8 +259,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -286,8 +286,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -315,8 +315,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.empty()))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -344,7 +344,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -371,8 +371,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .dispositionField(disposition)
             .build()
             .formattedValue();
@@ -392,8 +392,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .build();
     }
 
@@ -411,9 +411,9 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .gatewayField(new Gateway("host.com"))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .gatewayField(new Gateway(Text.fromRawText("host.com")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -442,9 +442,9 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .gatewayField(new Gateway("postal", "5 rue Charles mercier"))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .gatewayField(new Gateway("postal", Text.fromRawText("5 rue Charles mercier")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -473,8 +473,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("roomNumber", "385"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("roomNumber", Text.fromRawText("385")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -489,6 +489,43 @@ public class MDNFactoryTest {
     }
 
     @Test
+    public void generateMDNReportShouldFormatMultilineAddresses() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                Optional.of("UA_product")))
+            .gatewayField(new Gateway("postal", Text.fromRawText("8 rue Charles mercier\n 36555 Saint Coincoin\n France")))
+            .finalRecipientField(new FinalRecipient("postal", Text.fromRawText("5 rue Mercier\n 36555 Saint Coincoin\n France")))
+            .originalRecipientField(new OriginalRecipient("postal", Text.fromRawText("3 rue Mercier\n 36555 Saint Coincoin\n France")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: postal;8 rue Charles mercier\r\n" +
+                " 36555 Saint Coincoin\r\n" +
+                " France\r\n" +
+                "Original-Recipient: postal; 3 rue Mercier\r\n" +
+                " 36555 Saint Coincoin\r\n" +
+                " France\r\n" +
+                "Final-Recepient: postal; 5 rue Mercier\r\n" +
+                " 36555 Saint Coincoin\r\n" +
+                " France\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
     public void generateMDNReportShouldFormatUnknownAddressTypeForOriginalRecipient() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Automatic)
@@ -502,8 +539,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(OriginalRecipient.ofUnknown("#$%*"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(OriginalRecipient.ofUnknown(Text.fromRawText("#$%*")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -531,8 +568,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("roomNumber", "781"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient("roomNumber", Text.fromRawText("781")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -562,7 +599,7 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build();
@@ -582,8 +619,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .errorField(new Error(Text.fromRawText("An error message")))
@@ -613,8 +650,8 @@ public class MDNFactoryTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .errorField(new Error(Text.fromRawText("An error message\non several lines")))

http://git-wip-us.apache.org/repos/asf/james-project/blob/beae701a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index fb624bb..8cd47ef 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -38,6 +38,7 @@ import org.apache.james.mdn.fields.FinalRecipient;
 import org.apache.james.mdn.fields.OriginalMessageId;
 import org.apache.james.mdn.fields.OriginalRecipient;
 import org.apache.james.mdn.fields.ReportingUserAgent;
+import org.apache.james.mdn.fields.Text;
 import org.apache.james.mdn.modifier.DispositionModifier;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
 import org.apache.james.mdn.type.DispositionType;
@@ -124,9 +125,9 @@ public class RejectAction implements MailAction {
                     new ReportingUserAgent(
                         reporting_UA_name,
                         Optional.ofNullable(reporting_UA_product)))
-                .finalRecipientField(new FinalRecipient(Optional.of(final_recipient)))
-                .originalRecipientField(Optional.ofNullable(original_recipient).map(OriginalRecipient::new))
-                .originalMessageIdField(new OriginalMessageId(Optional.of(original_message_id)))
+                .finalRecipientField(new FinalRecipient(Text.fromRawText(final_recipient)))
+                .originalRecipientField(Optional.ofNullable(original_recipient).map(Text::fromRawText).map(OriginalRecipient::new))
+                .originalMessageIdField(new OriginalMessageId(original_message_id))
                 .dispositionField(Disposition.builder()
                     .actionMode(DispositionActionMode.Automatic)
                     .sendingMode(DispositionSendingMode.Automatic)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[20/27] james-project git commit: JAMES-2132 Reference in MDN data-model class relevant portions of RFC-8098

Posted by bt...@apache.org.
JAMES-2132 Reference in MDN data-model class relevant portions of RFC-8098


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/879fe839
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/879fe839
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/879fe839

Branch: refs/heads/master
Commit: 879fe8395e46585e7c49f8e0b013bdc3dad492f5
Parents: 6643ef2
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 21:17:03 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:14:47 2017 +0700

----------------------------------------------------------------------
 .../org/apache/james/mdn/action/mode/DispositionActionMode.java | 4 +++-
 mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java  | 3 +++
 mdn/src/main/java/org/apache/james/mdn/fields/Error.java        | 5 +++++
 .../main/java/org/apache/james/mdn/fields/ExtensionField.java   | 5 +++++
 mdn/src/main/java/org/apache/james/mdn/fields/Field.java        | 5 +++++
 .../main/java/org/apache/james/mdn/fields/FinalRecipient.java   | 5 +++++
 .../java/org/apache/james/mdn/fields/OriginalMessageId.java     | 5 +++++
 .../java/org/apache/james/mdn/fields/OriginalRecipient.java     | 5 +++++
 .../java/org/apache/james/mdn/fields/ReportingUserAgent.java    | 5 +++++
 .../java/org/apache/james/mdn/modifier/DispositionModifier.java | 4 +++-
 .../apache/james/mdn/sending/mode/DispositionSendingMode.java   | 4 +++-
 .../main/java/org/apache/james/mdn/type/DispositionType.java    | 4 +++-
 12 files changed, 50 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
index 6becee0..4c41cc6 100644
--- a/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
+++ b/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
@@ -24,7 +24,9 @@ import java.util.stream.Stream;
 
 /**
  * Interface <code>DispositionActionMode</code> marks a type encapsulating
- * disposition action mode information as defined by RFC 2298.
+ * disposition action mode information as defined by RFC 8098.
+ *
+ * More information https://tools.ietf.org/html/rfc8098#section-3.2.6.1
  */
 public enum DispositionActionMode {
     Manual("manual-action"),

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
index 742893c..157b4b7 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Disposition.java
@@ -31,6 +31,9 @@ import org.apache.james.mdn.type.DispositionType;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
+/**
+ * Implements disposition as stated in https://tools.ietf.org/html/rfc8098#section-3.2.6
+ */
 public class Disposition implements Field {
     public static final String FIELD_NAME = "Disposition";
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Error.java b/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
index 8a68299..64dface 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Error.java
@@ -19,6 +19,11 @@
 
 package org.apache.james.mdn.fields;
 
+/**
+ * Implements the optional MDN Error field defined in RFC-8098
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.7
+ */
 public class Error implements Field {
     public static final String FIELD_NAME = "Error";
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java b/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
index 65d9e84..9b6e6bc 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ExtensionField.java
@@ -19,6 +19,11 @@
 
 package org.apache.james.mdn.fields;
 
+/**
+ * Implements extension fields allowed by RFC-8098
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.3
+ */
 public class ExtensionField implements Field {
     private final String fieldName;
     private final String rawValue;

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Field.java b/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
index bef0139..3875cd3 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Field.java
@@ -19,6 +19,11 @@
 
 package org.apache.james.mdn.fields;
 
+/**
+ * Interface that defines fields as stated in RFC-8098
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.1
+ */
 public interface Field {
     String formattedValue();
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
index d8ce484..b613747 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -23,6 +23,11 @@ import org.apache.james.mdn.Constants;
 
 import com.google.common.base.Preconditions;
 
+/**
+ * Implements mandatory Final recipient field
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.4
+ */
 public class FinalRecipient implements Field {
     public static final String FIELD_NAME = "Final-Recipient";
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
index 220a905..96a1245 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
@@ -19,6 +19,11 @@
 
 package org.apache.james.mdn.fields;
 
+/**
+ * Optional Original-Message−Id as defined in RFC-8098
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.5
+ */
 public class OriginalMessageId implements Field {
     private static final String FIELD_NAME = "Original-Message-ID";
     private final String originalMessageId;

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
index 9c53e7e..ccb69c2 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -23,6 +23,11 @@ import org.apache.james.mdn.Constants;
 
 import com.google.common.base.Preconditions;
 
+/**
+ * Implements optional Original-Recipient field defined in:
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.3
+ */
 public class OriginalRecipient implements Field{
     private static final String UNKNOWN = "unknown";
     private static final String FIELD_NAME = "Original-Recipient";

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
index 492e56d..663a27a 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -23,6 +23,11 @@ import java.util.Optional;
 
 import com.google.common.base.Preconditions;
 
+/**
+ * Implements optional Reporting-UA header field
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.1
+ */
 public class ReportingUserAgent implements Field {
     private static final String FIELD_NAME = "Reporting-UA";
     private final String userAgentName;

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
index ac4ba63..f4a2b70 100644
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
@@ -21,7 +21,9 @@ package org.apache.james.mdn.modifier;
 
 /**
  * Interface <code>DispositionModifier</code> marks a type encapsulating
- * disposition modifier information as defined by RFC 2298.
+ * disposition modifier information as defined by RFC 8098.
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.6.3
  */
 public class DispositionModifier {
     public static DispositionModifier Error = new DispositionModifier("error");

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
index 99e63c1..d3c3556 100644
--- a/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
+++ b/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
@@ -24,7 +24,9 @@ import java.util.stream.Stream;
 
 /**
  * Interface <code>DispositionSendingMode</code> marks a type encapsulating
- * disposition sending mode information as defined by RFC 2298.
+ * disposition sending mode information as defined by RFC 8098.
+ *
+ * More information: https://tools.ietf.org/html/rfc8098#section-3.2.6.1
  */
 public enum DispositionSendingMode {
     Manual("MDN-sent-manually"),

http://git-wip-us.apache.org/repos/asf/james-project/blob/879fe839/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
index a70bdd1..e548e35 100644
--- a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
+++ b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
@@ -24,7 +24,9 @@ import java.util.stream.Stream;
 
 /**
  * Interface <code>DispositionType</code> marks a type encapsulating
- * disposition type information as defined by RFC 2298.
+ * disposition type information as defined by RFC 8098.
+ *
+ * https://tools.ietf.org/html/rfc8098#section-3.2.6.2
  */
 public enum DispositionType {
     Deleted("deleted"),


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[24/27] james-project git commit: JAMES-2132 Introduce a MDN top level object

Posted by bt...@apache.org.
JAMES-2132 Introduce a MDN top level object

This also removes the dependency to mailet-base


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/1f443cd1
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/1f443cd1
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/1f443cd1

Branch: refs/heads/master
Commit: 1f443cd1b1418886388b3977f600face45d0d375
Parents: 7c8ecec
Author: benwa <bt...@linagora.com>
Authored: Wed Aug 30 14:15:03 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:16:14 2017 +0700

----------------------------------------------------------------------
 mdn/pom.xml                                     |   8 +-
 mdn/src/main/java/org/apache/james/mdn/MDN.java | 127 ++++
 .../java/org/apache/james/mdn/MDNFactory.java   |  68 --
 .../org/apache/james/mdn/MDNFactoryTest.java    | 727 -------------------
 .../james/mdn/MDNReportFormattingTest.java      | 727 +++++++++++++++++++
 .../test/java/org/apache/james/mdn/MDNTest.java | 130 ++++
 .../transport/mailets/jsieve/RejectAction.java  |  35 +-
 7 files changed, 1009 insertions(+), 813 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/mdn/pom.xml
----------------------------------------------------------------------
diff --git a/mdn/pom.xml b/mdn/pom.xml
index 3094c9d..7eb7d4b 100644
--- a/mdn/pom.xml
+++ b/mdn/pom.xml
@@ -34,8 +34,12 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.james</groupId>
-            <artifactId>apache-mailet-base</artifactId>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
         </dependency>
         <dependency>
             <groupId>junit</groupId>

http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/mdn/src/main/java/org/apache/james/mdn/MDN.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDN.java b/mdn/src/main/java/org/apache/james/mdn/MDN.java
new file mode 100644
index 0000000..06f6ebb
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/MDN.java
@@ -0,0 +1,127 @@
+/****************************************************************
+ * 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.mdn;
+
+import java.util.Objects;
+import java.util.Properties;
+
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+
+public class MDN {
+    public static class Builder {
+        private String humanReadableText;
+        private MDNReport report;
+
+        public Builder report(MDNReport report) {
+            Preconditions.checkNotNull(report);
+            this.report = report;
+            return this;
+        }
+
+        public Builder humanReadableText(String humanReadableText) {
+            Preconditions.checkNotNull(humanReadableText);
+            this.humanReadableText = humanReadableText;
+            return this;
+        }
+
+        public MDN build() {
+            Preconditions.checkState(report != null);
+            Preconditions.checkState(humanReadableText != null);
+            return new MDN(humanReadableText, report);
+        }
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    private final String humanReadableText;
+    private final MDNReport report;
+
+    public MDN(String humanReadableText, MDNReport report) {
+        this.humanReadableText = humanReadableText;
+        this.report = report;
+    }
+
+    public String getHumanReadableText() {
+        return humanReadableText;
+    }
+
+    public MDNReport getReport() {
+        return report;
+    }
+
+    public MimeMultipart asMultipart() throws MessagingException {
+        MimeMultipart multipart = new MimeMultipart();
+        multipart.setSubType("report");
+        multipart.addBodyPart(computeHumanReadablePart());
+        multipart.addBodyPart(computeReportPart());
+        // The optional third part, the original message is omitted.
+        // We don't want to propogate over-sized, virus infected or
+        // other undesirable mail!
+        // There is the option of adding a Text/RFC822-Headers part, which
+        // includes only the RFC 822 headers of the failed message. This is
+        // described in RFC 1892. It would be a useful addition!
+        return multipart;
+    }
+
+    public MimeMessage asMimeMessage() throws MessagingException {
+        MimeMessage mimeMessage = new MimeMessage(Session.getDefaultInstance(new Properties()));
+        mimeMessage.setContent(asMultipart());
+        return mimeMessage;
+    }
+
+    public BodyPart computeHumanReadablePart() throws MessagingException {
+        MimeBodyPart textPart = new MimeBodyPart();
+        textPart.setText(humanReadableText, Charsets.UTF_8.displayName());
+        textPart.setDisposition(MimeMessage.INLINE);
+        return textPart;
+    }
+
+    public BodyPart computeReportPart() throws MessagingException {
+        MimeBodyPart mdnPart = new MimeBodyPart();
+        mdnPart.setContent(report.formattedValue(), "message/disposition-notification");
+        return mdnPart;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof MDN) {
+            MDN mdn = (MDN) o;
+
+            return Objects.equals(this.humanReadableText, mdn.humanReadableText)
+                && Objects.equals(this.report, mdn.report);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(humanReadableText, report);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java b/mdn/src/main/java/org/apache/james/mdn/MDNFactory.java
deleted file mode 100644
index 57ff29a..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/MDNFactory.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.james.mdn;
-
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeBodyPart;
-
-import org.apache.mailet.base.mail.MimeMultipartReport;
-
-/**
- * Class <code>MDNFactory</code> creates MimeMultipartReports containing
- * Message Delivery Notifications as specified by RFC 2298.
- */
-public class MDNFactory {
-    
-    /**
-     * Answers a MimeMultipartReport containing a
-     * Message Delivery Notification as specified by RFC 2298.
-     * 
-     * @param humanText
-     * @param mdnReport
-     * @return MimeMultipartReport
-     * @throws MessagingException
-     */
-    public static MimeMultipartReport create(String humanText,
-            MDNReport mdnReport) throws MessagingException {
-        // Create the message parts. According to RFC 2298, there are two
-        // compulsory parts and one optional part...
-        MimeMultipartReport multiPart = new MimeMultipartReport();
-        multiPart.setReportType("disposition-notification");
-        
-        // Part 1: The 'human-readable' part
-        MimeBodyPart humanPart = new MimeBodyPart();
-        humanPart.setText(humanText);
-        multiPart.addBodyPart(humanPart);
-
-        // Part 2: MDN Report Part
-        MimeBodyPart mdnPart = new MimeBodyPart();
-        mdnPart.setContent(mdnReport.formattedValue(), "message/disposition-notification");
-        multiPart.addBodyPart(mdnPart);
-
-        // Part 3: The optional third part, the original message is omitted.
-        // We don't want to propogate over-sized, virus infected or
-        // other undesirable mail!
-        // There is the option of adding a Text/RFC822-Headers part, which
-        // includes only the RFC 822 headers of the failed message. This is
-        // described in RFC 1892. It would be a useful addition!        
-        return multiPart;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
deleted file mode 100644
index eaad55c..0000000
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ /dev/null
@@ -1,727 +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.mdn;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.apache.james.mdn.action.mode.DispositionActionMode;
-import org.apache.james.mdn.fields.Disposition;
-import org.apache.james.mdn.fields.Error;
-import org.apache.james.mdn.fields.ExtensionField;
-import org.apache.james.mdn.fields.FinalRecipient;
-import org.apache.james.mdn.fields.Gateway;
-import org.apache.james.mdn.fields.OriginalMessageId;
-import org.apache.james.mdn.fields.OriginalRecipient;
-import org.apache.james.mdn.fields.ReportingUserAgent;
-import org.apache.james.mdn.fields.Text;
-import org.apache.james.mdn.modifier.DispositionModifier;
-import org.apache.james.mdn.sending.mode.DispositionSendingMode;
-import org.apache.james.mdn.type.DispositionType;
-import org.junit.Test;
-
-public class MDNFactoryTest {
-
-    @Test
-    public void generateMDNReportShouldFormatAutomaticActions() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatManualActions() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatTypeDispatcher() {
-        Disposition disposition = Disposition.builder()
-        .actionMode(DispositionActionMode.Manual)
-        .sendingMode(DispositionSendingMode.Manual)
-        .type(DispositionType.Dispatched)
-        .addModifier(DispositionModifier.Error)
-        .addModifier(DispositionModifier.Failed)
-        .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;dispatched/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatTypeDisplayed() {
-        Disposition disposition = Disposition.builder()
-        .actionMode(DispositionActionMode.Manual)
-        .sendingMode(DispositionSendingMode.Manual)
-        .type(DispositionType.Displayed)
-        .addModifier(DispositionModifier.Error)
-        .addModifier(DispositionModifier.Failed)
-        .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;displayed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatTypeDeleted() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatAllModifier() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Deleted)
-            .addModifiers(DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
-                DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/error,expired,failed,mailbox-terminated,superseded,warning\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatOneModifier() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/error\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatUnknownModifier() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Deleted)
-            .addModifier(new DispositionModifier("new"))
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/new\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatNoModifier() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Deleted)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatNullUserAgentProduct() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent("UA_name"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; \r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatNullOriginalRecipient() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatWhenMissingOriginalMessageId() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatGateway() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .gatewayField(new Gateway(Text.fromRawText("host.com")))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "MDN-Gateway: dns;host.com\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatGatewayWithExoticNameType() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .gatewayField(new Gateway("postal", Text.fromRawText("5 rue Charles mercier")))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "MDN-Gateway: postal;5 rue Charles mercier\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatExoticAddressTypeForOriginalRecipient() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient("roomNumber", Text.fromRawText("385")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: roomNumber; 385\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatMultilineAddresses() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .gatewayField(new Gateway("postal", Text.fromRawText("8 rue Charles mercier\n 36555 Saint Coincoin\n France")))
-            .finalRecipientField(new FinalRecipient("postal", Text.fromRawText("5 rue Mercier\n 36555 Saint Coincoin\n France")))
-            .originalRecipientField(new OriginalRecipient("postal", Text.fromRawText("3 rue Mercier\n 36555 Saint Coincoin\n France")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "MDN-Gateway: postal;8 rue Charles mercier\r\n" +
-                " 36555 Saint Coincoin\r\n" +
-                " France\r\n" +
-                "Original-Recipient: postal; 3 rue Mercier\r\n" +
-                " 36555 Saint Coincoin\r\n" +
-                " France\r\n" +
-                "Final-Recipient: postal; 5 rue Mercier\r\n" +
-                " 36555 Saint Coincoin\r\n" +
-                " France\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatUnknownAddressTypeForOriginalRecipient() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(OriginalRecipient.ofUnknown(Text.fromRawText("#$%*")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: unknown; #$%*\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatExoticFinalRecipientAddressType() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient("roomNumber", Text.fromRawText("781")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: roomNumber; 781\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatErrorField() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .addErrorField(new Error(Text.fromRawText("An error message")))
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
-                "Error: An error message\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatErrorFields() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .addErrorFields(
-                new Error(Text.fromRawText("An error message")),
-                new Error(Text.fromRawText("A second error message")))
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
-                "Error: An error message\r\n" +
-                "Error: A second error message\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatErrorFieldsOnSeveralLines() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .addErrorField(new Error(Text.fromRawText("An error message\non several lines")))
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
-                "Error: An error message\r\n" +
-                " on several lines\r\n");
-    }
-
-    @Test
-    public void generateMDNReportShouldFormatOneExtension() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-         .withExtensionField(new ExtensionField("X-OPENPAAS-IP", "177.177.177.77"))
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
-                "X-OPENPAAS-IP: 177.177.177.77\r\n");
-    }
-
-
-    @Test
-    public void generateMDNReportShouldFormatManyExtensions() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Automatic)
-            .sendingMode(DispositionSendingMode.Automatic)
-            .type(DispositionType.Processed)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                "UA_product"))
-            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .withExtensionFields(
-                new ExtensionField("X-OPENPAAS-IP", "177.177.177.77"),
-                new ExtensionField("X-OPENPAAS-PORT", "8000"))
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recipient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
-                "X-OPENPAAS-IP: 177.177.177.77\r\n" +
-                "X-OPENPAAS-PORT: 8000\r\n");
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
new file mode 100644
index 0000000..8168915
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
@@ -0,0 +1,727 @@
+/****************************************************************
+ * 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.mdn;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.fields.Error;
+import org.apache.james.mdn.fields.ExtensionField;
+import org.apache.james.mdn.fields.FinalRecipient;
+import org.apache.james.mdn.fields.Gateway;
+import org.apache.james.mdn.fields.OriginalMessageId;
+import org.apache.james.mdn.fields.OriginalRecipient;
+import org.apache.james.mdn.fields.ReportingUserAgent;
+import org.apache.james.mdn.fields.Text;
+import org.apache.james.mdn.modifier.DispositionModifier;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
+import org.junit.Test;
+
+public class MDNReportFormattingTest {
+
+    @Test
+    public void generateMDNReportShouldFormatAutomaticActions() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatManualActions() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDispatcher() {
+        Disposition disposition = Disposition.builder()
+        .actionMode(DispositionActionMode.Manual)
+        .sendingMode(DispositionSendingMode.Manual)
+        .type(DispositionType.Dispatched)
+        .addModifier(DispositionModifier.Error)
+        .addModifier(DispositionModifier.Failed)
+        .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;dispatched/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDisplayed() {
+        Disposition disposition = Disposition.builder()
+        .actionMode(DispositionActionMode.Manual)
+        .sendingMode(DispositionSendingMode.Manual)
+        .type(DispositionType.Displayed)
+        .addModifier(DispositionModifier.Error)
+        .addModifier(DispositionModifier.Failed)
+        .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;displayed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatTypeDeleted() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatAllModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifiers(DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
+                DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/error,expired,failed,mailbox-terminated,superseded,warning\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatOneModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/error\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatUnknownModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .addModifier(new DispositionModifier("new"))
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted/new\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNoModifier() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Manual)
+            .type(DispositionType.Deleted)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-manually;deleted\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullUserAgentProduct() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent("UA_name"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; \r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatNullOriginalRecipient() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatWhenMissingOriginalMessageId() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Manual)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Disposition: manual-action/MDN-sent-automatically;deleted/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatGateway() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .gatewayField(new Gateway(Text.fromRawText("host.com")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: dns;host.com\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatGatewayWithExoticNameType() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .gatewayField(new Gateway("postal", Text.fromRawText("5 rue Charles mercier")))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: postal;5 rue Charles mercier\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatExoticAddressTypeForOriginalRecipient() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient("roomNumber", Text.fromRawText("385")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: roomNumber; 385\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatMultilineAddresses() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .gatewayField(new Gateway("postal", Text.fromRawText("8 rue Charles mercier\n 36555 Saint Coincoin\n France")))
+            .finalRecipientField(new FinalRecipient("postal", Text.fromRawText("5 rue Mercier\n 36555 Saint Coincoin\n France")))
+            .originalRecipientField(new OriginalRecipient("postal", Text.fromRawText("3 rue Mercier\n 36555 Saint Coincoin\n France")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "MDN-Gateway: postal;8 rue Charles mercier\r\n" +
+                " 36555 Saint Coincoin\r\n" +
+                " France\r\n" +
+                "Original-Recipient: postal; 3 rue Mercier\r\n" +
+                " 36555 Saint Coincoin\r\n" +
+                " France\r\n" +
+                "Final-Recipient: postal; 5 rue Mercier\r\n" +
+                " 36555 Saint Coincoin\r\n" +
+                " France\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatUnknownAddressTypeForOriginalRecipient() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(OriginalRecipient.ofUnknown(Text.fromRawText("#$%*")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: unknown; #$%*\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatExoticFinalRecipientAddressType() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient("roomNumber", Text.fromRawText("781")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: roomNumber; 781\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatErrorField() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .addErrorField(new Error(Text.fromRawText("An error message")))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "Error: An error message\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatErrorFields() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .addErrorFields(
+                new Error(Text.fromRawText("An error message")),
+                new Error(Text.fromRawText("A second error message")))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "Error: An error message\r\n" +
+                "Error: A second error message\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatErrorFieldsOnSeveralLines() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .addErrorField(new Error(Text.fromRawText("An error message\non several lines")))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "Error: An error message\r\n" +
+                " on several lines\r\n");
+    }
+
+    @Test
+    public void generateMDNReportShouldFormatOneExtension() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+         .withExtensionField(new ExtensionField("X-OPENPAAS-IP", "177.177.177.77"))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "X-OPENPAAS-IP: 177.177.177.77\r\n");
+    }
+
+
+    @Test
+    public void generateMDNReportShouldFormatManyExtensions() {
+        Disposition disposition = Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Processed)
+            .addModifier(DispositionModifier.Error)
+            .addModifier(DispositionModifier.Failed)
+            .build();
+
+        String report = MDNReport.builder()
+            .reportingUserAgentField(new ReportingUserAgent(
+                "UA_name",
+                "UA_product"))
+            .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
+            .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
+            .originalMessageIdField(new OriginalMessageId("original_message_id"))
+            .dispositionField(disposition)
+            .withExtensionFields(
+                new ExtensionField("X-OPENPAAS-IP", "177.177.177.77"),
+                new ExtensionField("X-OPENPAAS-PORT", "8000"))
+            .build()
+            .formattedValue();
+
+        assertThat(report)
+            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
+                "Original-Recipient: rfc822; originalRecipient\r\n" +
+                "Final-Recipient: rfc822; final_recipient\r\n" +
+                "Original-Message-ID: original_message_id\r\n" +
+                "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed\r\n" +
+                "X-OPENPAAS-IP: 177.177.177.77\r\n" +
+                "X-OPENPAAS-PORT: 8000\r\n");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1f443cd1/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
new file mode 100644
index 0000000..cf8b522
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
@@ -0,0 +1,130 @@
+/****************************************************************
+ * 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.mdn;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.mail.internet.MimeMessage;
+
+import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.fields.Disposition;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import com.google.common.base.Charsets;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class MDNTest {
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(MDN.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void asMimeMessageShouldComportExplanationPartAndReportPart() throws Exception {
+        MimeMessage mimeMessage = MDN.builder()
+            .humanReadableText("Explanation")
+            .report(MDNReport.builder()
+                .finalRecipientField("final@domain.com")
+                .dispositionField(Disposition.builder()
+                    .actionMode(DispositionActionMode.Automatic)
+                    .sendingMode(DispositionSendingMode.Automatic)
+                    .type(DispositionType.Deleted)
+                    .build())
+                .build())
+            .build()
+            .asMimeMessage();
+
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        mimeMessage.writeTo(byteArrayOutputStream);
+        assertThat(new String(byteArrayOutputStream.toByteArray(), Charsets.UTF_8))
+            .contains(
+                "Content-Type: text/plain; charset=UTF-8\r\n" +
+                "Content-Transfer-Encoding: 7bit\r\n" +
+                "Content-Disposition: inline\r\n" +
+                "\r\n" +
+                "Explanation")
+            .contains(
+                "Content-Type: message/disposition-notification\r\n" +
+                    "Content-Transfer-Encoding: 7bit\r\n" +
+                    "\r\n" +
+                    "Final-Recipient: rfc822; final@domain.com\r\n" +
+                    "Disposition: automatic-action/MDN-sent-automatically;deleted");
+    }
+
+    @Test
+    public void asMimeMessageShouldDisplayEmptyExplanation() throws Exception {
+        MimeMessage mimeMessage = MDN.builder()
+            .humanReadableText("")
+            .report(MDNReport.builder()
+                .finalRecipientField("final@domain.com")
+                .dispositionField(Disposition.builder()
+                    .actionMode(DispositionActionMode.Automatic)
+                    .sendingMode(DispositionSendingMode.Automatic)
+                    .type(DispositionType.Deleted)
+                    .build())
+                .build())
+            .build()
+            .asMimeMessage();
+
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        mimeMessage.writeTo(byteArrayOutputStream);
+        assertThat(new String(byteArrayOutputStream.toByteArray(), Charsets.UTF_8))
+            .contains(
+                "Content-Type: text/plain; charset=UTF-8\r\n" +
+                    "Content-Transfer-Encoding: 7bit\r\n" +
+                    "Content-Disposition: inline\r\n" +
+                    "\r\n")
+            .contains(
+                "Content-Type: message/disposition-notification\r\n" +
+                    "Content-Transfer-Encoding: 7bit\r\n" +
+                    "\r\n" +
+                    "Final-Recipient: rfc822; final@domain.com\r\n" +
+                    "Disposition: automatic-action/MDN-sent-automatically;deleted");
+    }
+
+    @Test
+    public void reportShouldThrowOnNullValue() {
+        expectedException.expect(NullPointerException.class);
+
+        MDN.builder()
+            .report(null);
+    }
+
+    @Test
+    public void humanReadableTextShouldThrowOnNullValue() {
+        expectedException.expect(NullPointerException.class);
+
+        MDN.builder()
+            .humanReadableText(null);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[08/27] james-project git commit: JAMES-2132 Rely on enumerations for MDN fields

Posted by bt...@apache.org.
JAMES-2132 Rely on enumerations for MDN fields


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/3d8120e9
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/3d8120e9
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/3d8120e9

Branch: refs/heads/master
Commit: 3d8120e94e98c3e61f2a6af4874d387970547790
Parents: 811b847
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 11:05:21 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:19 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/Disposition.java  |  8 +-
 .../mdn/action/mode/ActionModeAutomatic.java    | 42 ----------
 .../james/mdn/action/mode/ActionModeManual.java | 47 -----------
 .../mdn/action/mode/DispositionActionMode.java  | 23 +++++-
 .../james/mdn/modifier/DispositionModifier.java | 27 ++++++-
 .../james/mdn/modifier/ModifierError.java       | 44 -----------
 .../james/mdn/modifier/ModifierExpired.java     | 45 -----------
 .../james/mdn/modifier/ModifierFailed.java      | 45 -----------
 .../mdn/modifier/ModifierMailboxTerminated.java | 45 -----------
 .../james/mdn/modifier/ModifierSuperseded.java  | 45 -----------
 .../james/mdn/modifier/ModifierWarning.java     | 45 -----------
 .../sending/mode/DispositionSendingMode.java    | 23 +++++-
 .../mdn/sending/mode/SendingModeAutomatic.java  | 45 -----------
 .../mdn/sending/mode/SendingModeManual.java     | 45 -----------
 .../apache/james/mdn/type/DispositionType.java  | 27 ++++++-
 .../org/apache/james/mdn/type/TypeDeleted.java  | 45 -----------
 .../org/apache/james/mdn/type/TypeDenied.java   | 44 -----------
 .../apache/james/mdn/type/TypeDispatched.java   | 43 ----------
 .../apache/james/mdn/type/TypeDisplayed.java    | 44 -----------
 .../org/apache/james/mdn/type/TypeFailed.java   | 44 -----------
 .../apache/james/mdn/type/TypeProcessed.java    | 44 -----------
 .../org/apache/james/mdn/MDNFactoryTest.java    | 82 ++++++++------------
 .../transport/mailets/jsieve/RejectAction.java  | 13 ++--
 23 files changed, 135 insertions(+), 780 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/Disposition.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/Disposition.java b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
index 9fcc8a5..381376f 100644
--- a/mdn/src/main/java/org/apache/james/mdn/Disposition.java
+++ b/mdn/src/main/java/org/apache/james/mdn/Disposition.java
@@ -140,11 +140,11 @@ public class Disposition
     {
         StringBuilder builder = new StringBuilder(64);
         builder.append("Disposition: ");
-        builder.append(getActionMode() == null ? "" : getActionMode().toString());
+        builder.append(getActionMode() == null ? "" : getActionMode().getValue());
         builder.append('/');
-        builder.append(getSendingMode() == null ? "" : getSendingMode().toString());
+        builder.append(getSendingMode() == null ? "" : getSendingMode().getValue());
         builder.append(';');
-        builder.append(getDispositionType() == null ? "" : getDispositionType().toString());
+        builder.append(getDispositionType() == null ? "" : getDispositionType().getValue());
         if (null != getDispositionModifiers()
                 && getDispositionModifiers().length > 0)
         {
@@ -153,7 +153,7 @@ public class Disposition
             {
                 if (i > 0)
                     builder.append(',');
-                builder.append(getDispositionModifiers()[i]);
+                builder.append(getDispositionModifiers()[i].getValue());
             }
         }
         return builder.toString();

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java
deleted file mode 100644
index d4b4459..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeAutomatic.java
+++ /dev/null
@@ -1,42 +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.mdn.action.mode;
-
-
-/**
- * Class <code>ActionModeAutomatic</code>
- */
-public class ActionModeAutomatic implements DispositionActionMode {
-
-    /**
-     * Default Constructor
-     */
-    public ActionModeAutomatic() {
-        super();
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return "automatic-action";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java
deleted file mode 100644
index 1a2a7b7..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/action/mode/ActionModeManual.java
+++ /dev/null
@@ -1,47 +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.mdn.action.mode;
-
-
-/**
- * Class <code>ActionModeManual</code>
- */
-public class ActionModeManual
-        implements
-            DispositionActionMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public ActionModeManual()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "manual-action";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java b/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
index b855e08..6becee0 100644
--- a/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
+++ b/mdn/src/main/java/org/apache/james/mdn/action/mode/DispositionActionMode.java
@@ -19,11 +19,30 @@
 
 package org.apache.james.mdn.action.mode;
 
+import java.util.Optional;
+import java.util.stream.Stream;
+
 /**
  * Interface <code>DispositionActionMode</code> marks a type encapsulating
  * disposition action mode information as defined by RFC 2298.
  */
-public interface DispositionActionMode
-{
+public enum DispositionActionMode {
+    Manual("manual-action"),
+    Automatic("automatic-action");
+
+    public static Optional<DispositionActionMode> fromString(String value) {
+        return Stream.of(values())
+            .filter(actionMode -> actionMode.getValue().equalsIgnoreCase(value))
+            .findFirst();
+    }
+
+    private final String value;
+
+    DispositionActionMode(String value) {
+        this.value = value;
+    }
 
+    public String getValue() {
+        return value;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
index 66ab46a..1efb7d0 100644
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
@@ -19,11 +19,34 @@
 
 package org.apache.james.mdn.modifier;
 
+import java.util.Optional;
+import java.util.stream.Stream;
+
 /**
  * Interface <code>DispositionModifier</code> marks a type encapsulating
  * disposition modifier information as defined by RFC 2298.
  */
-public interface DispositionModifier
-{
+public enum DispositionModifier {
+    Error("error"),
+    Expired("expired"),
+    Failed("failed"),
+    MailboxTerminated("mailbox-terminated"),
+    Superseded("superseded"),
+    Warning("warning");
+
+    public static Optional<DispositionModifier> fromString(String value) {
+        return Stream.of(values())
+            .filter(sendingMode -> sendingMode.getValue().equalsIgnoreCase(value))
+            .findFirst();
+    }
+
+    private final String value;
+
+    DispositionModifier(String value) {
+        this.value = value;
+    }
 
+    public String getValue() {
+        return value;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java
deleted file mode 100644
index 2a6feed..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierError.java
+++ /dev/null
@@ -1,44 +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.mdn.modifier;
-
-
-/**
- * Class <code>ModifierError</code>
- */
-public class ModifierError implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierError()
-    {
-        super();
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "error";
-    }
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java
deleted file mode 100644
index 9a73b0e..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierExpired.java
+++ /dev/null
@@ -1,45 +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.mdn.modifier;
-
-
-/**
- * Class <code>ModifierExpired</code>
- */    
-public class ModifierExpired implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierExpired()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "expired";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java
deleted file mode 100644
index 53edbe2..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierFailed.java
+++ /dev/null
@@ -1,45 +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.mdn.modifier;
-
-
-/**
- * Class <code>ModifierFailed</code>
- */    
-public class ModifierFailed implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierFailed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "failed";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java
deleted file mode 100644
index b2c6ade..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierMailboxTerminated.java
+++ /dev/null
@@ -1,45 +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.mdn.modifier;
-
-
-/**
- * Class <code>ModifierMailboxTerminated</code>
- */    
-public class ModifierMailboxTerminated implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierMailboxTerminated()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "mailbox-terminated";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java
deleted file mode 100644
index 11786f9..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierSuperseded.java
+++ /dev/null
@@ -1,45 +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.mdn.modifier;
-
-
-/**
- * Class <code>ModifierSuperseded</code>
- */    
-public class ModifierSuperseded implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierSuperseded()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "superseded";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java b/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java
deleted file mode 100644
index de8d1c6..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/ModifierWarning.java
+++ /dev/null
@@ -1,45 +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.mdn.modifier;
-
-
-/**
- * Class <code>ModifierWarning</code>
- */    
-public class ModifierWarning implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierWarning()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "warning";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
index 741c661..99e63c1 100644
--- a/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
+++ b/mdn/src/main/java/org/apache/james/mdn/sending/mode/DispositionSendingMode.java
@@ -19,11 +19,30 @@
 
 package org.apache.james.mdn.sending.mode;
 
+import java.util.Optional;
+import java.util.stream.Stream;
+
 /**
  * Interface <code>DispositionSendingMode</code> marks a type encapsulating
  * disposition sending mode information as defined by RFC 2298.
  */
-public interface DispositionSendingMode
-{
+public enum DispositionSendingMode {
+    Manual("MDN-sent-manually"),
+    Automatic("MDN-sent-automatically");
+
+    public static Optional<DispositionSendingMode> fromString(String value) {
+        return Stream.of(values())
+            .filter(sendingMode -> sendingMode.getValue().equalsIgnoreCase(value))
+            .findFirst();
+    }
+
+    private final String value;
+
+    DispositionSendingMode(String value) {
+        this.value = value;
+    }
 
+    public String getValue() {
+        return value;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java
deleted file mode 100644
index f847007..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeAutomatic.java
+++ /dev/null
@@ -1,45 +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.mdn.sending.mode;
-
-
-/**
- * Class <code>SendingModeAutomatic</code>
- */
-public class SendingModeAutomatic implements DispositionSendingMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public SendingModeAutomatic()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "MDN-sent-automatically";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java b/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java
deleted file mode 100644
index 1087082..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/sending/mode/SendingModeManual.java
+++ /dev/null
@@ -1,45 +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.mdn.sending.mode;
-
-
-/**
- * Class <code>SendingModeManual</code>
- */
-public class SendingModeManual implements DispositionSendingMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public SendingModeManual()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "MDN-sent-manually";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
index c02ba2e..2ce39b9 100644
--- a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
+++ b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
@@ -19,11 +19,34 @@
 
 package org.apache.james.mdn.type;
 
+import java.util.Optional;
+import java.util.stream.Stream;
+
 /**
  * Interface <code>DispositionType</code> marks a type encapsulating
  * disposition type information as defined by RFC 2298.
  */
-public interface DispositionType
-{
+public enum DispositionType {
+    Deleted("deleted"),
+    Denied("denied"),
+    Dispatched("dispatched"),
+    Displayed("displayed"),
+    Failed("failed"),
+    Processed("processed");
+
+    public static Optional<DispositionType> fromString(String value) {
+        return Stream.of(values())
+            .filter(sendingMode -> sendingMode.getValue().equalsIgnoreCase(value))
+            .findFirst();
+    }
+
+    private final String value;
+
+    DispositionType(String value) {
+        this.value = value;
+    }
 
+    public String getValue() {
+        return value;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java
deleted file mode 100644
index 028e644..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/type/TypeDeleted.java
+++ /dev/null
@@ -1,45 +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.mdn.type;
-
-
-/**
- * Class <code>TypeDeleted</code>
- */
-public class TypeDeleted implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDeleted()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "deleted";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java
deleted file mode 100644
index 3430f65..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/type/TypeDenied.java
+++ /dev/null
@@ -1,44 +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.mdn.type;
-
-
-/**
- * Class <code>TypeDenied</code>
- */    
-public class TypeDenied implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDenied()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "denied";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java
deleted file mode 100644
index 5bf9190..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/type/TypeDispatched.java
+++ /dev/null
@@ -1,43 +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.mdn.type;
-
-
-/**
- * Class <code>TypeDispatched</code>
- */
-public class TypeDispatched implements DispositionType
-{
-    /**
-     * Default Constructor
-     */
-    public TypeDispatched()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "dispatched";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java
deleted file mode 100644
index 48e9323..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/type/TypeDisplayed.java
+++ /dev/null
@@ -1,44 +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.mdn.type;
-
-
-/**
- * Class <code>TypeDisplayed</code>
- */
-public class TypeDisplayed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDisplayed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "displayed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java
deleted file mode 100644
index 067c892..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/type/TypeFailed.java
+++ /dev/null
@@ -1,44 +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.mdn.type;
-
-
-/**
- * Class <code>TypeFailed</code>
- */    
-public class TypeFailed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeFailed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "failed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java b/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java
deleted file mode 100644
index ed1895b..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/type/TypeProcessed.java
+++ /dev/null
@@ -1,44 +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.mdn.type;
-
-
-/**
- * Class <code>TypeProcessed</code>
- */    
-public class TypeProcessed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeProcessed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "processed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 18337c6..5272252 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -21,26 +21,10 @@ package org.apache.james.mdn;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.james.mdn.action.mode.ActionModeAutomatic;
-import org.apache.james.mdn.action.mode.ActionModeManual;
 import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.modifier.DispositionModifier;
-import org.apache.james.mdn.modifier.ModifierError;
-import org.apache.james.mdn.modifier.ModifierExpired;
-import org.apache.james.mdn.modifier.ModifierFailed;
-import org.apache.james.mdn.modifier.ModifierMailboxTerminated;
-import org.apache.james.mdn.modifier.ModifierSuperseded;
-import org.apache.james.mdn.modifier.ModifierWarning;
 import org.apache.james.mdn.sending.mode.DispositionSendingMode;
-import org.apache.james.mdn.sending.mode.SendingModeAutomatic;
-import org.apache.james.mdn.sending.mode.SendingModeManual;
 import org.apache.james.mdn.type.DispositionType;
-import org.apache.james.mdn.type.TypeDeleted;
-import org.apache.james.mdn.type.TypeDenied;
-import org.apache.james.mdn.type.TypeDispatched;
-import org.apache.james.mdn.type.TypeDisplayed;
-import org.apache.james.mdn.type.TypeFailed;
-import org.apache.james.mdn.type.TypeProcessed;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -52,8 +36,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatAutomaticActions() {
-        Disposition disposition = new Disposition(new ActionModeAutomatic(), new SendingModeAutomatic(), new TypeProcessed());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Automatic, DispositionSendingMode.Automatic, DispositionType.Processed);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -69,8 +53,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatManualActions() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeProcessed());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Processed);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -86,8 +70,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDenied() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDenied());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Denied);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -103,8 +87,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDispatcher() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDispatched());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Dispatched);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -120,8 +104,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDisplayed() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDisplayed());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Displayed);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -137,8 +121,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeFailed() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeFailed());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Failed);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -154,8 +138,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatTypeDeleted() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -171,9 +155,9 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatAllModifier() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierExpired(), new ModifierFailed(),
-            new ModifierMailboxTerminated(), new ModifierSuperseded(), new ModifierWarning()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
+            DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -189,7 +173,7 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNoModifier() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), new TypeDeleted());
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, DispositionType.Deleted);
         DispositionModifier[] dispostionModifiers = {};
         disposition.setDispositionModifiers(dispostionModifiers);
 
@@ -207,7 +191,7 @@ public class MDNFactoryTest {
     @Test
     public void generateMDNReportShouldFormatNoModifierNullType() {
         DispositionType type = null;
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeManual(), type);
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Manual, type);
         DispositionModifier[] dispostionModifiers = {};
         disposition.setDispositionModifiers(dispostionModifiers);
 
@@ -225,8 +209,8 @@ public class MDNFactoryTest {
     @Test
     public void generateMDNReportShouldFormatNullActionMode() {
         DispositionActionMode actionMode = null;
-        Disposition disposition = new Disposition(actionMode, new SendingModeManual(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(actionMode, DispositionSendingMode.Manual, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -243,8 +227,8 @@ public class MDNFactoryTest {
     @Test
     public void generateMDNReportShouldFormatNullSendingMode() {
         DispositionSendingMode sendingMode = null;
-        Disposition disposition = new Disposition(new ActionModeManual(), sendingMode, new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, sendingMode, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String report = MDNFactory.generateMDNReport("UA_name", "UA_product", "originalRecipient",
@@ -260,8 +244,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullUserAgentName() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String reporting_ua_name = null;
@@ -278,8 +262,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullUserAgentProduct() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String reporting_ua_product = null;
@@ -296,8 +280,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullOriginalRecipient() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String original_recipient = null;
@@ -313,8 +297,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullFinalRecipient() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String final_recipient = null;
@@ -331,8 +315,8 @@ public class MDNFactoryTest {
 
     @Test
     public void generateMDNReportShouldFormatNullOriginalMessageId() {
-        Disposition disposition = new Disposition(new ActionModeManual(), new SendingModeAutomatic(), new TypeDeleted());
-        DispositionModifier[] dispostionModifiers = {new ModifierError(), new ModifierFailed()};
+        Disposition disposition = new Disposition(DispositionActionMode.Manual, DispositionSendingMode.Automatic, DispositionType.Deleted);
+        DispositionModifier[] dispostionModifiers = {DispositionModifier.Error, DispositionModifier.Failed};
         disposition.setDispositionModifiers(dispostionModifiers);
 
         String original_message_id = null;

http://git-wip-us.apache.org/repos/asf/james-project/blob/3d8120e9/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
index c2ee308..d206303 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/RejectAction.java
@@ -31,11 +31,10 @@ import javax.mail.internet.MimeMultipart;
 
 import org.apache.james.mdn.Disposition;
 import org.apache.james.mdn.MDNFactory;
-import org.apache.james.mdn.action.mode.ActionModeAutomatic;
+import org.apache.james.mdn.action.mode.DispositionActionMode;
 import org.apache.james.mdn.modifier.DispositionModifier;
-import org.apache.james.mdn.modifier.ModifierError;
-import org.apache.james.mdn.sending.mode.SendingModeAutomatic;
-import org.apache.james.mdn.type.TypeDeleted;
+import org.apache.james.mdn.sending.mode.DispositionSendingMode;
+import org.apache.james.mdn.type.DispositionType;
 import org.apache.jsieve.mail.Action;
 import org.apache.jsieve.mail.ActionReject;
 import org.apache.mailet.Mail;
@@ -113,9 +112,9 @@ public class RejectAction implements MailAction {
 
         String original_message_id = aMail.getMessage().getMessageID();
 
-        DispositionModifier modifiers[] = {new ModifierError()};
-        Disposition disposition = new Disposition(new ActionModeAutomatic(),
-                new SendingModeAutomatic(), new TypeDeleted(), modifiers);
+        DispositionModifier modifiers[] = {DispositionModifier.Error};
+        Disposition disposition = new Disposition(DispositionActionMode.Automatic,
+                DispositionSendingMode.Automatic, DispositionType.Deleted, modifiers);
 
         MimeMultipart multiPart = MDNFactory.create(humanText.toString(),
                 reporting_UA_name, reporting_UA_product, original_recipient,


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[27/27] james-project git commit: JAMES-2132 Reject empty and folding white space values + trim where relevant

Posted by bt...@apache.org.
JAMES-2132 Reject empty and folding white space values + trim where relevant


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/8d9287ff
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/8d9287ff
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/8d9287ff

Branch: refs/heads/master
Commit: 8d9287ff92e6722e210227bbf52978d450374645
Parents: 599bec3
Author: benwa <bt...@linagora.com>
Authored: Thu Aug 31 09:26:06 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Fri Sep 1 08:16:14 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/mdn/Constants.java    | 24 -----
 mdn/src/main/java/org/apache/james/mdn/MDN.java |  4 +-
 .../apache/james/mdn/fields/AddressType.java    | 60 ++++++++++++
 .../apache/james/mdn/fields/FinalRecipient.java | 15 +--
 .../org/apache/james/mdn/fields/Gateway.java    | 12 +--
 .../james/mdn/fields/OriginalMessageId.java     |  4 +-
 .../james/mdn/fields/OriginalRecipient.java     | 16 ++--
 .../james/mdn/fields/ReportingUserAgent.java    | 11 ++-
 .../java/org/apache/james/mdn/fields/Text.java  |  5 +-
 .../james/mdn/modifier/DispositionModifier.java |  5 +-
 .../james/mdn/MDNReportFormattingTest.java      | 13 +--
 .../test/java/org/apache/james/mdn/MDNTest.java | 74 +++++++++++----
 .../james/mdn/fields/AddressTypeTest.java       | 99 ++++++++++++++++++++
 .../james/mdn/fields/FinalRecipientTest.java    | 17 +---
 .../apache/james/mdn/fields/GatewayTest.java    | 16 +---
 .../james/mdn/fields/OriginalMessageIdTest.java | 37 ++++++++
 .../james/mdn/fields/OriginalRecipientTest.java |  9 +-
 .../mdn/fields/ReportingUserAgentTest.java      | 64 +++++++++++++
 .../org/apache/james/mdn/fields/TextTest.java   |  6 +-
 .../mdn/modifier/DispositionModifierTest.java   | 28 ++++++
 20 files changed, 409 insertions(+), 110 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/Constants.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/Constants.java b/mdn/src/main/java/org/apache/james/mdn/Constants.java
deleted file mode 100644
index 5e07c00..0000000
--- a/mdn/src/main/java/org/apache/james/mdn/Constants.java
+++ /dev/null
@@ -1,24 +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.mdn;
-
-public interface Constants {
-    String RFC_822 = "rfc822";
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/MDN.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/MDN.java b/mdn/src/main/java/org/apache/james/mdn/MDN.java
index 06f6ebb..ad65f8c 100644
--- a/mdn/src/main/java/org/apache/james/mdn/MDN.java
+++ b/mdn/src/main/java/org/apache/james/mdn/MDN.java
@@ -52,6 +52,8 @@ public class MDN {
         public MDN build() {
             Preconditions.checkState(report != null);
             Preconditions.checkState(humanReadableText != null);
+            Preconditions.checkState(!humanReadableText.trim().isEmpty());
+
             return new MDN(humanReadableText, report);
         }
     }
@@ -63,7 +65,7 @@ public class MDN {
     private final String humanReadableText;
     private final MDNReport report;
 
-    public MDN(String humanReadableText, MDNReport report) {
+    private MDN(String humanReadableText, MDNReport report) {
         this.humanReadableText = humanReadableText;
         this.report = report;
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/AddressType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/AddressType.java b/mdn/src/main/java/org/apache/james/mdn/fields/AddressType.java
new file mode 100644
index 0000000..ccadbc4
--- /dev/null
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/AddressType.java
@@ -0,0 +1,60 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+
+public class AddressType {
+    public static final AddressType DNS = new AddressType("dns");
+    public static final AddressType RFC_822 = new AddressType("rfc822");
+    public static final AddressType UNKNOWN = new AddressType("unknown");
+
+    private final String type;
+
+    public AddressType(String type) {
+        Preconditions.checkNotNull(type);
+        Preconditions.checkArgument(!type.contains("\n"), "Address type can not be multiline");
+        String trimmedType = type.trim();
+        Preconditions.checkArgument(!trimmedType.isEmpty(), "Address type can not be empty");
+
+        this.type = trimmedType;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof AddressType) {
+            AddressType that = (AddressType) o;
+
+            return Objects.equals(this.type, that.type);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(type);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
index 8f87170..0775479 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/FinalRecipient.java
@@ -21,8 +21,6 @@ package org.apache.james.mdn.fields;
 
 import java.util.Objects;
 
-import org.apache.james.mdn.Constants;
-
 import com.google.common.base.Preconditions;
 
 /**
@@ -34,28 +32,31 @@ public class FinalRecipient implements Field {
     public static final String FIELD_NAME = "Final-Recipient";
 
     private final Text finalRecipient;
-    private final String addressType;
+    private final AddressType addressType;
 
-    public FinalRecipient(String addressType, Text finalRecipient) {
+    public FinalRecipient(AddressType addressType, Text finalRecipient) {
         Preconditions.checkNotNull(finalRecipient);
         Preconditions.checkNotNull(addressType);
-        Preconditions.checkArgument(!addressType.contains("\n"), "Address type can not be multiline");
 
         this.finalRecipient = finalRecipient;
         this.addressType = addressType;
     }
 
     public FinalRecipient(Text finalRecipient) {
-        this(Constants.RFC_822, finalRecipient);
+        this(AddressType.RFC_822, finalRecipient);
     }
 
     public Text getFinalRecipient() {
         return finalRecipient;
     }
 
+    public AddressType getAddressType() {
+        return addressType;
+    }
+
     @Override
     public String formattedValue() {
-        return FIELD_NAME + ": " + addressType + "; " + finalRecipient.formatted();
+        return FIELD_NAME + ": " + addressType.getType() + "; " + finalRecipient.formatted();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
index f11bc7a..c988b37 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Gateway.java
@@ -27,31 +27,29 @@ import com.google.common.base.Preconditions;
  * MDN-Gateway field as specified in https://tools.ietf.org/html/rfc8098#section-3.2.2
  */
 public class Gateway implements Field {
-    public static final String DNS = "dns";
     public static final String FIELD_NAME = "MDN-Gateway";
 
-    private final String nameType;
+    private final AddressType nameType;
     private final Text name;
 
-    public Gateway(String nameType, Text name) {
+    public Gateway(AddressType nameType, Text name) {
         Preconditions.checkNotNull(nameType);
         Preconditions.checkNotNull(name);
-        Preconditions.checkArgument(!nameType.contains("\n"));
 
         this.nameType = nameType;
         this.name = name;
     }
 
     public Gateway(Text name) {
-        this(DNS, name);
+        this(AddressType.DNS, name);
     }
 
     @Override
     public String formattedValue() {
-        return FIELD_NAME + ": " + nameType + ";" + name.formatted();
+        return FIELD_NAME + ": " + nameType.getType() + ";" + name.formatted();
     }
 
-    public String getNameType() {
+    public AddressType getNameType() {
         return nameType;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
index 8d0c6f1..45538bf 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalMessageId.java
@@ -35,8 +35,10 @@ public class OriginalMessageId implements Field {
     public OriginalMessageId(String originalMessageId) {
         Preconditions.checkNotNull(originalMessageId);
         Preconditions.checkArgument(!originalMessageId.contains("\n"));
+        String trimmedMessageId = originalMessageId.trim();
+        Preconditions.checkArgument(!trimmedMessageId.isEmpty());
 
-        this.originalMessageId = originalMessageId;
+        this.originalMessageId = trimmedMessageId;
     }
 
     public String getOriginalMessageId() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
index d1c7d33..c12a87f 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/OriginalRecipient.java
@@ -21,8 +21,6 @@ package org.apache.james.mdn.fields;
 
 import java.util.Objects;
 
-import org.apache.james.mdn.Constants;
-
 import com.google.common.base.Preconditions;
 
 /**
@@ -31,32 +29,32 @@ import com.google.common.base.Preconditions;
  * https://tools.ietf.org/html/rfc8098#section-3.2.3
  */
 public class OriginalRecipient implements Field {
-    private static final String UNKNOWN = "unknown";
     private static final String FIELD_NAME = "Original-Recipient";
 
     public static OriginalRecipient ofUnknown(Text address) {
-        return new OriginalRecipient(UNKNOWN, address);
+        return new OriginalRecipient(AddressType.UNKNOWN, address);
     }
 
     private final Text originalRecipient;
-    private final String addressType;
+    private final AddressType addressType;
 
-    public OriginalRecipient(String addressType, Text originalRecipient) {
+    public OriginalRecipient(AddressType addressType, Text originalRecipient) {
         Preconditions.checkNotNull(addressType);
         Preconditions.checkNotNull(originalRecipient);
+
         this.addressType = addressType;
         this.originalRecipient = originalRecipient;
     }
 
     public OriginalRecipient(Text originalRecipient) {
-        this(Constants.RFC_822, originalRecipient);
+        this(AddressType.RFC_822, originalRecipient);
     }
 
     public Text getOriginalRecipient() {
         return originalRecipient;
     }
 
-    public String getAddressType() {
+    public AddressType getAddressType() {
         return addressType;
     }
 
@@ -78,7 +76,7 @@ public class OriginalRecipient implements Field {
 
     @Override
     public String formattedValue() {
-        return FIELD_NAME + ": " + addressType + "; " + originalRecipient.formatted();
+        return FIELD_NAME + ": " + addressType.getType() + "; " + originalRecipient.formatted();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
index 62bc92b..f3c67fb 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/ReportingUserAgent.java
@@ -21,6 +21,7 @@ package org.apache.james.mdn.fields;
 
 import java.util.Objects;
 import java.util.Optional;
+import java.util.function.Predicate;
 
 import com.google.common.base.Preconditions;
 
@@ -31,6 +32,7 @@ import com.google.common.base.Preconditions;
  */
 public class ReportingUserAgent implements Field {
     private static final String FIELD_NAME = "Reporting-UA";
+    public static final Predicate<String> IS_EMPTY = String::isEmpty;
     private final String userAgentName;
     private final Optional<String> userAgentProduct;
 
@@ -45,9 +47,14 @@ public class ReportingUserAgent implements Field {
     public ReportingUserAgent(String userAgentName, Optional<String> userAgentProduct) {
         Preconditions.checkNotNull(userAgentName);
         Preconditions.checkNotNull(userAgentProduct);
+        Preconditions.checkArgument(!userAgentName.contains("\n"), "Name should not contain line break");
+        String trimmedName = userAgentName.trim();
+        Preconditions.checkArgument(!trimmedName.isEmpty(), "Name should not be empty");
 
-        this.userAgentName = userAgentName;
-        this.userAgentProduct = userAgentProduct;
+        this.userAgentName = trimmedName;
+        this.userAgentProduct = userAgentProduct
+            .map(String::trim)
+            .filter(IS_EMPTY.negate());
     }
 
     public String getUserAgentName() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/fields/Text.java b/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
index d3592cf..7c99b7d 100644
--- a/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
+++ b/mdn/src/main/java/org/apache/james/mdn/fields/Text.java
@@ -28,7 +28,10 @@ public class Text {
 
     public static Text fromRawText(String rawText) {
         Preconditions.checkNotNull(rawText);
-        return new Text(replaceLineBreaksByContinuation(rawText));
+        String trimmedText = rawText.trim();
+        Preconditions.checkArgument(!trimmedText.isEmpty(), "Text should not be empty");
+
+        return new Text(replaceLineBreaksByContinuation(trimmedText));
     }
 
     private static String replaceLineBreaksByContinuation(String rawText) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
index f7e9171..fec53fd 100644
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
@@ -42,7 +42,10 @@ public class DispositionModifier {
     public DispositionModifier(String value) {
         Preconditions.checkNotNull(value);
         Preconditions.checkArgument(!value.contains("\n"), "Multiline Disposition modifier are forbiden");
-        this.value = value;
+        String trimmedValue = value.trim();
+        Preconditions.checkArgument(!trimmedValue.isEmpty(), "Disposition modifier can not be empty");
+
+        this.value = trimmedValue;
     }
 
     public String getValue() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
index 8168915..3f1555e 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNReportFormattingTest.java
@@ -22,6 +22,7 @@ package org.apache.james.mdn;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.james.mdn.action.mode.DispositionActionMode;
+import org.apache.james.mdn.fields.AddressType;
 import org.apache.james.mdn.fields.Disposition;
 import org.apache.james.mdn.fields.Error;
 import org.apache.james.mdn.fields.ExtensionField;
@@ -421,7 +422,7 @@ public class MDNReportFormattingTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 "UA_product"))
-            .gatewayField(new Gateway("postal", Text.fromRawText("5 rue Charles mercier")))
+            .gatewayField(new Gateway(new AddressType("postal"), Text.fromRawText("5 rue Charles mercier")))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
@@ -453,7 +454,7 @@ public class MDNReportFormattingTest {
                 "UA_name",
                 "UA_product"))
             .finalRecipientField(new FinalRecipient(Text.fromRawText("final_recipient")))
-            .originalRecipientField(new OriginalRecipient("roomNumber", Text.fromRawText("385")))
+            .originalRecipientField(new OriginalRecipient(new AddressType("roomNumber"), Text.fromRawText("385")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -481,9 +482,9 @@ public class MDNReportFormattingTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 "UA_product"))
-            .gatewayField(new Gateway("postal", Text.fromRawText("8 rue Charles mercier\n 36555 Saint Coincoin\n France")))
-            .finalRecipientField(new FinalRecipient("postal", Text.fromRawText("5 rue Mercier\n 36555 Saint Coincoin\n France")))
-            .originalRecipientField(new OriginalRecipient("postal", Text.fromRawText("3 rue Mercier\n 36555 Saint Coincoin\n France")))
+            .gatewayField(new Gateway(new AddressType("postal"), Text.fromRawText("8 rue Charles mercier\n 36555 Saint Coincoin\n France")))
+            .finalRecipientField(new FinalRecipient(new AddressType("postal"), Text.fromRawText("5 rue Mercier\n 36555 Saint Coincoin\n France")))
+            .originalRecipientField(new OriginalRecipient(new AddressType("postal"), Text.fromRawText("3 rue Mercier\n 36555 Saint Coincoin\n France")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)
             .build()
@@ -547,7 +548,7 @@ public class MDNReportFormattingTest {
             .reportingUserAgentField(new ReportingUserAgent(
                 "UA_name",
                 "UA_product"))
-            .finalRecipientField(new FinalRecipient("roomNumber", Text.fromRawText("781")))
+            .finalRecipientField(new FinalRecipient(new AddressType("roomNumber"), Text.fromRawText("781")))
             .originalRecipientField(new OriginalRecipient(Text.fromRawText("originalRecipient")))
             .originalMessageIdField(new OriginalMessageId("original_message_id"))
             .dispositionField(disposition)

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
index cf8b522..2282e05 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNTest.java
@@ -39,6 +39,14 @@ import nl.jqno.equalsverifier.EqualsVerifier;
 
 public class MDNTest {
 
+    public static final MDNReport MINIMAL_REPORT = MDNReport.builder()
+        .finalRecipientField("final@domain.com")
+        .dispositionField(Disposition.builder()
+            .actionMode(DispositionActionMode.Automatic)
+            .sendingMode(DispositionSendingMode.Automatic)
+            .type(DispositionType.Deleted)
+            .build())
+        .build();
     @Rule
     public ExpectedException expectedException = ExpectedException.none();
 
@@ -53,14 +61,7 @@ public class MDNTest {
     public void asMimeMessageShouldComportExplanationPartAndReportPart() throws Exception {
         MimeMessage mimeMessage = MDN.builder()
             .humanReadableText("Explanation")
-            .report(MDNReport.builder()
-                .finalRecipientField("final@domain.com")
-                .dispositionField(Disposition.builder()
-                    .actionMode(DispositionActionMode.Automatic)
-                    .sendingMode(DispositionSendingMode.Automatic)
-                    .type(DispositionType.Deleted)
-                    .build())
-                .build())
+            .report(MINIMAL_REPORT)
             .build()
             .asMimeMessage();
 
@@ -84,15 +85,8 @@ public class MDNTest {
     @Test
     public void asMimeMessageShouldDisplayEmptyExplanation() throws Exception {
         MimeMessage mimeMessage = MDN.builder()
-            .humanReadableText("")
-            .report(MDNReport.builder()
-                .finalRecipientField("final@domain.com")
-                .dispositionField(Disposition.builder()
-                    .actionMode(DispositionActionMode.Automatic)
-                    .sendingMode(DispositionSendingMode.Automatic)
-                    .type(DispositionType.Deleted)
-                    .build())
-                .build())
+            .humanReadableText("Explanation")
+            .report(MINIMAL_REPORT)
             .build()
             .asMimeMessage();
 
@@ -103,7 +97,8 @@ public class MDNTest {
                 "Content-Type: text/plain; charset=UTF-8\r\n" +
                     "Content-Transfer-Encoding: 7bit\r\n" +
                     "Content-Disposition: inline\r\n" +
-                    "\r\n")
+                    "\r\n" +
+                    "Explanation")
             .contains(
                 "Content-Type: message/disposition-notification\r\n" +
                     "Content-Transfer-Encoding: 7bit\r\n" +
@@ -127,4 +122,47 @@ public class MDNTest {
         MDN.builder()
             .humanReadableText(null);
     }
+
+    @Test
+    public void buildShouldThrowOnEmptyHumanReadableText() {
+        expectedException.expect(IllegalStateException.class);
+
+        MDN.builder()
+            .humanReadableText("")
+            .report(MINIMAL_REPORT)
+            .build();
+    }
+
+    @Test
+    public void buildShouldThrowOnFoldingWhiteHumanReadableText() {
+        expectedException.expect(IllegalStateException.class);
+
+        MDN.builder()
+            .humanReadableText("  ")
+            .report(MINIMAL_REPORT)
+            .build();
+    }
+
+    @Test
+    public void humanReadableTextShouldNotBeTrimmed() throws Exception {
+        MimeMessage mimeMessage = MDN.builder()
+            .humanReadableText("Explanation:\n" +
+                " - We should always write detailed unit tests\n" +
+                " - We should think of all edge cases\n")
+            .report(MINIMAL_REPORT)
+            .build()
+            .asMimeMessage();
+
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        mimeMessage.writeTo(byteArrayOutputStream);
+        assertThat(new String(byteArrayOutputStream.toByteArray(), Charsets.UTF_8))
+            .contains(
+                "Content-Type: text/plain; charset=UTF-8\r\n" +
+                    "Content-Transfer-Encoding: 7bit\r\n" +
+                    "Content-Disposition: inline\r\n" +
+                    "\r\n" +
+                    "Explanation:\n" +
+                    " - We should always write detailed unit tests\n" +
+                    " - We should think of all edge cases\n");
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/AddressTypeTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/AddressTypeTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/AddressTypeTest.java
new file mode 100644
index 0000000..ee2520b
--- /dev/null
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/AddressTypeTest.java
@@ -0,0 +1,99 @@
+/****************************************************************
+ * 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.mdn.fields;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class AddressTypeTest {
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    @Test
+    public void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(AddressType.class)
+            .allFieldsShouldBeUsed()
+            .verify();
+    }
+
+    @Test
+    public void constructorShouldThrowOnNull() {
+        expectedException.expect(NullPointerException.class);
+
+        new AddressType(null);
+    }
+
+    @Test
+    public void constructorShouldThrowOnEmpty() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new AddressType("");
+    }
+
+    @Test
+    public void constructorShouldThrowOnFoldingWhiteSpaces() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new AddressType("   ");
+    }
+
+    @Test
+    public void constructorShouldThrowOnLineBreaks() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new AddressType("a\nb");
+    }
+
+    @Test
+    public void constructorShouldThrowOnLineBreakAtTheEnd() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new AddressType("a\n");
+    }
+
+    @Test
+    public void constructorShouldThrowOnLineBreakAtTheBeginning() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new AddressType("\na");
+    }
+
+    @Test
+    public void constructorShouldAcceptValidValue() {
+        String type = "ab";
+        AddressType addressType = new AddressType(type);
+
+        assertThat(addressType.getType())
+            .isEqualTo(type);
+    }
+
+    @Test
+    public void typeShouldBeTrimmed() {
+        AddressType addressType = new AddressType("  ab  ");
+
+        assertThat(addressType.getType())
+            .isEqualTo("ab");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
index c424a0c..b53cf61 100644
--- a/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/FinalRecipientTest.java
@@ -21,7 +21,6 @@ package org.apache.james.mdn.fields;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.james.mdn.Constants;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -51,22 +50,14 @@ public class FinalRecipientTest {
     public void shouldThrowOnNullAddressWithType() {
         expectedException.expect(NullPointerException.class);
 
-        new FinalRecipient("customType", null);
+        new FinalRecipient(new AddressType("customType"), null);
     }
 
     @Test
     public void shouldThrowOnNullType() {
         expectedException.expect(NullPointerException.class);
 
-        String addressType = null;
-        new FinalRecipient(addressType, Text.fromRawText("address"));
-    }
-
-    @Test
-    public void shouldThrowOnMultilineType() {
-        expectedException.expect(IllegalArgumentException.class);
-
-        String addressType = "a\nb";
+        AddressType addressType = null;
         new FinalRecipient(addressType, Text.fromRawText("address"));
     }
 
@@ -74,7 +65,7 @@ public class FinalRecipientTest {
     public void typeShouldDefaultToRfc822() {
         Text address = Text.fromRawText("address");
         assertThat(new FinalRecipient(address))
-            .isEqualTo(new FinalRecipient(Constants.RFC_822, address));
+            .isEqualTo(new FinalRecipient(AddressType.RFC_822, address));
     }
 
     @Test
@@ -86,7 +77,7 @@ public class FinalRecipientTest {
 
     @Test
     public void formattedValueShouldDisplayCustomType() {
-        assertThat(new FinalRecipient("postal", Text.fromRawText("Plop"))
+        assertThat(new FinalRecipient(new AddressType("postal"), Text.fromRawText("Plop"))
             .formattedValue())
             .isEqualTo("Final-Recipient: postal; Plop");
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
index b5041fd..3d69440 100644
--- a/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/GatewayTest.java
@@ -52,22 +52,14 @@ public class GatewayTest {
         expectedException.expect(NullPointerException.class);
 
         Text name = null;
-        new Gateway("type", name);
+        new Gateway(new AddressType("type"), name);
     }
 
     @Test
     public void shouldThrowOnNullType() {
         expectedException.expect(NullPointerException.class);
 
-        String nameType = null;
-        new Gateway(nameType, Text.fromRawText("name"));
-    }
-
-    @Test
-    public void shouldThrowOnMultilineType() {
-        expectedException.expect(IllegalArgumentException.class);
-
-        String nameType = "name\ntype";
+        AddressType nameType = null;
         new Gateway(nameType, Text.fromRawText("name"));
     }
 
@@ -75,7 +67,7 @@ public class GatewayTest {
     public void addressTypeSHouldDefaultToDNS() {
         Text address = Text.fromRawText("address");
         assertThat(new Gateway(address))
-            .isEqualTo(new Gateway(Gateway.DNS, address));
+            .isEqualTo(new Gateway(AddressType.DNS, address));
     }
 
     @Test
@@ -95,7 +87,7 @@ public class GatewayTest {
 
     @Test
     public void formattedValueShouldDisplayCustomAddress() {
-        assertThat(new Gateway("custom", Text.fromRawText("address"))
+        assertThat(new Gateway(new AddressType("custom"), Text.fromRawText("address"))
             .formattedValue())
             .isEqualTo("MDN-Gateway: custom;address");
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
index 58f12c1..fb5719a 100644
--- a/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalMessageIdTest.java
@@ -54,9 +54,46 @@ public class OriginalMessageIdTest {
     }
 
     @Test
+    public void constructorShouldThrowOnEmpty() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new OriginalMessageId("");
+    }
+
+    @Test
+    public void constructorShouldThrowOnFoldingWhiteSpaces() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new OriginalMessageId("   ");
+    }
+
+    @Test
+    public void shouldThrowOnNameWithLineBreakAtTheEnd() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "a\n";
+        new OriginalMessageId(userAgentName);
+    }
+
+    @Test
+    public void shouldThrowOnNameWithLineBreakAtTheBeginning() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "\nb";
+        new OriginalMessageId(userAgentName);
+    }
+
+    @Test
     public void formattedValueShouldDisplayMessageId() {
         assertThat(new OriginalMessageId("msgId")
             .formattedValue())
             .isEqualTo("Original-Message-ID: msgId");
     }
+
+    @Test
+    public void messageIdShouldBeTrimmed() {
+        assertThat(new OriginalMessageId(" msgId ")
+            .getOriginalMessageId())
+            .isEqualTo("msgId");
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
index 7a37e54..5f9e4a6 100644
--- a/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/OriginalRecipientTest.java
@@ -21,7 +21,6 @@ package org.apache.james.mdn.fields;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.james.mdn.Constants;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -54,21 +53,21 @@ public class OriginalRecipientTest {
         expectedException.expect(NullPointerException.class);
 
         Text originalRecipient = null;
-        new OriginalRecipient("customType", originalRecipient);
+        new OriginalRecipient(new AddressType("customType"), originalRecipient);
     }
 
     @Test
     public void shouldThrowOnNullAddressType() {
         expectedException.expect(NullPointerException.class);
 
-        String addressType = null;
+        AddressType addressType = null;
         new OriginalRecipient(addressType, ADDRESS);
     }
 
     @Test
     public void addressTypeShouldDefaultToRfc822() {
         assertThat(new OriginalRecipient(ADDRESS))
-            .isEqualTo(new OriginalRecipient(Constants.RFC_822, ADDRESS));
+            .isEqualTo(new OriginalRecipient(AddressType.RFC_822, ADDRESS));
     }
 
     @Test
@@ -80,7 +79,7 @@ public class OriginalRecipientTest {
 
     @Test
     public void formattedValueShouldDisplayCustomType() {
-        assertThat(new OriginalRecipient("custom", ADDRESS)
+        assertThat(new OriginalRecipient(new AddressType("custom"), ADDRESS)
             .formattedValue())
             .isEqualTo("Original-Recipient: custom; address");
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
index 74f3a97..53954b8 100644
--- a/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/ReportingUserAgentTest.java
@@ -80,12 +80,76 @@ public class ReportingUserAgentTest {
     }
 
     @Test
+    public void shouldThrowOnEmptyName() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "";
+        new ReportingUserAgent(userAgentName);
+    }
+
+    @Test
+    public void shouldThrowOnFoldingWhiteSpaceName() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "   ";
+        new ReportingUserAgent(userAgentName);
+    }
+
+    @Test
+    public void shouldThrowOnNameWithLineBreak() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "a\nb";
+        new ReportingUserAgent(userAgentName);
+    }
+
+    @Test
+    public void shouldThrowOnNameWithLineBreakAtTheEnd() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "a\n";
+        new ReportingUserAgent(userAgentName);
+    }
+
+    @Test
+    public void shouldThrowOnNameWithLineBreakAtTheBeginning() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        String userAgentName = "\nb";
+        new ReportingUserAgent(userAgentName);
+    }
+
+    @Test
+    public void nameShouldBeTrimmed() {
+        assertThat(new ReportingUserAgent(" name ").getUserAgentName())
+            .isEqualTo(USER_AGENT_NAME);
+    }
+
+    @Test
+    public void productShouldBeTrimmed() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME, " product ").getUserAgentProduct())
+            .contains(USER_AGENT_PRODUCT);
+    }
+
+    @Test
     public void formattedValueShouldDisplayNameWhenProductMissing() {
         assertThat(new ReportingUserAgent(USER_AGENT_NAME).formattedValue())
             .isEqualTo("Reporting-UA: name; ");
     }
 
     @Test
+    public void emptyProductShouldBeFilteredOut() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME, "").getUserAgentProduct())
+            .isEmpty();
+    }
+
+    @Test
+    public void foldingWhiteSpaceProductShouldBeFilteredOut() {
+        assertThat(new ReportingUserAgent(USER_AGENT_NAME, "  ").getUserAgentProduct())
+            .isEmpty();
+    }
+
+    @Test
     public void formattedValueShouldDisplayProduct() {
         assertThat(new ReportingUserAgent(USER_AGENT_NAME, USER_AGENT_PRODUCT).formattedValue())
             .isEqualTo("Reporting-UA: name; product");

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java b/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
index 938b6fe..0d82c28 100644
--- a/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/fields/TextTest.java
@@ -47,10 +47,10 @@ public class TextTest {
     }
 
     @Test
-    public void formattedShouldRenderEmptyStrings() {
-        Text text = Text.fromRawText("");
+    public void fromRawTextShouldThrowOnEmptyStrings() {
+        expectedException.expect(IllegalArgumentException.class);
 
-        assertThat(text.formatted()).isEqualTo("");
+        Text.fromRawText("");
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/8d9287ff/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java b/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
index a408b51..dccf3dd 100644
--- a/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/modifier/DispositionModifierTest.java
@@ -50,4 +50,32 @@ public class DispositionModifierTest {
 
         new DispositionModifier("multi\nline");
     }
+
+    @Test
+    public void shouldThrowOnEndBreakLine() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new DispositionModifier("multi\n");
+    }
+
+    @Test
+    public void shouldThrowOnBeginningBreakLine() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new DispositionModifier("\nline");
+    }
+
+    @Test
+    public void shouldThrowOnEmptyValue() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new DispositionModifier("");
+    }
+
+    @Test
+    public void shouldThrowOnFoldingWhiteSpaceValue() {
+        expectedException.expect(IllegalArgumentException.class);
+
+        new DispositionModifier("    ");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[14/27] james-project git commit: JAMES-2132 Support arbitrary MDN Disposition modifier

Posted by bt...@apache.org.
JAMES-2132 Support arbitrary MDN Disposition modifier

RFC defines them in https://tools.ietf.org/html/rfc8098#section-3.2.6.3 as:

   disposition-modifier = "error" / disposition-modifier-extension

   The following disposition-types are defined:

   disposition-modifier-extension
                       Disposition modifiers may be defined in the
                       future by later revisions or extensions to this
                       specification.  MDN disposition value names MUST
                       be registered with the Internet Assigned Numbers
                       Authority (IANA) using the "Specification
                       Required" registration policy.  (See Section 10
                       for a registration form.)  MDNs with disposition
                       modifier names not understood by the receiving
                       MUA MAY be silently ignored or placed in the
                       user's mailbox without special interpretation.
                       They MUST NOT cause any error message to be sent
                       to the sender of the MDN.


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5ee43e68
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5ee43e68
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5ee43e68

Branch: refs/heads/master
Commit: 5ee43e68e7f87738caf513f70c93d7c755f6dc14
Parents: b254ac3
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:44:30 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 .../james/mdn/modifier/DispositionModifier.java | 25 +++------
 .../org/apache/james/mdn/MDNFactoryTest.java    | 56 +++++---------------
 2 files changed, 21 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/5ee43e68/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
index 1efb7d0..ac4ba63 100644
--- a/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
+++ b/mdn/src/main/java/org/apache/james/mdn/modifier/DispositionModifier.java
@@ -19,30 +19,21 @@
 
 package org.apache.james.mdn.modifier;
 
-import java.util.Optional;
-import java.util.stream.Stream;
-
 /**
  * Interface <code>DispositionModifier</code> marks a type encapsulating
  * disposition modifier information as defined by RFC 2298.
  */
-public enum DispositionModifier {
-    Error("error"),
-    Expired("expired"),
-    Failed("failed"),
-    MailboxTerminated("mailbox-terminated"),
-    Superseded("superseded"),
-    Warning("warning");
-
-    public static Optional<DispositionModifier> fromString(String value) {
-        return Stream.of(values())
-            .filter(sendingMode -> sendingMode.getValue().equalsIgnoreCase(value))
-            .findFirst();
-    }
+public class DispositionModifier {
+    public static DispositionModifier Error = new DispositionModifier("error");
+    public static DispositionModifier Expired = new DispositionModifier("expired");
+    public static DispositionModifier Failed = new DispositionModifier("failed");
+    public static DispositionModifier MailboxTerminated = new DispositionModifier("mailbox-terminated");
+    public static DispositionModifier Superseded = new DispositionModifier("superseded");
+    public static DispositionModifier Warning = new DispositionModifier("warning");
 
     private final String value;
 
-    DispositionModifier(String value) {
+    public DispositionModifier(String value) {
         this.value = value;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/5ee43e68/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
----------------------------------------------------------------------
diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
index 968c788..ac51b08 100644
--- a/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
+++ b/mdn/src/test/java/org/apache/james/mdn/MDNFactoryTest.java
@@ -101,35 +101,6 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatTypeDenied() {
-        Disposition disposition = Disposition.builder()
-            .actionMode(DispositionActionMode.Manual)
-            .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Denied)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
-            .build();
-
-        String report = MDNReport.builder()
-            .reportingUserAgentField(new ReportingUserAgent(
-                "UA_name",
-                Optional.of("UA_product")))
-            .finalRecipientField(new FinalRecipient("final_recipient"))
-            .originalRecipientField(new OriginalRecipient("originalRecipient"))
-            .originalMessageIdField(new OriginalMessageId("original_message_id"))
-            .dispositionField(disposition)
-            .build()
-            .formattedValue();
-
-        assertThat(report)
-            .isEqualTo("Reporting-UA: UA_name; UA_product\r\n" +
-                "Original-Recipient: rfc822; originalRecipient\r\n" +
-                "Final-Recepient: rfc822; final_recipient\r\n" +
-                "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;denied/error,failed\r\n");
-    }
-
-    @Test
     public void generateMDNReportShouldFormatTypeDispatcher() {
         Disposition disposition = Disposition.builder()
         .actionMode(DispositionActionMode.Manual)
@@ -188,11 +159,11 @@ public class MDNFactoryTest {
     }
 
     @Test
-    public void generateMDNReportShouldFormatTypeFailed() {
+    public void generateMDNReportShouldFormatTypeDeleted() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
             .sendingMode(DispositionSendingMode.Manual)
-            .type(DispositionType.Failed)
+            .type(DispositionType.Deleted)
             .addModifier(DispositionModifier.Error)
             .addModifier(DispositionModifier.Failed)
             .build();
@@ -213,17 +184,17 @@ public class MDNFactoryTest {
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;failed/error,failed\r\n");
+                "Disposition: manual-action/MDN-sent-manually;deleted/error,failed\r\n");
     }
 
     @Test
-    public void generateMDNReportShouldFormatTypeDeleted() {
+    public void generateMDNReportShouldFormatAllModifier() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
             .sendingMode(DispositionSendingMode.Manual)
             .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
-            .addModifier(DispositionModifier.Failed)
+            .addModifiers(DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
+                DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning)
             .build();
 
         String report = MDNReport.builder()
@@ -242,17 +213,16 @@ public class MDNFactoryTest {
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/error,failed\r\n");
+                "Disposition: manual-action/MDN-sent-manually;deleted/error,expired,failed,mailbox-terminated,superseded,warning\r\n");
     }
 
     @Test
-    public void generateMDNReportShouldFormatAllModifier() {
+    public void generateMDNReportShouldFormatOneModifier() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
             .sendingMode(DispositionSendingMode.Manual)
             .type(DispositionType.Deleted)
-            .addModifiers(DispositionModifier.Error, DispositionModifier.Expired, DispositionModifier.Failed,
-                DispositionModifier.MailboxTerminated, DispositionModifier.Superseded, DispositionModifier.Warning)
+            .addModifier(DispositionModifier.Error)
             .build();
 
         String report = MDNReport.builder()
@@ -271,16 +241,16 @@ public class MDNFactoryTest {
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/error,expired,failed,mailbox-terminated,superseded,warning\r\n");
+                "Disposition: manual-action/MDN-sent-manually;deleted/error\r\n");
     }
 
     @Test
-    public void generateMDNReportShouldFormatOneModifier() {
+    public void generateMDNReportShouldFormatUnknownModifier() {
         Disposition disposition = Disposition.builder()
             .actionMode(DispositionActionMode.Manual)
             .sendingMode(DispositionSendingMode.Manual)
             .type(DispositionType.Deleted)
-            .addModifier(DispositionModifier.Error)
+            .addModifier(new DispositionModifier("new"))
             .build();
 
         String report = MDNReport.builder()
@@ -299,7 +269,7 @@ public class MDNFactoryTest {
                 "Original-Recipient: rfc822; originalRecipient\r\n" +
                 "Final-Recepient: rfc822; final_recipient\r\n" +
                 "Original-Message-ID: original_message_id\r\n" +
-                "Disposition: manual-action/MDN-sent-manually;deleted/error\r\n");
+                "Disposition: manual-action/MDN-sent-manually;deleted/new\r\n");
     }
 
     @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[02/27] james-project git commit: JAMES-2132 moving MDN to a separated project

Posted by bt...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierExpired.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierExpired.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierExpired.java
deleted file mode 100644
index cda3e5b..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierExpired.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ModifierExpired</code>
- */    
-public class ModifierExpired implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierExpired()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "expired";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierFailed.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierFailed.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierFailed.java
deleted file mode 100644
index 1d008c6..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierFailed.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ModifierFailed</code>
- */    
-public class ModifierFailed implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierFailed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "failed";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierMailboxTerminated.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierMailboxTerminated.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierMailboxTerminated.java
deleted file mode 100644
index a0eb504..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierMailboxTerminated.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ModifierMailboxTerminated</code>
- */    
-public class ModifierMailboxTerminated implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierMailboxTerminated()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "mailbox-terminated";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierSuperseded.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierSuperseded.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierSuperseded.java
deleted file mode 100644
index efad900..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierSuperseded.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ModifierSuperseded</code>
- */    
-public class ModifierSuperseded implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierSuperseded()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "superseded";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierWarning.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierWarning.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierWarning.java
deleted file mode 100644
index ca39308..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/ModifierWarning.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>ModifierWarning</code>
- */    
-public class ModifierWarning implements DispositionModifier
-{
-
-    /**
-     * Default Constructor
-     */
-    public ModifierWarning()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "warning";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeAutomatic.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeAutomatic.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeAutomatic.java
deleted file mode 100644
index 9626643..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeAutomatic.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>SendingModeAutomatic</code>
- */
-public class SendingModeAutomatic implements DispositionSendingMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public SendingModeAutomatic()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "MDN-sent-automatically";
-    }        
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeManual.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeManual.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeManual.java
deleted file mode 100644
index 69581b4..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/SendingModeManual.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>SendingModeManual</code>
- */
-public class SendingModeManual implements DispositionSendingMode
-{
-
-    /**
-     * Default Constructor
-     */
-    public SendingModeManual()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "MDN-sent-manually";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDeleted.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDeleted.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDeleted.java
deleted file mode 100644
index 01f8806..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDeleted.java
+++ /dev/null
@@ -1,45 +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.jsieve.mdn;
-
-
-/**
- * Class <code>TypeDeleted</code>
- */
-public class TypeDeleted implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDeleted()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "deleted";
-    }         
-
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDenied.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDenied.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDenied.java
deleted file mode 100644
index fed3985..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDenied.java
+++ /dev/null
@@ -1,44 +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.jsieve.mdn;
-
-
-/**
- * Class <code>TypeDenied</code>
- */    
-public class TypeDenied implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDenied()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "denied";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDispatched.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDispatched.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDispatched.java
deleted file mode 100644
index 4a23185..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDispatched.java
+++ /dev/null
@@ -1,43 +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.jsieve.mdn;
-
-
-/**
- * Class <code>TypeDispatched</code>
- */
-public class TypeDispatched implements DispositionType
-{
-    /**
-     * Default Constructor
-     */
-    public TypeDispatched()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "dispatched";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDisplayed.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDisplayed.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDisplayed.java
deleted file mode 100644
index 57ab717..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeDisplayed.java
+++ /dev/null
@@ -1,44 +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.jsieve.mdn;
-
-
-/**
- * Class <code>TypeDisplayed</code>
- */
-public class TypeDisplayed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeDisplayed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "displayed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeFailed.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeFailed.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeFailed.java
deleted file mode 100644
index 41ec777..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeFailed.java
+++ /dev/null
@@ -1,44 +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.jsieve.mdn;
-
-
-/**
- * Class <code>TypeFailed</code>
- */    
-public class TypeFailed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeFailed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "failed";
-    }         
-}

http://git-wip-us.apache.org/repos/asf/james-project/blob/976a3037/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeProcessed.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeProcessed.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeProcessed.java
deleted file mode 100644
index e136070..0000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/mdn/TypeProcessed.java
+++ /dev/null
@@ -1,44 +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.jsieve.mdn;
-
-
-/**
- * Class <code>TypeProcessed</code>
- */    
-public class TypeProcessed implements DispositionType
-{
-
-    /**
-     * Default Constructor
-     */
-    public TypeProcessed()
-    {
-        super();
-    }
-    
-    /**
-     * @see java.lang.Object#toString()
-     */
-    public String toString()
-    {
-        return "processed";
-    }         
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[11/27] james-project git commit: JAMES-2132 Remove extra Disposition types

Posted by bt...@apache.org.
JAMES-2132 Remove extra Disposition types

RFC defines them in https://tools.ietf.org/html/rfc8098#section-3.2.6.2 as:

   The following disposition-types are defined:

   "displayed"         The message has been displayed by the MUA to
                       someone reading the recipient's mailbox.  There
                       is no guarantee that the content has been read or
                       understood.

   "dispatched"        The message has been sent somewhere in some
                       manner (e.g., printed, faxed, forwarded) without
                       necessarily having been previously displayed to
                       the user.  The user may or may not see the
                       message later.

   "processed"         The message has been processed in some manner
                       (i.e., by some sort of rules or server) without
                       being displayed to the user.  The user may or may
                       not see the message later, or there may not even
                       be a human user associated with the mailbox.

   "deleted"           The message has been deleted.  The recipient may
                       or may not have seen the message.  The recipient
                       might "undelete" the message at a later time and
                       read the message.


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/b254ac37
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/b254ac37
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/b254ac37

Branch: refs/heads/master
Commit: b254ac3773113b54138a72d4d42a917336f3c4fe
Parents: fdd5cf3
Author: benwa <bt...@linagora.com>
Authored: Mon Aug 28 17:38:46 2017 +0700
Committer: benwa <bt...@linagora.com>
Committed: Thu Aug 31 18:00:20 2017 +0700

----------------------------------------------------------------------
 mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java | 2 --
 1 file changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/b254ac37/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
----------------------------------------------------------------------
diff --git a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
index 2ce39b9..a70bdd1 100644
--- a/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
+++ b/mdn/src/main/java/org/apache/james/mdn/type/DispositionType.java
@@ -28,10 +28,8 @@ import java.util.stream.Stream;
  */
 public enum DispositionType {
     Deleted("deleted"),
-    Denied("denied"),
     Dispatched("dispatched"),
     Displayed("displayed"),
-    Failed("failed"),
     Processed("processed");
 
     public static Optional<DispositionType> fromString(String value) {


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org