View Javadoc

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