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 <btell...@linagora.com>
Authored: Mon Aug 28 11:55:39 2017 +0700
Committer: benwa <btell...@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-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to