001package org.codemonkey.simplejavamail;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.HashMap;
006import java.util.List;
007import java.util.Map;
008
009import javax.activation.DataSource;
010import javax.mail.Message.RecipientType;
011import javax.mail.util.ByteArrayDataSource;
012
013/**
014 * Email message with all necessary data for an effective mailing action, including attachments etc.
015 *
016 * @author Benny Bottema
017 */
018public class Email {
019        /**
020         * The sender of the email. Can be used in conjunction with {@link #replyToRecipient}.
021         */
022        private Recipient fromRecipient;
023        /**
024         * The reply-to-address, optional. Can be used in conjunction with {@link #fromRecipient}.
025         */
026        private Recipient replyToRecipient;
027
028        /**
029         * The email message body in plain text.
030         */
031        private String text;
032
033        /**
034         * The email message body in html.
035         */
036        private String textHTML;
037
038        /**
039         * The subject of the email message.
040         */
041        private String subject;
042
043        /**
044         * List of {@link Recipient}.
045         */
046        private final List<Recipient> recipients;
047
048        /**
049         * List of {@link AttachmentResource}.
050         */
051        private final List<AttachmentResource> embeddedImages;
052
053        /**
054         * List of {@link AttachmentResource}.
055         */
056        private final List<AttachmentResource> attachments;
057
058        /**
059         * Map of header name and values, such as <code>X-Priority</code> etc.
060         */
061        private final Map<String, String> headers;
062
063        /**
064         * Constructor, creates all internal lists.
065         */
066        public Email() {
067                recipients = new ArrayList<Recipient>();
068                embeddedImages = new ArrayList<AttachmentResource>();
069                attachments = new ArrayList<AttachmentResource>();
070                headers = new HashMap<String, String>();
071        }
072
073        /**
074         * Sets the sender address.
075         *
076         * @param name The sender's name.
077         * @param fromAddress The sender's email address.
078         */
079        public void setFromAddress(final String name, final String fromAddress) {
080                fromRecipient = new Recipient(name, fromAddress, null);
081        }
082
083        /**
084         * Sets the reply-to address (optional).
085         *
086         * @param name The replied-to-receiver name.
087         * @param replyToAddress The replied-to-receiver email address.
088         */
089        public void setReplyToAddress(final String name, final String replyToAddress) {
090                replyToRecipient = new Recipient(name, replyToAddress, null);
091        }
092
093        /**
094         * Bean setters for {@link #subject}.
095         */
096        public void setSubject(final String subject) {
097                this.subject = subject;
098        }
099
100        /**
101         * Bean setters for {@link #text}.
102         */
103        public void setText(final String text) {
104                this.text = text;
105        }
106
107        /**
108         * Bean setters for {@link #textHTML}.
109         */
110        public void setTextHTML(final String textHTML) {
111                this.textHTML = textHTML;
112        }
113
114        /**
115         * Adds a new {@link Recipient} to the list on account of name, address and recipient type (eg. {@link RecipientType#CC}).
116         *
117         * @param name The name of the recipient.
118         * @param address The emailadres of the recipient.
119         * @param type The type of receiver (eg. {@link RecipientType#CC}).
120         * @see #recipients
121         * @see Recipient
122         * @see RecipientType
123         */
124        public void addRecipient(final String name, final String address, final RecipientType type) {
125                recipients.add(new Recipient(name, address, type));
126        }
127
128        /**
129         * Adds an embedded image (attachment type) to the email message and generates the necessary {@link DataSource} with the given byte
130         * data. Then delegates to {@link #addEmbeddedImage(String, DataSource)}. At this point the datasource is actually a
131         * {@link ByteArrayDataSource}.
132         *
133         * @param name The name of the image as being referred to from the message content body (eg. '&lt;cid:signature&gt;').
134         * @param data The byte data of the image to be embedded.
135         * @param mimetype The content type of the given data (eg. "image/gif" or "image/jpeg").
136         * @see ByteArrayDataSource
137         * @see #addEmbeddedImage(String, DataSource)
138         */
139        public void addEmbeddedImage(final String name, final byte[] data, final String mimetype) {
140                final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype);
141                dataSource.setName(name);
142                addEmbeddedImage(name, dataSource);
143        }
144
145        /**
146         * Overloaded method which sets an embedded image on account of name and {@link DataSource}.
147         *
148         * @param name The name of the image as being referred to from the message content body (eg. '&lt;cid:embeddedimage&gt;').
149         * @param imagedata The image data.
150         */
151        public void addEmbeddedImage(final String name, final DataSource imagedata) {
152                embeddedImages.add(new AttachmentResource(name, imagedata));
153        }
154
155        /**
156         * Adds a header to the {@link #headers} list. The value is stored as a <code>String</code>.
157         * <p>
158         * example: <code>email.addHeader("X-Priority", 2)</code>
159         *
160         * @param name The name of the header.
161         * @param value The value of the header, which will be stored using {@link String#valueOf(Object)}.
162         */
163        public void addHeader(final String name, final Object value) {
164                headers.put(name, String.valueOf(value));
165        }
166
167        /**
168         * Adds an attachment to the email message and generates the necessary {@link DataSource} with the given byte data. Then delegates to
169         * {@link #addAttachment(String, DataSource)}. At this point the datasource is actually a {@link ByteArrayDataSource}.
170         *
171         * @param name The name of the extension (eg. filename including extension).
172         * @param data The byte data of the attachment.
173         * @param mimetype The content type of the given data (eg. "plain/text", "image/gif" or "application/pdf").
174         * @see ByteArrayDataSource
175         * @see #addAttachment(String, DataSource)
176         */
177        public void addAttachment(final String name, final byte[] data, final String mimetype) {
178                final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype);
179                dataSource.setName(name);
180                addAttachment(name, dataSource);
181        }
182
183        /**
184         * Overloaded method which sets an attachment on account of name and {@link DataSource}.
185         *
186         * @param name The name of the attachment (eg. 'filename.ext').
187         * @param filedata The attachment data.
188         */
189        public void addAttachment(final String name, final DataSource filedata) {
190                attachments.add(new AttachmentResource(name, filedata));
191        }
192
193        /**
194         * Bean getter for {@link #fromRecipient}.
195         */
196        public Recipient getFromRecipient() {
197                return fromRecipient;
198        }
199
200        /**
201         * Bean getter for {@link #replyToRecipient}.
202         */
203        public Recipient getReplyToRecipient() {
204                return replyToRecipient;
205        }
206
207        /**
208         * Bean getter for {@link #subject}.
209         */
210        public String getSubject() {
211                return subject;
212        }
213
214        /**
215         * Bean getter for {@link #text}.
216         */
217        public String getText() {
218                return text;
219        }
220
221        /**
222         * Bean getter for {@link #textHTML}.
223         */
224        public String getTextHTML() {
225                return textHTML;
226        }
227
228        /**
229         * Bean getter for {@link #attachments} as unmodifiable list.
230         */
231        public List<AttachmentResource> getAttachments() {
232                return Collections.unmodifiableList(attachments);
233        }
234
235        /**
236         * Bean getter for {@link #embeddedImages} as unmodifiable list.
237         */
238        public List<AttachmentResource> getEmbeddedImages() {
239                return Collections.unmodifiableList(embeddedImages);
240        }
241
242        /**
243         * Bean getter for {@link #recipients} as unmodifiable list.
244         */
245        public List<Recipient> getRecipients() {
246                return Collections.unmodifiableList(recipients);
247        }
248
249        /**
250         * Bean getter for {@link #headers} as unmodifiable map.
251         */
252        public Map<String, String> getHeaders() {
253                return Collections.unmodifiableMap(headers);
254        }
255
256        /**
257         * Fluent interface Builder for Emails
258         * @author Jared Stewart
259         */
260        public static class Builder {
261                private Recipient fromRecipient;
262                /**
263                 * The reply-to-address, optional. Can be used in conjunction with {@link #fromRecipient}.
264                 */
265                private Recipient replyToRecipient;
266
267                /**
268                 * The email message body in plain text.
269                 */
270                private String text;
271
272                /**
273                 * The email message body in html.
274                 */
275                private String textHTML;
276
277                /**
278                 * The subject of the email message.
279                 */
280                private String subject;
281
282                /**
283                 * List of {@link Recipient}.
284                 */
285                private final List<Recipient> recipients;
286
287                /**
288                 * List of {@link AttachmentResource}.
289                 */
290                private final List<AttachmentResource> embeddedImages;
291
292                /**
293                 * List of {@link AttachmentResource}.
294                 */
295                private final List<AttachmentResource> attachments;
296
297                /**
298                 * Map of header name and values, such as <code>X-Priority</code> etc.
299                 */
300                private final Map<String, String> headers;
301
302                private Email email;
303
304                public Builder() {
305                        recipients = new ArrayList<Recipient>();
306                        embeddedImages = new ArrayList<AttachmentResource>();
307                        attachments = new ArrayList<AttachmentResource>();
308                        headers = new HashMap<String, String>();
309                }
310
311                /**
312                 *
313                 */
314                public Email build() {
315                        return new Email(this);
316                }
317
318                /**
319                 * Sets the sender address.
320                 *
321                 * @param name The sender's name.
322                 * @param fromAddress The sender's email address.
323                 */
324                public Builder from(final String name, final String fromAddress){
325                        this.fromRecipient = new Recipient(name, fromAddress, null);
326                        return this;
327                }
328
329                /**
330                 * Sets the reply-to address (optional).
331                 *
332                 * @param name The replied-to-receiver name.
333                 * @param replyToAddress The replied-to-receiver email address.
334                 */
335                public Builder replyTo(final String name, final String replyToAddress) {
336                        this.replyToRecipient = new Recipient(name, replyToAddress, null);
337                        return this;
338                }
339
340
341                /**
342                 * Sets the {@link #subject}.
343                 */
344                public Builder subject(final String subject) {
345                        this.subject = subject;
346                        return this;
347                }
348
349                /**
350                 * Sets the {@link #text}.
351                 */
352                public Builder text(final String text) {
353                        this.text = text;
354                        return this;
355                }
356
357                /**
358                 * Sets the {@link #textHTML}.
359                 */
360                public Builder textHTML(final String textHTML) {
361                        this.textHTML = textHTML;
362                        return this;
363                }
364
365                /**
366                 * Adds a new {@link Recipient} to the list on account of name, address with recipient type {@link RecipientType#TO}.
367                 *
368                 * @param name The name of the recipient.
369                 * @param address The emailaddress of the recipient.
370                 * @see #recipients
371                 * @see Recipient
372                 */
373                public Builder to(final String name, final String address) {
374                        recipients.add(new Recipient(name, address, RecipientType.TO));
375                        return this;
376                }
377
378                /**
379                 * Adds a new {@link Recipient} to the list on account of name, address with recipient type {@link RecipientType#TO}.
380                 *
381                 * @param recipient The recipent whose name and address to use
382                 * @see #recipients
383                 * @see Recipient
384                 */
385                public Builder to(final Recipient recipient) {
386                        recipients.add(new Recipient(recipient.getName(), recipient.getAddress(), RecipientType.TO));
387                        return this;
388                }
389
390
391
392                /**
393                 * Adds a new {@link Recipient} to the list on account of name, address with recipient type {@link RecipientType#CC}.
394                 *
395                 * @param name The name of the recipient.
396                 * @param address The emailaddress of the recipient.
397                 * @see #recipients
398                 * @see Recipient
399                 */
400                public Builder cc(final String name, final String address) {
401                        recipients.add(new Recipient(name, address, RecipientType.CC));
402                        return this;
403                }
404
405                /**
406                 * Adds a new {@link Recipient} to the list on account of name, address with recipient type {@link RecipientType#CC}.
407                 *
408                 * @param recipient The recipent whose name and address to use
409                 * @see #recipients
410                 * @see Recipient
411                 */
412                public Builder cc(final Recipient recipient) {
413                        recipients.add(new Recipient(recipient.getName(), recipient.getAddress(), RecipientType.CC));
414                        return this;
415                }
416
417                /**
418                 * Adds a new {@link Recipient} to the list on account of name, address with recipient type {@link RecipientType#BCC}.
419                 *
420                 * @param name The name of the recipient.
421                 * @param address The emailaddress of the recipient.
422                 * @see #recipients
423                 * @see Recipient
424                 */
425                public Builder bcc(final String name, final String address) {
426                        recipients.add(new Recipient(name, address, RecipientType.BCC));
427                        return this;
428                }
429
430                /**
431                 * Adds a new {@link Recipient} to the list on account of name, address with recipient type {@link RecipientType#BCC}.
432                 *
433                 * @param recipient The recipent whose name and address to use
434                 * @see #recipients
435                 * @see Recipient
436                 */
437                public Builder bcc(final Recipient recipient) {
438                        recipients.add(new Recipient(recipient.getName(), recipient.getAddress(), RecipientType.BCC));
439                        return this;
440                }
441
442                /**
443                 * Adds an embedded image (attachment type) to the email message and generates the necessary {@link DataSource} with the given byte
444                 * data. Then delegates to {@link #addEmbeddedImage(String, DataSource)}. At this point the datasource is actually a
445                 * {@link ByteArrayDataSource}.
446                 *
447                 * @param name The name of the image as being referred to from the message content body (eg. '&lt;cid:signature&gt;').
448                 * @param data The byte data of the image to be embedded.
449                 * @param mimetype The content type of the given data (eg. "image/gif" or "image/jpeg").
450                 * @see ByteArrayDataSource
451                 * @see #addEmbeddedImage(String, DataSource)
452                 */
453                public Builder embedImage(final String name, final byte[] data, final String mimetype) {
454                        final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype);
455                        dataSource.setName(name);
456                        return embedImage(name, dataSource);
457                }
458
459                /**
460                 * Overloaded method which sets an embedded image on account of name and {@link DataSource}.
461                 *
462                 * @param name The name of the image as being referred to from the message content body (eg. '&lt;cid:embeddedimage&gt;').
463                 * @param imagedata The image data.
464                 */
465                public Builder embedImage(final String name, final DataSource imagedata) {
466                        embeddedImages.add(new AttachmentResource(name, imagedata));
467                        return this;
468                }
469
470                /**
471                 * Adds a header to the {@link #headers} list. The value is stored as a <code>String</code>.
472                 * <p>
473                 * example: <code>email.addHeader("X-Priority", 2)</code>
474                 *
475                 * @param name The name of the header.
476                 * @param value The value of the header, which will be stored using {@link String#valueOf(Object)}.
477                 */
478                public Builder addHeader(final String name, final Object value) {
479                        headers.put(name, String.valueOf(value));
480                        return this;
481                }
482
483                /**
484                 * Adds an attachment to the email message and generates the necessary {@link DataSource} with the given byte data. Then delegates to
485                 * {@link #addAttachment(String, DataSource)}. At this point the datasource is actually a {@link ByteArrayDataSource}.
486                 *
487                 * @param name The name of the extension (eg. filename including extension).
488                 * @param data The byte data of the attachment.
489                 * @param mimetype The content type of the given data (eg. "plain/text", "image/gif" or "application/pdf").
490                 * @see ByteArrayDataSource
491                 * @see #addAttachment(String, DataSource)
492                 */
493                public void addAttachment(final String name, final byte[] data, final String mimetype) {
494                        final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, mimetype);
495                        dataSource.setName(name);
496                        addAttachment(name, dataSource);
497                }
498
499                /**
500                 * Overloaded method which sets an attachment on account of name and {@link DataSource}.
501                 *
502                 * @param name The name of the attachment (eg. 'filename.ext').
503                 * @param filedata The attachment data.
504                 */
505                public void addAttachment(final String name, final DataSource filedata) {
506                        attachments.add(new AttachmentResource(name, filedata));
507                }
508
509        }
510
511        /**
512         * Constructor for the Builder class
513         * @param builder The builder from which to create the email.
514         */
515        private Email(Builder builder) {
516                recipients = builder.recipients;
517                embeddedImages = builder.embeddedImages;
518                attachments = builder.attachments;
519                headers = builder.headers;
520
521                fromRecipient = builder.fromRecipient;
522                replyToRecipient = builder.replyToRecipient;
523                text = builder.text;
524                textHTML = builder.textHTML;
525                subject = builder.subject;
526        }
527}