001: package org.apache.turbine.util.velocity;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License")
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.net.URL;
020:
021: import java.util.Hashtable;
022:
023: import org.apache.commons.lang.StringUtils;
024:
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027:
028: import org.apache.commons.mail.EmailException;
029: import org.apache.commons.mail.HtmlEmail;
030:
031: import org.apache.turbine.Turbine;
032: import org.apache.turbine.TurbineConstants;
033: import org.apache.turbine.services.velocity.TurbineVelocity;
034: import org.apache.turbine.util.RunData;
035:
036: import org.apache.velocity.context.Context;
037:
038: /**
039: * This is a simple class for sending html email from within Velocity.
040: * Essentially, the bodies (text and html) of the email are a Velocity
041: * Context objects. The beauty of this is that you can send email
042: * from within your Velocity template or from your business logic in
043: * your Java code. The body of the email is just a Velocity template
044: * so you can use all the template functionality of Velocity within
045: * your emails!
046: *
047: * <p>This class allows you to send HTML email with embedded content
048: * and/or with attachments. You can access the VelocityHtmlEmail
049: * instance within your templates trough the <code>$mail</code>
050: * Velocity variable.
051: * <p><code>VelocityHtmlEmail myEmail= new VelocityHtmlEmail(data);<br>
052: * context.put("mail", myMail);</code>
053: * <b>or</b>
054: * <code>VelocityHtmlEmail myEmail= new VelocityHtmlEmail(context);<br>
055: * context.put("mail", myMail);</code>
056: *
057: *
058: * <p>The templates should be located under your Template turbine
059: * directory.
060: *
061: * <p>This class wraps the HtmlEmail class from commons-email. Thus, it uses
062: * the JavaMail API and also depends on having the mail.server property
063: * set in the TurbineResources.properties file. If you want to use
064: * this class outside of Turbine for general processing that is also
065: * possible by making sure to set the path to the
066: * TurbineResources.properties. See the
067: * TurbineResourceService.setPropertiesFileName() method for more
068: * information.
069: *
070: * <p>This class is basically a conversion of the WebMacroHtmlEmail
071: * written by Regis Koenig
072: *
073: * <p>You can turn on debugging for the JavaMail API by calling
074: * setDebug(true). The debugging messages will be written to System.out.
075: *
076: * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
077: * @author <a href="mailto:A.Schild@aarboard.ch">Andre Schild</a>
078: * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
079: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
080: * @version $Id: VelocityHtmlEmail.java 264148 2005-08-29 14:21:04Z henning $
081: */
082: public class VelocityHtmlEmail extends HtmlEmail {
083: /** Logging */
084: private static Log log = LogFactory.getLog(VelocityHtmlEmail.class);
085:
086: /**
087: * The html template to process, relative to VM's template
088: * directory.
089: */
090: private String htmlTemplate = null;
091:
092: /**
093: * The text template to process, relative to VM's template
094: * directory.
095: */
096: private String textTemplate = null;
097:
098: /** The cached context object. */
099: private Context context = null;
100:
101: /** The map of embedded files. */
102: private Hashtable embmap = null;
103:
104: /** Address of outgoing mail server */
105: private String mailServer;
106:
107: /**
108: * Constructor, sets the context object from the passed RunData object
109: *
110: * @param data A Turbine RunData object.
111: */
112: public VelocityHtmlEmail(RunData data) {
113: this .context = TurbineVelocity.getContext(data);
114: embmap = new Hashtable();
115: }
116:
117: /**
118: * Constructor, sets the context object.
119: *
120: * @param context A Velocity context object.
121: */
122: public VelocityHtmlEmail(Context context) {
123: this .context = context;
124: embmap = new Hashtable();
125: }
126:
127: /**
128: * Set the HTML template for the mail. This is the Velocity
129: * template to execute for the HTML part. Path is relative to the
130: * VM templates directory.
131: *
132: * @param template A String.
133: * @return A VelocityHtmlEmail (self).
134: */
135: public VelocityHtmlEmail setHtmlTemplate(String template) {
136: this .htmlTemplate = template;
137: return this ;
138: }
139:
140: /**
141: * Set the text template for the mail. This is the Velocity
142: * template to execute for the text part. Path is relative to the
143: * VM templates directory
144: *
145: * @param template A String.
146: * @return A VelocityHtmlEmail (self).
147: */
148: public VelocityHtmlEmail setTextTemplate(String template) {
149: this .textTemplate = template;
150: return this ;
151: }
152:
153: /**
154: * Sets the address of the outgoing mail server. This method
155: * should be used when you need to override the value stored in
156: * TR.props.
157: *
158: * @param serverAddress host name of your outgoing mail server
159: */
160: public void setMailServer(String serverAddress) {
161: this .mailServer = serverAddress;
162: }
163:
164: /**
165: * Gets the host name of the outgoing mail server. If the server
166: * name has not been set by calling setMailServer(), the value
167: * from TR.props for mail.server will be returned. If TR.props
168: * has no value for mail.server, localhost will be returned.
169: *
170: * @return host name of the mail server.
171: */
172: public String getMailServer() {
173: return StringUtils.isNotEmpty(mailServer) ? mailServer
174: : Turbine.getConfiguration().getString(
175: TurbineConstants.MAIL_SERVER_KEY,
176: TurbineConstants.MAIL_SERVER_DEFAULT);
177: }
178:
179: /**
180: * Actually send the mail.
181: *
182: * @exception EmailException thrown if mail cannot be sent.
183: */
184: public String send() throws EmailException {
185: context.put("mail", this );
186:
187: try {
188: if (htmlTemplate != null) {
189: setHtmlMsg(TurbineVelocity.handleRequest(context,
190: htmlTemplate));
191: }
192: if (textTemplate != null) {
193: setTextMsg(TurbineVelocity.handleRequest(context,
194: textTemplate));
195: }
196: } catch (Exception e) {
197: throw new EmailException("Cannot parse velocity template",
198: e);
199: }
200: setHostName(getMailServer());
201: return super .send();
202: }
203:
204: /**
205: * Embed a file in the mail. The file can be referenced through
206: * its Content-ID. This function also registers the CID in an
207: * internal map, so the embedded file can be referenced more than
208: * once by using the getCid() function. This may be useful in a
209: * template.
210: *
211: * <p>Example of template:
212: *
213: * <code><pre width="80">
214: * <html>
215: * <!-- $mail.embed("http://server/border.gif","border.gif"); -->
216: * <img src=$mail.getCid("border.gif")>
217: * <p>This is your content
218: * <img src=$mail.getCid("border.gif")>
219: * </html>
220: * </pre></code>
221: *
222: * @param surl A String.
223: * @param name A String.
224: * @return A String with the cid of the embedded file.
225: * @exception VelocityEmailException
226: * @see HtmlEmail#embed(URL surl, String name) embed.
227: */
228: public String embed(String surl, String name)
229: throws VelocityEmailException {
230: String cid = "";
231: try {
232: URL url = new URL(surl);
233: cid = embed(url, name);
234: } catch (Exception e) {
235: log.error("cannot embed " + surl + ": ", e);
236: }
237: return cid;
238: }
239:
240: /**
241: * Get the cid of an embedded file.
242: *
243: * @param filename A String.
244: * @return A String with the cid of the embedded file.
245: * @see #embed(String surl, String name) embed.
246: */
247: public String getCid(String filename) {
248: String cid = (String) embmap.get(filename);
249: return "cid:" + cid;
250: }
251:
252: }
|