1 package org.apache.turbine.util.velocity;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import javax.mail.MessagingException;
20
21 import org.apache.commons.lang.StringUtils;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import org.apache.commons.mail.SimpleEmail;
27
28 import org.apache.turbine.Turbine;
29 import org.apache.turbine.TurbineConstants;
30 import org.apache.turbine.services.velocity.TurbineVelocity;
31
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,v 1.11.2.2 2004/05/20 03:28:01 seade Exp $
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 }
126
127 /***
128 * Constructor
129 */
130 public VelocityEmail(Context context)
131 {
132 this.context = context;
133 }
134
135 /***
136 * To: toName, toEmail
137 *
138 * @param toName A String with the TO toName.
139 * @param toEmail A String with the TO toEmail.
140 * @deprecated use addTo(email,name) instead
141 * @throws MessagingException email address could not be parsed
142 * @return A VelocityEmail (self).
143 */
144 public VelocityEmail setTo(String toName, String toEmail)
145 throws MessagingException
146 {
147 addTo(toEmail,toName);
148 return this;
149 }
150
151 /***
152 * Velocity template to execute. Path is relative to the Velocity
153 * templates directory.
154 *
155 * @param template relative path of the template to parse including the
156 * filename.
157 * @return A VelocityEmail (self).
158 */
159 public VelocityEmail setTemplate(String template)
160 {
161 this.template = template;
162 return this;
163 }
164
165 /***
166 * Set the column at which long lines of text should be word-
167 * wrapped. Setting to zero turns off word-wrap (default).
168 *
169 * NOTE: don't use tabs in your email template document,
170 * or your word-wrapping will be off for the lines with tabs
171 * in them.
172 *
173 * @param wordWrap The column at which to wrap long lines.
174 * @return A VelocityEmail (self).
175 */
176 public VelocityEmail setWordWrap(int wordWrap)
177 {
178 this.wordWrap = wordWrap;
179 return this;
180 }
181
182 /***
183 * Set the context object that will be merged with the
184 * template.
185 *
186 * @param context A Velocity context object.
187 * @return A VelocityEmail (self).
188 */
189 public VelocityEmail setContext(Context context)
190 {
191 this.context = context;
192 return this;
193 }
194
195 /***
196 * Get the context object that will be merged with the
197 * template.
198 *
199 * @return A Context (self).
200 */
201 public Context getContext()
202 {
203 return this.context;
204 }
205
206 /***
207 * Sets the address of the outgoing mail server. This method
208 * should be used when you need to override the value stored in
209 * TR.props.
210 *
211 * @param serverAddress host name of your outgoing mail server
212 */
213 public void setMailServer(String serverAddress)
214 {
215 this.mailServer = serverAddress;
216 }
217
218 /***
219 * Gets the host name of the outgoing mail server. If the server
220 * name has not been set by calling setMailServer(), the value
221 * from TR.props for mail.server will be returned. If TR.props
222 * has no value for mail.server, localhost will be returned.
223 *
224 * @return host name of the mail server.
225 */
226 public String getMailServer()
227 {
228 return StringUtils.isNotEmpty(mailServer) ? mailServer
229 : Turbine.getConfiguration().getString(
230 TurbineConstants.MAIL_SERVER_KEY,
231 TurbineConstants.MAIL_SERVER_DEFAULT);
232 }
233
234 /***
235 * This method sends the email.
236 * <p>If the mail server was not set by calling, setMailServer()
237 * the value of mail.server will be used from TR.props. If that
238 * value was not set, localhost is used.
239 *
240 * @throws MessagingException Failure during merging the velocity
241 * template or sending the email.
242 */
243 public void send() throws MessagingException
244 {
245 String body = null;
246 try
247 {
248
249 body = TurbineVelocity.handleRequest(context, template);
250 }
251 catch (Exception e)
252 {
253 throw new MessagingException(
254 "Could not render velocitty template", e);
255 }
256
257
258 if (wordWrap > 0)
259 {
260 body = org.apache.turbine.util.StringUtils.wrapText(body,
261 System.getProperty("line.separator"), wordWrap);
262 }
263
264 setMsg(body);
265 setHostName(getMailServer());
266 super.send();
267 }
268
269 /***
270 * The method toString() calls send() for ease of use within a
271 * Velocity template (see example usage above).
272 *
273 * @return An empty string.
274 */
275 public String toString()
276 {
277 try
278 {
279 send();
280 }
281 catch (Exception e)
282 {
283 log.error("VelocityEmail error", e);
284 }
285 return "";
286 }
287 }