JAMES-2134 Parse Disposition field and construct appropriate object
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/e2048572 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/e2048572 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/e2048572 Branch: refs/heads/master Commit: e20485729b695fcb14bd090554b0307e31410d73 Parents: 0cc5bd2 Author: Raphael Ouazana <[email protected]> Authored: Wed Apr 4 12:04:41 2018 +0200 Committer: Raphael Ouazana <[email protected]> Committed: Thu Apr 5 14:48:42 2018 +0200 ---------------------------------------------------------------------- .../org/apache/james/mdn/MDNReportParser.java | 69 ++++++++++-- .../apache/james/mdn/MDNReportParserTest.java | 112 +++++++++++++++++++ 2 files changed, 174 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/e2048572/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java ---------------------------------------------------------------------- diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java b/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java index 43d0964..07a4ef2 100644 --- a/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java +++ b/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java @@ -19,13 +19,18 @@ package org.apache.james.mdn; +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.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.parboiled.BaseParser; import org.parboiled.Rule; @@ -542,10 +547,37 @@ public class MDNReportParser { *( OWS "," OWS disposition-modifier ) ] OWS */ Rule dispositionField() { return Sequence( - "Disposition", ":", ows(), dispositionMode(), ows(), ";", - ows(), dispositionType(), - Optional(Sequence(ows(), "/", ows(), dispositionModifier(), - ZeroOrMore(Sequence(ows(), ",", dispositionModifier())))), ows()); + push(Disposition.builder()), + "Disposition", ":", + ows(), + dispositionMode(), + ows(), + ";", + ows(), + dispositionType(), + Optional( + Sequence( + ows(), + "/", + ows(), + dispositionModifier(), ACTION(addDispositionModifier()), + ZeroOrMore( + Sequence( + ows(), + ",", + dispositionModifier(), ACTION(addDispositionModifier()))))), + ows(), + ACTION(buildDispositionField())); + } + + boolean addDispositionModifier() { + this.<Disposition.Builder>peekT().addModifier(new DispositionModifier(match())); + return true; + } + + boolean buildDispositionField() { + push(this.<Disposition.Builder>popT().build()); + return true; } // disposition-mode = action-mode OWS "/" OWS sending-mode @@ -555,18 +587,41 @@ public class MDNReportParser { // action-mode = "manual-action" / "automatic-action" Rule actionMode() { - return FirstOf("manual-action", "automatic-action"); + return FirstOf( + Sequence("manual-action", ACTION(setActionMode(DispositionActionMode.Manual))), + Sequence("automatic-action", ACTION(setActionMode(DispositionActionMode.Automatic)))); + } + + boolean setActionMode(DispositionActionMode actionMode) { + this.<Disposition.Builder>peekT().actionMode(actionMode); + return true; } // sending-mode = "MDN-sent-manually" / "MDN-sent-automatically" Rule sendingMode() { - return FirstOf("MDN-sent-manually", "MDN-sent-automatically"); + return FirstOf( + Sequence("MDN-sent-manually", ACTION(setSendingMode(DispositionSendingMode.Manual))), + Sequence("MDN-sent-automatically", ACTION(setSendingMode(DispositionSendingMode.Automatic)))); + } + + boolean setSendingMode(DispositionSendingMode sendingMode) { + this.<Disposition.Builder>peekT().sendingMode(sendingMode); + return true; } /* disposition-type = "displayed" / "deleted" / "dispatched" / "processed" */ Rule dispositionType() { - return FirstOf("displayed", "deleted", "dispatched", "processed"); + return FirstOf( + Sequence("displayed", ACTION(setDispositionType(DispositionType.Displayed))), + Sequence("deleted", ACTION(setDispositionType(DispositionType.Deleted))), + Sequence("dispatched", ACTION(setDispositionType(DispositionType.Dispatched))), + Sequence("processed", ACTION(setDispositionType(DispositionType.Processed)))); + } + + boolean setDispositionType(DispositionType type) { + this.<Disposition.Builder>peekT().type(type); + return true; } // disposition-modifier = "error" / disposition-modifier-extension http://git-wip-us.apache.org/repos/asf/james-project/blob/e2048572/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java ---------------------------------------------------------------------- diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java index 20cfb30..05bc80f 100644 --- a/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java +++ b/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java @@ -22,13 +22,18 @@ package org.apache.james.mdn; import static org.assertj.core.api.Assertions.assertThat; import org.apache.james.mdn.MDNReportParser.Parser; +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.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; import org.parboiled.Parboiled; import org.parboiled.parserunners.ReportingParseRunner; @@ -139,4 +144,111 @@ public class MDNReportParserTest { assertThat(result.resultValue).isInstanceOf(OriginalMessageId.class); assertThat((OriginalMessageId)result.resultValue).isEqualTo(new OriginalMessageId("<[email protected]>")); } + + @Test + public void dispositionFieldShouldParseWhenMinimal() { + String minimal = "Disposition: automatic-action/MDN-sent-automatically;processed"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Automatic) + .type(DispositionType.Processed) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(minimal); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } + + @Test + public void dispositionFieldShouldParseWhenMaximal() { + String maximal = "Disposition: automatic-action/MDN-sent-automatically;processed/error,failed"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Automatic) + .type(DispositionType.Processed) + .addModifier(DispositionModifier.Error) + .addModifier(DispositionModifier.Failed) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(maximal); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } + + @Test + public void dispositionFieldShouldParseWhenManualAutomaticWithDisplayedType() { + String disposition = "Disposition: manual-action/MDN-sent-automatically;processed"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Manual) + .sendingMode(DispositionSendingMode.Automatic) + .type(DispositionType.Processed) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(disposition); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } + + @Test + public void dispositionFieldShouldParseWhenAutomaticManualWithDisplayedType() { + String disposition = "Disposition: automatic-action/MDN-sent-manually;processed"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Manual) + .type(DispositionType.Processed) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(disposition); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } + + @Test + public void dispositionFieldShouldParseWhenDeletedType() { + String disposition = "Disposition: automatic-action/MDN-sent-manually;deleted"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Manual) + .type(DispositionType.Deleted) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(disposition); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } + + @Test + public void dispositionFieldShouldParseWhenDispatchedType() { + String disposition = "Disposition: automatic-action/MDN-sent-manually;dispatched"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Manual) + .type(DispositionType.Dispatched) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(disposition); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } + + @Test + public void dispositionFieldShouldParseWhenDisplayedType() { + String disposition = "Disposition: automatic-action/MDN-sent-manually;displayed"; + Disposition expected = Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Manual) + .type(DispositionType.Displayed) + .build(); + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionField()).run(disposition); + assertThat(result.matched).isTrue(); + assertThat(result.resultValue).isInstanceOf(Disposition.class); + assertThat((Disposition)result.resultValue).isEqualTo(expected); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
