View Javadoc

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