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