View Javadoc

1   package org.apache.turbine.util.velocity;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.apache.commons.lang.WordUtils;
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.commons.mail.EmailException;
24  import org.apache.commons.mail.SimpleEmail;
25  import org.apache.turbine.Turbine;
26  import org.apache.turbine.TurbineConstants;
27  import org.apache.turbine.services.velocity.TurbineVelocity;
28  import org.apache.velocity.context.Context;
29  
30  /***
31   * This is a simple class for sending email from within Velocity.
32   * Essentially, the body of the email is processed with a
33   * Velocity Context object.
34   * The beauty of this is that you can send email from within your
35   * Velocity template or from your business logic in your Java code.
36   * The body of the email is just a Velocity template so you can use
37   * all the template functionality of Velocity within your emails!
38   *
39   * <p>Example Usage (This all needs to be on one line in your
40   * template):
41   *
42   * <p>Setup your context:
43   *
44   * <p><code>context.put ("VelocityEmail", new VelocityEmail() );</code>
45   *
46   * <p>Then, in your template:
47   *
48   * <pre>
49   * $VelocityEmail.setTo("Jon Stevens", "jon@latchkey.com")
50   *     .setFrom("Mom", "mom@mom.com").setSubject("Eat dinner")
51   *     .setTemplate("email/momEmail.vm")
52   *     .setContext($context)
53   * </pre>
54   *
55   * The email/momEmail.wm template will then be parsed with the
56   * Context that was defined with setContext().
57   *
58   * <p>If you want to use this class from within your Java code all you
59   * have to do is something like this:
60   *
61   * <pre>
62   * VelocityEmail ve = new VelocityEmail();
63   * ve.setTo("Jon Stevens", "jon@latchkey.com");
64   * ve.setFrom("Mom", "mom@mom.com").setSubject("Eat dinner");
65   * ve.setContext(context);
66   * ve.setTemplate("email/momEmail.vm")
67   * ve.send();
68   * </pre>
69   *
70   * <p>(Note that when used within a Velocity template, the send method
71   * will be called for you when Velocity tries to convert the
72   * VelocityEmail to a string by calling toString()).</p>
73   *
74   * <p>If you need your email to be word-wrapped, you can add the
75   * following call to those above:
76   *
77   * <pre>
78   * ve.setWordWrap (60);
79   * </pre>
80   *
81   * <p>This class is just a wrapper around the SimpleEmail class from
82   * commons-mail using the JavaMail API.
83   * Thus, it depends on having the
84   * mail.server property set in the TurbineResources.properties file.
85   * If you want to use this class outside of Turbine for general
86   * processing that is also possible by making sure to set the path to
87   * the TurbineResources.properties.  See the
88   * TurbineConfig class for more information.</p>
89   *
90   * <p>You can turn on debugging for the JavaMail API by calling
91   * setDebug(true).  The debugging messages will be written to System.out.
92   *
93   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
94   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
95   * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
96   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
97   * @version $Id: VelocityEmail.java 279822 2005-09-09 17:07:25Z henning $
98   */
99  public class VelocityEmail extends SimpleEmail
100 {
101     /*** Logging */
102     private static Log log = LogFactory.getLog(VelocityEmail.class);
103 
104     /*** The column to word-wrap at.  <code>0</code> indicates no wrap. */
105     private int wordWrap = 0;
106 
107     /*** Address of outgoing mail server */
108     private String mailServer;
109 
110     /*** The template to process, relative to Velocity template directory. */
111     private String template = null;
112 
113     /*** Velocity context */
114     private Context context = null;
115 
116     /***
117      * Constructor
118      */
119     public VelocityEmail()
120     {
121     }
122 
123     /***
124      * Constructor
125      */
126     public VelocityEmail(Context context)
127     {
128         this.context = context;
129     }
130 
131     /***
132      * To: toName, toEmail
133      *
134      * @param toName A String with the TO toName.
135      * @param toEmail A String with the TO toEmail.
136      * @deprecated use addTo(email,name) instead
137      * @throws EmailException email address could not be parsed
138      * @return A VelocityEmail (self).
139      */
140     public VelocityEmail setTo(String toName, String toEmail)
141             throws EmailException
142     {
143         addTo(toEmail,toName);
144         return this;
145     }
146 
147     /***
148      * Velocity template to execute. Path is relative to the Velocity
149      * templates directory.
150      *
151      * @param template relative path of the template to parse including the
152      *                 filename.
153      * @return A VelocityEmail (self).
154      */
155     public VelocityEmail setTemplate(String template)
156     {
157         this.template = template;
158         return this;
159     }
160 
161     /***
162      * Set the column at which long lines of text should be word-
163      * wrapped. Setting to zero turns off word-wrap (default).
164      *
165      * NOTE: don't use tabs in your email template document,
166      * or your word-wrapping will be off for the lines with tabs
167      * in them.
168      *
169      * @param wordWrap The column at which to wrap long lines.
170      * @return A VelocityEmail (self).
171      */
172     public VelocityEmail setWordWrap(int wordWrap)
173     {
174         this.wordWrap = wordWrap;
175         return this;
176     }
177 
178     /***
179      * Set the context object that will be merged with the
180      * template.
181      *
182      * @param context A Velocity context object.
183      * @return A VelocityEmail (self).
184      */
185     public VelocityEmail setContext(Context context)
186     {
187         this.context = context;
188         return this;
189     }
190 
191     /***
192      * Get the context object that will be merged with the
193      * template.
194      *
195      * @return A Context (self).
196      */
197     public Context getContext()
198     {
199         return this.context;
200     }
201 
202     /***
203      * Sets the address of the outgoing mail server.  This method
204      * should be used when you need to override the value stored in
205      * TR.props.
206      *
207      * @param serverAddress host name of your outgoing mail server
208      */
209     public void setMailServer(String serverAddress)
210     {
211         this.mailServer = serverAddress;
212     }
213 
214     /***
215      * Gets the host name of the outgoing mail server.  If the server
216      * name has not been set by calling setMailServer(), the value
217      * from TR.props for mail.server will be returned.  If TR.props
218      * has no value for mail.server, localhost will be returned.
219      *
220      * @return host name of the mail server.
221      */
222     public String getMailServer()
223     {
224         return StringUtils.isNotEmpty(mailServer) ? mailServer
225                 : Turbine.getConfiguration().getString(
226                 TurbineConstants.MAIL_SERVER_KEY,
227                 TurbineConstants.MAIL_SERVER_DEFAULT);
228     }
229 
230     /***
231      * This method sends the email.
232      * <p>If the mail server was not set by calling, setMailServer()
233      * the value of mail.server will be used from TR.props.  If that
234      * value was not set, localhost is used.
235      *
236      * @throws EmailException Failure during merging the velocity
237      * template or sending the email.
238      */
239     public String send() throws EmailException
240     {
241         String body = null;
242         try
243         {
244             // Process the template.
245             body = TurbineVelocity.handleRequest(context, template);
246         }
247         catch (Exception e)
248         {
249             throw new EmailException(
250                     "Could not render velocitty template", e);
251         }
252 
253         // If the caller desires word-wrapping, do it here
254         if (wordWrap > 0)
255         {
256             body = WordUtils.wrap(body, wordWrap,
257                     System.getProperty("line.separator"), false);
258         }
259 
260         setMsg(body);
261         setHostName(getMailServer());
262         return super.send();
263     }
264 
265     /***
266      * The method toString() calls send() for ease of use within a
267      * Velocity template (see example usage above).
268      *
269      * @return An empty string.
270      */
271     public String toString()
272     {
273         try
274         {
275             send();
276         }
277         catch (Exception e)
278         {
279             log.error("VelocityEmail error", e);
280         }
281         return "";
282     }
283 }