Skip to content

Commit

Permalink
#144: added multipart structure browser in the RFC Compliance page
Browse files Browse the repository at this point in the history
  • Loading branch information
bbottema committed Jun 3, 2018
1 parent aff4ba4 commit 51ae5d9
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/main/webapp/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NgModule, enableProdMode } from '@angular/core'
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { rootRouterConfig } from './app/simple-java-mail-routes';
import { SimpleJavaMailApp } from './app/simple-java-mail-app';
import { BrowserModule } from '@angular/platform-browser';
Expand Down Expand Up @@ -37,6 +38,7 @@ require('./index.html');
imports: [
BrowserModule,
HttpModule,
FormsModule,
RouterModule.forRoot(rootRouterConfig, { useHash: true }),
Ng2SimplePageScrollModule.forRoot()
],
Expand Down
10 changes: 10 additions & 0 deletions src/main/webapp/src/app/components/rfc/Email.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export class Email {
constructor(readonly usePlainText: boolean,
readonly useHTMLText: boolean,
readonly useEmbeddedContent: boolean,
readonly useCalendarEvent: boolean,
readonly useAttachments: boolean,
readonly useEmailForward: boolean,
) {
}
}
22 changes: 22 additions & 0 deletions src/main/webapp/src/app/components/rfc/MessageStrategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {Email} from "./Email";

export abstract class MessageStrategy {

abstract compatibleWithEmail(email: Email): boolean;

abstract determineMessageStructure(email: Email): string;

protected static emailContainsMixedContent(email: Email): boolean {
return email.useAttachments || email.useEmailForward;
}

protected static emailContainsRelatedContent(email: Email): boolean {
return email.useEmbeddedContent;
}

protected static emailContainsAlternativeContent(email: Email): boolean {
return (email.usePlainText ? 1 : 0) +
(email.useHTMLText ? 1 : 0) +
(email.useCalendarEvent ? 1 : 0) > 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {MessageStrategy} from "./MessageStrategy";
import {Email} from "./Email";

export class MessageStrategyAlternative extends MessageStrategy {
compatibleWithEmail(email: Email): boolean {
return !MessageStrategy.emailContainsMixedContent(email) &&
!MessageStrategy.emailContainsRelatedContent(email) &&
MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">alternative (root)" +
" <ul>" +
(email.usePlainText ? "<li class=\"indent\">Plain text</li>" : "") +
(email.useHTMLText ? "<li class=\"indent\">HTML text</li>" : "") +
(email.useCalendarEvent ? "<li class=\"indent\">iCalendar text</li>" : "") +
" </ul>" +
" </li>" +
"</ul>";
}
}
24 changes: 24 additions & 0 deletions src/main/webapp/src/app/components/rfc/MessageStrategyMixed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {Email} from "./Email";
import {MessageStrategy} from "./MessageStrategy";

export class MessageStrategyMixed extends MessageStrategy {
compatibleWithEmail(email: Email): boolean {
return MessageStrategy.emailContainsMixedContent(email) &&
!MessageStrategy.emailContainsRelatedContent(email) &&
!MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">mixed (root)" +
" <ul>" +
(email.usePlainText ? "<li class=\"indent\">Plain text</li>" : "") +
(email.useHTMLText ? "<li class=\"indent\">HTML text</li>" : "") +
(email.useCalendarEvent ? "<li class=\"indent\">iCalendar text</li>" : "") +
(email.useEmailForward ? "<li class=\"indent\">forwarded email</li>" : "") +
(email.useAttachments ? "<li class=\"indent\">downloadable attachments</li>" : "") +
" </ul>" +
" </li>" +
"</ul>";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {Email} from "./Email";
import {MessageStrategy} from "./MessageStrategy";

export class MessageStrategyMixedAlternative extends MessageStrategy {
compatibleWithEmail(email: Email): boolean {
return MessageStrategy.emailContainsMixedContent(email) &&
!MessageStrategy.emailContainsRelatedContent(email) &&
MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">mixed (root)" +
" <ul>" +
" <li class=\"indent\">alternative" +
" <ul>" +
(email.usePlainText ? "<li class=\"indent\">Plain text</li>" : "") +
(email.useHTMLText ? "<li class=\"indent\">HTML text</li>" : "") +
(email.useCalendarEvent ? "<li class=\"indent\">iCalendar text</li>" : "") +
" </ul>" +
" </li>" +
(email.useEmailForward ? "<li class=\"indent\">forwarded email</li>" : "") +
(email.useAttachments ? "<li class=\"indent\">downloadable attachments</li>" : "") +
" </ul>" +
" </li>" +
"</ul>";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Email} from "./Email";
import {MessageStrategy} from "./MessageStrategy";

export class MessageStrategyMixedRelated extends MessageStrategy {
compatibleWithEmail(email: Email): boolean {
return MessageStrategy.emailContainsMixedContent(email) &&
MessageStrategy.emailContainsRelatedContent(email) &&
!MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">mixed (root)" +
" <ul>" +
" <li class=\"indent\">related" +
" <ul>" +
" <li class=\"indent\">HTML text</li>" +
" <li class=\"indent\">embeddable content (ie. images)</li>" +
" </ul>" +
" </li>" +
(email.useEmailForward ? "<li class=\"indent\">forwarded email</li>" : "") +
(email.useAttachments ? "<li class=\"indent\">downloadable attachments</li>" : "") +
" </ul>" +
" </li>" +
"</ul>";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {Email} from "./Email";
import {MessageStrategy} from "./MessageStrategy";

export class MessageStrategyMixedRelatedAlternative extends MessageStrategy {

compatibleWithEmail(email: Email): boolean {
return MessageStrategy.emailContainsMixedContent(email) &&
MessageStrategy.emailContainsRelatedContent(email) &&
MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">mixed (root)" +
" <ul>" +
" <li class=\"indent\">related" +
" <ul>" +
" <li class=\"indent\">alternative" +
" <ul>" +
(email.usePlainText ? "<li class=\"indent\">Plain text</li>" : "") +
(email.useHTMLText ? "<li class=\"indent\">HTML text</li>" : "") +
(email.useCalendarEvent ? "<li class=\"indent\">iCalendar text</li>" : "") +
" </ul>" +
" </li>" +
" <li class=\"indent\">embeddable content (ie. images) </li>" +
" </ul>" +
" </li>" +
(email.useEmailForward ? "<li class=\"indent\">forwarded email</li>" : "") +
(email.useAttachments ? "<li class=\"indent\">downloadable attachments</li>" : "") +
" </ul>" +
" </li>" +
"</ul>";
}
}
21 changes: 21 additions & 0 deletions src/main/webapp/src/app/components/rfc/MessageStrategyRelated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {Email} from "./Email";
import {MessageStrategy} from "./MessageStrategy";

export class MessageStrategyRelated extends MessageStrategy {
compatibleWithEmail(email: Email): boolean {
return !MessageStrategy.emailContainsMixedContent(email) &&
MessageStrategy.emailContainsRelatedContent(email) &&
!MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">related (root)" +
" <ul>" +
" <li class=\"indent\">HTML text</li>" +
" <li class=\"indent\">embeddable content (ie. images)</li>" +
" </ul>" +
" </li>" +
"</ul>";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Email} from "./Email";
import {MessageStrategy} from "./MessageStrategy";

export class MessageStrategyRelatedAlternative extends MessageStrategy {
compatibleWithEmail(email: Email): boolean {
return !MessageStrategy.emailContainsMixedContent(email) &&
MessageStrategy.emailContainsRelatedContent(email) &&
MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
" <li class=\"indent\">related (root)<ul>" +
" <li class=\"indent\">alternative" +
" <ul>" +
(email.usePlainText ? "<li class=\"indent\">Plain text</li>" : "") +
(email.useHTMLText ? "<li class=\"indent\">HTML text</li>" : "") +
(email.useCalendarEvent ? "<li class=\"indent\">iCalendar text</li>" : "") +
" </ul>" +
" </li>" +
" <li class=\"indent\">embeddable content (ie. images)</li>" +
" </ul>" +
"</li>";
}
}
19 changes: 19 additions & 0 deletions src/main/webapp/src/app/components/rfc/MessageStrategySimple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {MessageStrategy} from "./MessageStrategy";
import {Email} from "./Email";

export class MessageStrategySimple extends MessageStrategy {

compatibleWithEmail(email: Email): boolean {
return !MessageStrategy.emailContainsMixedContent(email) &&
!MessageStrategy.emailContainsRelatedContent(email) &&
!MessageStrategy.emailContainsAlternativeContent(email);
}

public determineMessageStructure(email: Email): string {
return "<ul>" +
(email.usePlainText ? "<li class=\"indent\">Plain text (root)</li>" : "") +
(email.useHTMLText ? "<li class=\"indent\">HTML text (root)</li>" : "") +
(email.useCalendarEvent ? "<li class=\"indent\">iCalendar text (root)</li>" : "") +
" </ul>";
}
}
44 changes: 44 additions & 0 deletions src/main/webapp/src/app/components/rfc/rfc.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ <h1>Simple Java Mail is fully RFC compliant</h1>
<ul>
<li><a simplePageScroll href="#section-why">Why RFC compliancy matters</a></li>
<li><a simplePageScroll href="#section-how">How is Simple Java Mail RFC compliant?</a></li>
<li><a simplePageScroll href="#section-explore-multipart">Explore the multipart structures used by Simple Java Mail</a></li>
</ul>
</section>

Expand Down Expand Up @@ -64,4 +65,47 @@ <h2>How is Simple Java Mail RFC compliant?</h2>
</ol>
</div>
</section>


<a href="#section-explore-multipart" id="#section-explore-multipart" class="section-link h2">&sect;</a>
<h2>Explore the multipart structures used by Simple Java Mail</h2>

<section>
<div class="view">
<p>Configure your email:</p>

<form>
<div>
<input type="checkbox" id="usePlainText" name="usePlainText" [(ngModel)]="usePlainText" (ngModelChange)="updateMessageStructure()">
<label for="usePlainText">Plain text body</label>
</div>
<div>
<input type="checkbox" id="useHTMLText" name="useHTMLText" [(ngModel)]="useHTMLText" (ngModelChange)="updateMessageStructure()">
<label for="useHTMLText">HTML text body</label>
</div>
<div class="indent">
<input type="checkbox" id="useEmbeddedContent" name="useEmbeddedContent" [(ngModel)]="useEmbeddedContent" (ngModelChange)="updateMessageStructure()"
[disabled]="!useHTMLText">
<label for="useEmbeddedContent">HTML body contains embedded content (such as image)</label>
</div>
<div>
<input type="checkbox" id="useCalendarEvent" name="useCalendarEvent" [(ngModel)]="useCalendarEvent" (ngModelChange)="updateMessageStructure()">
<label for="useCalendarEvent">iCalendar event</label>
</div>
<div>
<input type="checkbox" id="useAttachments" name="useAttachments" [(ngModel)]="useAttachments" (ngModelChange)="updateMessageStructure()">
<label for="useAttachments">Downloadable attachments</label>
</div>
<div>
<input type="checkbox" id="useEmailForward" name="useEmailForward" [(ngModel)]="useEmailForward" (ngModelChange)="updateMessageStructure()">
<label for="useEmailForward">Forwards another email</label>
</div>
</form>

</div>
<div class="side padded">
<p>Structure used for email:</p>
<div [innerHTML]="messageStructure"></div>
</div>
</section>
</div>
55 changes: 53 additions & 2 deletions src/main/webapp/src/app/components/rfc/rfc.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,59 @@
import {Component} from '@angular/core';
import {Component, Input} from '@angular/core';
import {MessageStrategy} from "./MessageStrategy";
import {MessageStrategyAlternative} from "./MessageStrategyAlternative";
import {MessageStrategyMixed} from "./MessageStrategyMixed";
import {MessageStrategyRelated} from "./MessageStrategyRelated";
import {MessageStrategyMixedRelatedAlternative} from "./MessageStrategyMixedRelatedAlternative";
import {MessageStrategyRelatedAlternative} from "./MessageStrategyRelatedAlternative";
import {MessageStrategyMixedAlternative} from "./MessageStrategyMixedAlternative";
import {MessageStrategyMixedRelated} from "./MessageStrategyMixedRelated";
import {MessageStrategySimple} from "./MessageStrategySimple";
import {Email} from "./Email";

@Component({
template: require('./rfc.html')
})

export class RfcCompliant {
@Input() usePlainText: boolean;
@Input() useHTMLText: boolean;
@Input() useEmbeddedContent: boolean;
@Input() useCalendarEvent: boolean;
@Input() useAttachments: boolean;
@Input() useEmailForward: boolean;

messageStructure: string;

private static readonly STRATEGIES: Array<MessageStrategy> = [
new MessageStrategySimple(),
new MessageStrategyAlternative(),
new MessageStrategyRelated(),
new MessageStrategyMixed(),
new MessageStrategyMixedRelated(),
new MessageStrategyMixedAlternative(),
new MessageStrategyRelatedAlternative(),
new MessageStrategyMixedRelatedAlternative()
];

updateMessageStructure(): void {
if (!this.useHTMLText) {
this.useEmbeddedContent = false;
}

this.messageStructure = RfcCompliant.determineFormalStructure(new Email(
this.usePlainText,
this.useHTMLText,
this.useEmbeddedContent,
this.useCalendarEvent,
this.useAttachments,
this.useEmailForward));
}

private static determineFormalStructure(email: Email): string {
for (const s of RfcCompliant.STRATEGIES) {
if (s.compatibleWithEmail(email)) {
return s.determineMessageStructure(email);
}
}
throw new Error("email config not recognized properly");
}
}

0 comments on commit 51ae5d9

Please sign in to comment.