View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jelly.tags.email;
17  
18  import org.apache.commons.jelly.TagSupport;
19  import org.apache.commons.jelly.XMLOutput;
20  import org.apache.commons.jelly.JellyTagException;
21  import org.apache.commons.jelly.expression.Expression;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.commons.logging.Log;
24  
25  import javax.mail.Session;
26  import javax.mail.Message;
27  import javax.mail.MessagingException;
28  import javax.mail.Multipart;
29  import javax.mail.Transport;
30  import javax.mail.internet.AddressException;
31  import javax.mail.internet.MimeMessage;
32  import javax.mail.internet.InternetAddress;
33  import javax.mail.internet.MimeBodyPart;
34  import javax.mail.internet.MimeMultipart;
35  import javax.activation.FileDataSource;
36  import javax.activation.DataHandler;
37  
38  import java.util.Properties;
39  import java.util.StringTokenizer;
40  import java.util.Date;
41  import java.io.File;
42  import java.io.FileNotFoundException;
43  
44  /***
45   * Basic tag for sending an email. Supports one attachment, multiple to addresses delimited by ";",
46   * multiple cc addresses, etc.
47   *
48   * @author  Jason Horman
49   * @author  <a href="mailto:willievu@yahoo.com">Willie Vu</a>
50   * @version  $Id: EmailTag.java 155420 2005-02-26 13:06:03Z dirkv $
51   */
52  
53  public class EmailTag extends TagSupport {
54      private Log logger = LogFactory.getLog(EmailTag.class);
55  
56      /*** smtp server */
57      private Expression server       = null;
58  
59      /*** who to send the message as */
60      private Expression from         = null;
61  
62      /*** who to send to */
63      private Expression to           = null;
64  
65      /*** who to cc */
66      private Expression cc           = null;
67  
68      /*** mail subject */
69      private Expression subject      = null;
70  
71      /*** mail message */
72      private Expression message      = null;
73  
74      /*** file attachment */
75      private File attachment     = null;
76  
77      /*** whether we should encode the XML body as text */
78      private boolean encodeXML = false;
79  
80      /***
81       * Set the smtp server for the message. If not set the system
82       * property "mail.smtp.host" will be used.
83       */
84      public void setServer(Expression server) {
85          this.server = server;
86      }
87  
88      /***
89       * Set the from address for the message
90       */
91      public void setFrom(Expression from) {
92          this.from = from;
93      }
94  
95      /***
96       * ";" seperated list of people to send to
97       */
98      public void setTo(Expression to) {
99          this.to = to;
100     }
101 
102     /***
103      * ";" seperated list of people to cc
104      */
105     public void setCC(Expression cc) {
106         this.cc = cc;
107     }
108 
109     /***
110      * Set the email subject
111      */
112     public void setSubject(Expression subject) {
113         this.subject = subject;
114     }
115 
116     /***
117      * Set the message body. This will override the Jelly tag body
118      */
119     public void setMessage(Expression message) {
120         this.message = message;
121     }
122 
123     /***
124      * Set the email attachment for the message. Only 1 attachment is supported right now
125      */
126     public void setAttach(File attachment) throws FileNotFoundException {
127         if (!attachment.exists()) {
128             throw new FileNotFoundException("attachment not found");
129         }
130 
131         this.attachment = attachment;
132     }
133 
134     /***
135      * Sets whether we should encode the XML body as text or not. The default
136      * is false so that the body will assumed to be valid XML
137      */
138     public void setEncodeXML(boolean encodeXML) {
139         this.encodeXML = encodeXML;
140     }
141 
142     /***
143      * Execute the tag
144      */
145     public void doTag(XMLOutput xmlOutput) throws JellyTagException {
146         Properties props = new Properties();
147         props.putAll(context.getVariables());
148 
149         // if a server was set then configure the system property
150         if (server != null) {
151             Object serverInput = this.server.evaluate(context);
152             props.put("mail.smtp.host", serverInput.toString());
153         }
154         else {
155             if (props.get("mail.smtp.host") == null) {
156                 throw new JellyTagException("no smtp server configured");
157             }
158         }
159 
160         // check if there was no to address
161         if (to == null) {
162             throw new JellyTagException("no to address specified");
163         }
164 
165         // check if there was no from
166         if (from == null) {
167             throw new JellyTagException("no from address specified");
168         }
169 
170         String messageBody = null;
171         if (this.message != null) {
172             messageBody = this.message.evaluate(context).toString();
173         }
174         else {
175             // get message from body
176             messageBody = getBodyText(encodeXML);
177         }
178 
179         Object fromInput = this.from.evaluate(context);
180         Object toInput = this.to.evaluate(context);
181 
182         // configure the mail session
183         Session session = Session.getDefaultInstance(props, null);
184 
185         // construct the mime message
186         MimeMessage msg = new MimeMessage(session);
187 
188         try {
189             // set the from address
190             msg.setFrom(new InternetAddress(fromInput.toString()));
191 
192             // parse out the to addresses
193             StringTokenizer st = new StringTokenizer(toInput.toString(), ";");
194             InternetAddress[] addresses = new InternetAddress[st.countTokens()];
195             int addressCount = 0;
196             while (st.hasMoreTokens()) {
197                 addresses[addressCount++] = new InternetAddress(st.nextToken().trim());
198             }
199 
200             // set the recipients
201             msg.setRecipients(Message.RecipientType.TO, addresses);
202 
203             // parse out the cc addresses
204             if (cc != null) {
205                 Object ccInput = this.cc.evaluate(context);
206                 st = new StringTokenizer(ccInput.toString(), ";");
207                 InternetAddress[] ccAddresses = new InternetAddress[st.countTokens()];
208                 int ccAddressCount = 0;
209                 while (st.hasMoreTokens()) {
210                     ccAddresses[ccAddressCount++] = new InternetAddress(st.nextToken().trim());
211                 }
212 
213                 // set the cc recipients
214                 msg.setRecipients(Message.RecipientType.CC, ccAddresses);
215             }
216         }
217         catch (AddressException e) {
218             throw new JellyTagException(e);
219         }
220         catch (MessagingException e) {
221             throw new JellyTagException(e);
222         }
223 
224         try {
225             // set the subject
226             if (subject != null) {
227                 Object subjectInput = this.subject.evaluate(context);
228                 msg.setSubject(subjectInput.toString());
229             }
230 
231             // set a timestamp
232             msg.setSentDate(new Date());
233 
234             // if there was no attachment just set the text/body of the message
235             if (attachment == null) {
236 
237                 msg.setText(messageBody);
238 
239             }
240             else {
241 
242                 // attach the multipart mime message
243                 // setup the body
244                 MimeBodyPart mbp1 = new MimeBodyPart();
245                 mbp1.setText(messageBody);
246 
247                 // setup the attachment
248                 MimeBodyPart mbp2 = new MimeBodyPart();
249                 FileDataSource fds = new FileDataSource(attachment);
250                 mbp2.setDataHandler(new DataHandler(fds));
251                 mbp2.setFileName(fds.getName());
252 
253                 // create the multipart and add its parts
254                 Multipart mp = new MimeMultipart();
255                 mp.addBodyPart(mbp1);
256                 mp.addBodyPart(mbp2);
257 
258                 msg.setContent(mp);
259 
260             }
261 
262             logger.info("sending email to " + to + " using " + server);
263 
264             // send the email
265             Transport.send(msg);
266         }
267         catch (MessagingException e) {
268             throw new JellyTagException(e);
269         }
270 
271     }
272 }