View Javadoc

1   package org.apache.fulcrum.template;
2   
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21   */
22  
23  
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.Iterator;
27  import java.io.StringWriter;
28  import javax.mail.internet.InternetAddress;
29  import org.apache.commons.mail.SimpleEmail;
30  import org.apache.fulcrum.util.WordWrapUtils;
31  
32  /**
33   * This is a simple class for sending email from within the TemplateService.
34   * Essentially, the body of the email is processed with a
35   * TemplateContext object.
36   * The beauty of this is that you can send email from within your
37   * template layer or from your business logic in your Java code.
38   * The body of the email is just a TemplateService template so you can use
39   * all the template functionality of your TemplateService within your emails!
40   *
41   * <p>Example Usage (This all needs to be on one line in your
42   * template):
43   *
44   * <p>Setup your imports:
45   *
46   * <p>import org.apache.fulcrum.template.TemplateEmail;
47   * <p>import org.apache.turbine.modules.ContextAdapter;
48   *
49   * <p>Setup your context:
50   *
51   * <p>context.put ("TemplateEmail", new TemplateEmail() );
52   * <p>context.put ("contextAdapter", new ContextAdapter(context) );
53   *
54   * <p>Then, in your template (Velocity Example):
55   *
56   * <pre>
57   * $TemplateEmail.setTo("Jon Stevens", "jon@latchkey.com")
58   *     .setFrom("Mom", "mom@mom.com").setSubject("Eat dinner")
59   *     .setTemplate("email/momEmail.vm")
60   *     .setContext($contextAdapter)
61   * </pre>
62   *
63   * The email/momEmail.vm template will then be parsed with the
64   * Context that was defined with setContext().
65   *
66   * <p>If you want to use this class from within your Java code all you
67   * have to do is something like this:
68   *
69   * <p>import org.apache.fulcrum.template.TemplateEmail;
70   * <p>import org.apache.turbine.modules.ContextAdapter;
71   *
72   * <pre>
73   * TemplateEmail ve = new TemplateEmail();
74   * ve.setTo("Jon Stevens", "jon@latchkey.com");
75   * ve.setFrom("Mom", "mom@mom.com").setSubject("Eat dinner");
76   * ve.setContext(new ContextAdapter(context));
77   * ve.setTemplate("email/momEmail.vm")
78   * ve.send();
79   * </pre>
80   *
81   * <p>(Note that when used within a Velocity template, the send method
82   * will be called for you when Velocity tries to convert the
83   * TemplateEmail to a string by calling toString()).</p>
84   *
85   * <p>If you need your email to be word-wrapped, you can add the
86   * following call to those above:
87   *
88   * <pre>
89   * ve.setWordWrap (60);
90   * </pre>
91   *
92   * <p>This class is just a wrapper around the SimpleEmail class.
93   * Thus, it uses the JavaMail API and also depends on having the
94   * mail.host property set in the System.properties().
95   *
96   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
97   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
98   * @author <a href="mailto:elicia@collab.net">Elicia David</a>
99   * @version $Id: TemplateEmail.java 535465 2007-05-05 06:58:06Z tv $
100  */
101 public class TemplateEmail
102 {
103     /** The to name field. */
104     private String toName = null;
105 
106     /** The to email field. */
107     private String toEmail = null;
108 
109     /** The from name field. */
110     private String fromName = null;
111 
112     /** The from email field. */
113     private String fromEmail = null;
114 
115     /** The cc name field. */
116     private String ccName = null;
117 
118     /** The cc email field. */
119     private String ccEmail = null;
120 
121     /** The subject of the message. */
122     private String subject = null;
123 
124     /** The to email list. */
125     private List toList = null;
126 
127     /** The cc list. */
128     private List ccList = null;
129 
130     /** The cc list. */
131     private List replyToList = null;
132 
133     /** The column to word-wrap at.  <code>0</code> indicates no wrap. */
134     private int wordWrap = 0;
135 
136     /**
137      * The template to process, relative to the TemplateService template
138      * directory.
139      */
140     private String template = null;
141 
142     /**
143      * A Context
144      */
145     private TemplateContext context = null;
146 
147     /**
148      * The charset
149      */
150     private String charset = null;
151 
152     /**
153      * The templateService to use in generating text
154      *
155      */
156     private TemplateService templateService;
157 
158     /**
159      * Constructor
160      */
161     public TemplateEmail()
162     {
163         this(null);
164     }
165 
166     /**
167      * Constructor
168      */
169     public TemplateEmail(TemplateContext context)
170     {
171         this.context = context;
172     }
173 
174     /** Add a recipient TO to the email.
175      *
176      * @param email A String.
177      * @param name A String.
178      */
179     public void addTo(String email, String name)
180         throws Exception
181     {
182         try
183         {
184             if ((name == null) || (name.trim().equals("")))
185             {
186                 name = email;
187             }
188 
189             if (toList == null)
190             {
191                 toList = new ArrayList();
192             }
193 
194             toList.add(new InternetAddress(email, name));
195         }
196         catch (Exception e)
197         {
198             throw new Exception("Cannot add 'To' recipient: " + e);
199         }
200     }
201 
202     /**
203      * Add a recipient CC to the email.
204      *
205      * @param email A String.
206      * @param name A String.
207      */
208     public void addCc(String email, String name)
209         throws Exception
210     {
211         try
212         {
213             if ((name == null) || (name.trim().equals("")))
214             {
215                 name = email;
216             }
217 
218             if (ccList == null)
219             {
220                 ccList = new ArrayList();
221             }
222 
223             ccList.add(new InternetAddress(email, name));
224         }
225         catch (Exception e)
226         {
227             throw new Exception("Cannot add 'CC' recipient: " + e);
228         }
229     }
230 
231 
232     /**
233      * The given Unicode string will be charset-encoded using the specified
234      * charset. The charset is also used to set the "charset" parameter.
235      *
236      * @param charset a <code>String</code> value
237      */
238     public void setCharset(String charset)
239     {
240         this.charset = charset;
241     }
242 
243     /**
244      * To: name, email
245      *
246      * @param to A String with the TO name.
247      * @param email A String with the TO email.
248      * @return A TemplateEmail (self).
249      */
250     public TemplateEmail setTo(String to,
251                                String email)
252     {
253         this.toName = to;
254         this.toEmail = email;
255         return (this);
256     }
257 
258     /**
259      * From: name, email.
260      *
261      * @param from A String with the FROM name.
262      * @param email A String with the FROM email.
263      * @return A TemplateEmail (self).
264      */
265     public TemplateEmail setFrom(String from,
266                                  String email)
267     {
268         this.fromName = from;
269         this.fromEmail = email;
270         return (this);
271     }
272 
273     /**
274      * CC: name, email.
275      *
276      * @param from A String with the CC name.
277      * @param email A String with the CC email.
278      * @return A TemplateEmail (self).
279      */
280     public TemplateEmail setCC(String cc,
281                                  String email)
282     {
283         this.ccName = cc;
284         this.ccEmail = email;
285         return (this);
286     }
287 
288 
289     /**
290      * Add a reply to address to the email.
291      *
292      * @param email A String.
293      * @param name A String.
294      * @return An Email.
295      * @exception MessagingException.
296      */
297     public TemplateEmail addReplyTo( String name, String email)
298     {
299         String[] emailName = new String[2];
300         emailName[0] = email;
301         emailName[1] = name;
302         if (replyToList == null)
303         {
304             replyToList = new ArrayList(3);
305         }
306         replyToList.add(emailName);
307         return this;
308     }
309 
310     private List headersList;
311     public TemplateEmail addHeader(String name, String value)
312     {
313         String[] pair = new String[2];
314         pair[0] = name;
315         pair[1] = value;
316         if (headersList == null)
317         {
318             headersList = new ArrayList(3);
319         }
320         headersList.add(pair);
321         return this;
322     }
323 
324     /**
325      * Subject.
326      *
327      * @param subject A String with the subject.
328      * @return A TemplateEmail (self).
329      */
330     public TemplateEmail setSubject(String subject)
331     {
332         if (subject == null)
333         {
334             this.subject = "";
335         }
336         else
337         {
338             this.subject = subject;
339         }
340         return (this);
341     }
342 
343     /**
344      * TemplateService template to execute. Path is relative to the
345      * TemplateService templates directory.
346      *
347      * @param template A String with the template.
348      * @return A TemplateEmail (self).
349      */
350     public TemplateEmail setTemplate(String template)
351     {
352         this.template = template;
353         return (this);
354     }
355 
356     /**
357      * Set the column at which long lines of text should be word-
358      * wrapped. Setting to zero turns off word-wrap (default).
359      *
360      * NOTE: don't use tabs in your email template document,
361      * or your word-wrapping will be off for the lines with tabs
362      * in them.
363      *
364      * @param wordWrap The column at which to wrap long lines.
365      * @return A TemplateEmail (self).
366      */
367     public TemplateEmail setWordWrap(int wordWrap)
368     {
369         this.wordWrap = wordWrap;
370         return (this);
371     }
372 
373     /**
374      * Set the context object that will be merged with the
375      * template.
376      *
377      * @param context A TemplateContext context object.
378      * @return A TemplateEmail (self).
379      */
380     public TemplateEmail setContext(TemplateContext context)
381     {
382         this.context = context;
383         return (this);
384     }
385 
386     /**
387      * Get the context object that will be merged with the
388      * template.
389      *
390      * @return A TemplateContext.
391      */
392     public TemplateContext getContext()
393     {
394         return this.context;
395     }
396 
397     /**
398      * This method sends the email. It will throw an exception
399      * if the To name or To Email values are null.
400      */
401     public void send()
402         throws Exception
403     {
404         if (toEmail == null || toName == null)
405         {
406             throw new Exception ("Must set a To:");
407         }
408 
409         // this method is only supposed to send to one user (additional cc:
410         // users are ok.)
411         toList = null;
412         addTo(toEmail, toName);
413         sendMultiple();
414     }
415 
416     /**
417      * This method sends the email to multiple addresses.
418      */
419     public void sendMultiple()
420         throws Exception
421     {
422         if (toList == null || toList.isEmpty())
423         {
424             throw new Exception ("Must set a To:");
425         }
426 
427         // Process the template.
428         StringWriter sw = new StringWriter();
429         templateService.handleRequest(context,template, sw);
430         String body = sw.toString();
431 
432         // If the caller desires word-wrapping, do it here
433         if (wordWrap > 0)
434         {
435             body = WordWrapUtils.wrapText (body,
436                                      System.getProperty("line.separator"),
437                                      wordWrap);
438         }
439 
440         SimpleEmail se = new SimpleEmail();
441         if (charset != null)
442         {
443             se.setCharset(charset);
444         }
445         se.setFrom(fromEmail, fromName);
446         se.setTo(toList);
447         if (ccList != null && !ccList.isEmpty())
448         {
449             se.setCc(ccList);
450         }
451         addReplyTo(se);
452         se.setSubject(subject);
453         se.setMsg(body);
454 
455         if (headersList != null)
456         {
457             Iterator i = headersList.iterator();
458             while (i.hasNext())
459             {
460                 String[] pair = (String[])i.next();
461                 se.addHeader(pair[0], pair[1]);
462             }
463         }
464 
465         se.send();
466     }
467 
468 
469 
470     /**
471      * A javabean style setter for passing in manually a templateservice
472      * @param templateService The templateService to set.
473      */
474     public void setTemplateService(TemplateService templateService) {
475         this.templateService = templateService;
476     }
477     /**
478      * if any reply-to email addresses exist, add them to the SimpleEmail
479      *
480      * @param se a <code>SimpleEmail</code> value
481      * @exception Exception if an error occurs
482      */
483     private void addReplyTo(SimpleEmail se)
484         throws Exception
485     {
486         if (replyToList != null)
487         {
488             Iterator i = replyToList.iterator();
489             while (i.hasNext())
490             {
491                 String[] emailName = (String[])i.next();
492                 se.addReplyTo(emailName[0], emailName[1]);
493             }
494         }
495     }
496 
497     /**
498      * The method toString() calls send() for ease of use within a
499      * TemplateService template (see example usage above).
500      *
501      * @return An empty string.
502      */
503     public String toString()
504     {
505         try
506         {
507             send();
508         }
509         catch (Exception e)
510         {
511 //            Log.error ("TemplateEmail error", e);
512         }
513         return "";
514     }
515 }