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