/* * Copyright 2002-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.listener; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.Hashtable; import java.util.Vector; import java.util.Properties; import java.util.Enumeration; import java.util.StringTokenizer; import org.apache.tools.ant.BuildEvent; import org.apache.tools.ant.DefaultLogger; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.email.EmailAddress; import org.apache.tools.ant.taskdefs.email.Message; import org.apache.tools.ant.taskdefs.email.Mailer; import org.apache.tools.ant.util.DateUtils; import org.apache.tools.ant.util.StringUtils; import org.apache.tools.mail.MailMessage; /** * Buffers log messages from DefaultLogger, and sends an e-mail with the * results. The following Project properties are used to send the mail. * * These properties are set using standard Ant property setting mechanisms * (<property>, command-line -D, etc). Ant properties can be overridden * by specifying the filename of a properties file in the * MailLogger.properties.file property . Any properties defined in that * file will override Ant properties. * * */ public class MailLogger extends DefaultLogger { /** Buffer in which the message is constructed prior to sending */ private StringBuffer buffer = new StringBuffer(); /** * Sends an e-mail with the log results. * * @param event the build finished event */ public void buildFinished(BuildEvent event) { super.buildFinished(event); Project project = event.getProject(); Hashtable properties = project.getProperties(); // overlay specified properties file (if any), which overrides project // settings Properties fileProperties = new Properties(); String filename = (String) properties.get("MailLogger.properties.file"); if (filename != null) { InputStream is = null; try { is = new FileInputStream(filename); fileProperties.load(is); } catch (IOException ioe) { // ignore because properties file is not required } finally { if (is != null) { try { is.close(); } catch (IOException e) { // ignore } } } } for (Enumeration e = fileProperties.keys(); e.hasMoreElements();) { String key = (String) e.nextElement(); String value = fileProperties.getProperty(key); properties.put(key, project.replaceProperties(value)); } boolean success = (event.getException() == null); String prefix = success ? "success" : "failure"; try { boolean notify = Project.toBoolean(getValue(properties, prefix + ".notify", "on")); if (!notify) { return; } String mailhost = getValue(properties, "mailhost", "localhost"); int port = Integer.parseInt(getValue(properties, "port", String.valueOf(MailMessage.DEFAULT_PORT))); String user = getValue(properties, "user", ""); String password = getValue(properties, "password", ""); boolean ssl = Project.toBoolean(getValue(properties, "ssl", "off")); String from = getValue(properties, "from", null); String replytoList = getValue(properties, "replyto", ""); String toList = getValue(properties, prefix + ".to", null); String subject = getValue(properties, prefix + ".subject", (success) ? "Build Success" : "Build Failure"); if (user.equals("") && password.equals("") && !ssl) { sendMail(mailhost, port, from, replytoList, toList, subject, buffer.substring(0)); } else { sendMimeMail(event.getProject(), mailhost, port, user, password, ssl, from, replytoList, toList, subject, buffer.substring(0)); } } catch (Exception e) { System.out.println("MailLogger failed to send e-mail!"); e.printStackTrace(System.err); } } /** * Receives and buffers log messages. * * @param message the message being logger */ protected void log(String message) { buffer.append(message).append(StringUtils.LINE_SEP); } /** * Gets the value of a property. * * @param properties Properties to obtain value from * @param name suffix of property name. "MailLogger." will be * prepended internally. * @param defaultValue value returned if not present in the properties. * Set to null to make required. * @return The value of the property, or default value. * @exception Exception thrown if no default value is specified and the * property is not present in properties. */ private String getValue(Hashtable properties, String name, String defaultValue) throws Exception { String propertyName = "MailLogger." + name; String value = (String) properties.get(propertyName); if (value == null) { value = defaultValue; } if (value == null) { throw new Exception("Missing required parameter: " + propertyName); } return value; } /** * Send the mail * @param mailhost mail server * @param port mail server port number * @param from from address * @param replyToList comma-separated replyto list * @param toList comma-separated recipient list * @param subject mail subject * @param message mail body * @exception IOException thrown if sending message fails */ private void sendMail(String mailhost, int port, String from, String replyToList, String toList, String subject, String message) throws IOException { MailMessage mailMessage = new MailMessage(mailhost, port); mailMessage.setHeader("Date", DateUtils.getDateForHeader()); mailMessage.from(from); if (!replyToList.equals("")) { StringTokenizer t = new StringTokenizer(replyToList, ", ", false); while (t.hasMoreTokens()) { mailMessage.replyto(t.nextToken()); } } StringTokenizer t = new StringTokenizer(toList, ", ", false); while (t.hasMoreTokens()) { mailMessage.to(t.nextToken()); } mailMessage.setSubject(subject); PrintStream ps = mailMessage.getPrintStream(); ps.println(message); mailMessage.sendAndClose(); } /** * Send the mail (MimeMail) * @param project current ant project * @param host mail server * @param port mail server port number * @param user user name for SMTP auth * @param password password for SMTP auth * @param ssl if true send message over SSL * @param from from address * @param replyToString comma-separated replyto list * @param toString comma-separated recipient list * @param subject mail subject * @param message mail body */ private void sendMimeMail(Project project, String host, int port, String user, String password, boolean ssl, String from, String replyToString, String toString, String subject, String message) { // convert the replyTo string into a vector of emailaddresses Mailer mailer = null; try { mailer = (Mailer) Class.forName("org.apache.tools.ant.taskdefs.email.MimeMailer") .newInstance(); } catch (Throwable e) { log("Failed to initialise MIME mail: " + e.getMessage()); return; } Vector replyToList = vectorizeEmailAddresses(replyToString); mailer.setHost(host); mailer.setPort(port); mailer.setUser(user); mailer.setPassword(password); mailer.setSSL(ssl); Message mymessage = new Message(message); mymessage.setProject(project); mailer.setMessage(mymessage); mailer.setFrom(new EmailAddress(from)); mailer.setReplyToList(replyToList); Vector toList = vectorizeEmailAddresses(toString); mailer.setToList(toList); mailer.setCcList(new Vector()); mailer.setBccList(new Vector()); mailer.setFiles(new Vector()); mailer.setSubject(subject); mailer.send(); } private Vector vectorizeEmailAddresses(String listString) { Vector emailList = new Vector(); StringTokenizer tokens = new StringTokenizer(listString, ","); while (tokens.hasMoreTokens()) { emailList.addElement(new EmailAddress(tokens.nextToken())); } return emailList; } }