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  
24  import java.net.URL;
25  import java.util.Hashtable;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.commons.mail.EmailException;
31  import org.apache.commons.mail.HtmlEmail;
32  import org.apache.turbine.Turbine;
33  import org.apache.turbine.TurbineConstants;
34  import org.apache.turbine.pipeline.PipelineData;
35  import org.apache.turbine.services.velocity.TurbineVelocity;
36  import org.apache.turbine.util.RunData;
37  import org.apache.velocity.context.Context;
38  
39  /**
40   * This is a simple class for sending html email from within Velocity.
41   * Essentially, the bodies (text and html) of the email are a Velocity
42   * Context objects.  The beauty of this is that you can send email
43   * from within your Velocity template or from your business logic in
44   * your Java code.  The body of the email is just a Velocity template
45   * so you can use all the template functionality of Velocity within
46   * your emails!
47   *
48   * <p>This class allows you to send HTML email with embedded content
49   * and/or with attachments.  You can access the VelocityHtmlEmail
50   * instance within your templates trough the <code>$mail</code>
51   * Velocity variable.
52   * <p><code>VelocityHtmlEmail   myEmail= new VelocityHtmlEmail(data);<br>
53   *                              context.put("mail", myMail);</code>
54   * <b>or</b>
55   *    <code>VelocityHtmlEmail   myEmail= new VelocityHtmlEmail(context);<br>
56   *                              context.put("mail", myMail);</code>
57   *
58   *
59   * <p>The templates should be located under your Template turbine
60   * directory.
61   *
62   * <p>This class wraps the HtmlEmail class from commons-email.  Thus, it uses
63   * the JavaMail API and also depends on having the mail.server property
64   * set in the TurbineResources.properties file.  If you want to use
65   * this class outside of Turbine for general processing that is also
66   * possible by making sure to set the path to the
67   * TurbineResources.properties.  See the
68   * TurbineResourceService.setPropertiesFileName() method for more
69   * information.
70   *
71   * <p>This class is basically a conversion of the WebMacroHtmlEmail
72   * written by Regis Koenig
73   *
74   * <p>You can turn on debugging for the JavaMail API by calling
75   * setDebug(true).  The debugging messages will be written to System.out.
76   *
77   * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
78   * @author <a href="mailto:A.Schild@aarboard.ch">Andre Schild</a>
79   * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
80   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
81   * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
82   * @version $Id: VelocityHtmlEmail.java 929479 2010-03-31 11:24:21Z tv $
83   */
84  public class VelocityHtmlEmail extends HtmlEmail
85  {
86      /** Logging */
87      private static Log log = LogFactory.getLog(VelocityHtmlEmail.class);
88  
89      /**
90       * The html template to process, relative to VM's template
91       * directory.
92       */
93      private String htmlTemplate = null;
94  
95      /**
96       * The text template to process, relative to VM's template
97       * directory.
98       */
99      private String textTemplate = null;
100 
101     /** The cached context object. */
102     private Context context = null;
103 
104     /** The map of embedded files. */
105     private Hashtable embmap = null;
106 
107     /** Address of outgoing mail server */
108     private String mailServer;
109 
110     /**
111      * Constructor, sets the context object from the passed RunData object
112      * @deprecated use PipelineData version instead
113      * @param data A Turbine RunData object.
114      */
115     public VelocityHtmlEmail(RunData data)
116     {
117         this.context = TurbineVelocity.getContext(data);
118         embmap = new Hashtable();
119     }
120 
121     /**
122      * Constructor, sets the context object from the passed RunData object
123      *
124      * @param data A Turbine RunData object.
125      */
126     public VelocityHtmlEmail(PipelineData pipelineData)
127     {
128         this.context = TurbineVelocity.getContext(pipelineData);
129         embmap = new Hashtable();
130     }
131 
132     /**
133      * Constructor, sets the context object.
134      *
135      * @param context A Velocity context object.
136      */
137     public VelocityHtmlEmail(Context context)
138     {
139         this.context = context;
140         embmap = new Hashtable();
141     }
142 
143     /**
144      * Set the HTML template for the mail.  This is the Velocity
145      * template to execute for the HTML part.  Path is relative to the
146      * VM templates directory.
147      *
148      * @param template A String.
149      * @return A VelocityHtmlEmail (self).
150      */
151     public VelocityHtmlEmail setHtmlTemplate(String template)
152     {
153         this.htmlTemplate = template;
154         return this;
155     }
156 
157     /**
158      * Set the text template for the mail.  This is the Velocity
159      * template to execute for the text part.  Path is relative to the
160      * VM templates directory
161      *
162      * @param template A String.
163      * @return A VelocityHtmlEmail (self).
164      */
165     public VelocityHtmlEmail setTextTemplate(String template)
166     {
167         this.textTemplate = template;
168         return this;
169     }
170 
171     /**
172      * Sets the address of the outgoing mail server.  This method
173      * should be used when you need to override the value stored in
174      * TR.props.
175      *
176      * @param serverAddress host name of your outgoing mail server
177      */
178     public void setMailServer(String serverAddress)
179     {
180         this.mailServer = serverAddress;
181     }
182 
183     /**
184      * Gets the host name of the outgoing mail server.  If the server
185      * name has not been set by calling setMailServer(), the value
186      * from TR.props for mail.server will be returned.  If TR.props
187      * has no value for mail.server, localhost will be returned.
188      *
189      * @return host name of the mail server.
190      */
191     public String getMailServer()
192     {
193         return StringUtils.isNotEmpty(mailServer) ? mailServer
194                 : Turbine.getConfiguration().getString(
195                 TurbineConstants.MAIL_SERVER_KEY,
196                 TurbineConstants.MAIL_SERVER_DEFAULT);
197     }
198 
199     /**
200      * Actually send the mail.
201      *
202      * @exception EmailException thrown if mail cannot be sent.
203      */
204     public String send() throws EmailException
205     {
206         context.put("mail", this);
207 
208         try
209         {
210             if (htmlTemplate != null)
211             {
212                 setHtmlMsg(
213                         TurbineVelocity.handleRequest(context, htmlTemplate));
214             }
215             if (textTemplate != null)
216             {
217                 setTextMsg(
218                         TurbineVelocity.handleRequest(context, textTemplate));
219             }
220         }
221         catch (Exception e)
222         {
223             throw new EmailException("Cannot parse velocity template", e);
224         }
225         setHostName(getMailServer());
226         return super.send();
227     }
228 
229     /**
230      * Embed a file in the mail.  The file can be referenced through
231      * its Content-ID.  This function also registers the CID in an
232      * internal map, so the embedded file can be referenced more than
233      * once by using the getCid() function.  This may be useful in a
234      * template.
235      *
236      * <p>Example of template:
237      *
238      * <code><pre width="80">
239      * &lt;html&gt;
240      * &lt;!-- $mail.embed("http://server/border.gif","border.gif"); --&gt;
241      * &lt;img src=$mail.getCid("border.gif")&gt;
242      * &lt;p&gt;This is your content
243      * &lt;img src=$mail.getCid("border.gif")&gt;
244      * &lt;/html&gt;
245      * </pre></code>
246      *
247      * @param surl A String.
248      * @param name A String.
249      * @return A String with the cid of the embedded file.
250      * 
251      * @see HtmlEmail#embed(URL surl, String name) embed.
252      */
253     public String embed(String surl, String name)
254     {
255         String cid = "";
256         try
257         {
258             URL url = new URL(surl);
259             cid = embed(url, name);
260         }
261         catch (Exception e)
262         {
263             log.error("cannot embed " + surl + ": ", e);
264         }
265         return cid;
266     }
267 
268     /**
269      * Get the cid of an embedded file.
270      *
271      * @param filename A String.
272      * @return A String with the cid of the embedded file.
273      * @see #embed(String surl, String name) embed.
274      */
275     public String getCid(String filename)
276     {
277         String cid = (String) embmap.get(filename);
278         return "cid:" + cid;
279     }
280 
281 }