package org.cdlib.xtf.saxonExt.mail; /* * Copyright (c) 2007, Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the University of California nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ import java.util.ArrayList; import java.util.Map; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import org.cdlib.xtf.saxonExt.ElementWithContent; import org.cdlib.xtf.saxonExt.InstructionWithContent; import net.sf.saxon.expr.Expression; import net.sf.saxon.expr.XPathContext; import net.sf.saxon.instruct.Executable; import net.sf.saxon.instruct.TailCall; import net.sf.saxon.trans.DynamicError; import net.sf.saxon.trans.XPathException; /** * Implements a Saxon instruction that reads an image from the filesystem, * optionally modifies it in various ways, and outputs it directly via the * current HttpServletResponse. * * @author Martin Haye */ public class SendElement extends ElementWithContent { public void prepareAttributes() throws XPathException { String[] mandatoryAtts = { "smtpHost", "from", "to", "subject" }; String[] optionalAtts = { "smtpUser", "smtpPassword", "useSSL" }; parseAttributes(mandatoryAtts, optionalAtts); } public Expression compile(Executable exec) throws XPathException { return new SendInstruction(attribs, compileContent(exec)); } private static class SendInstruction extends InstructionWithContent { public SendInstruction(Map<String, Expression> attribs, Expression content) { super("mail:send", attribs, content); } public TailCall processLeavingTail(final XPathContext context) throws XPathException { boolean debug = false; try { // Determine the proper protocol String protocol = ""; String useSSL = attribs.get("useSSL").evaluateAsString(context); if (useSSL != null && useSSL.matches("^(yes|Yes|true|True|1)$")) protocol = "smtps"; else protocol = "smtp"; // If user name and password were specified, do authentication. boolean doAuth = attribs.containsKey("smtpUser") && attribs.containsKey("smtpPassword"); // Set up SMTP host and authentication information Properties props = new Properties(); String server = attribs.get("smtpHost").evaluateAsString(context); props.put("mail." + protocol + ".host", server); props.put("mail." + protocol + ".auth", doAuth ? "true" : "false"); // Create the mail session, with authentication if appropriate. Session session; if (doAuth) { Authenticator auth = new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { try { String username = attribs.get("smtpUser").evaluateAsString(context); String password = attribs.get("smtpPassword").evaluateAsString(context); return new PasswordAuthentication(username, password); } catch (XPathException e) { throw new RuntimeException(e); } } }; session = Session.getInstance(props, auth); } else session = Session.getInstance(props); // Set the debug mode on the session. session.setDebug(debug); // Create a message and specify who it's from MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(attribs.get("from").evaluateAsString(context))); // Parse a list of recipients, separated by commas. String recips = attribs.get("to").evaluateAsString(context).trim(); ArrayList<InternetAddress> addressTo = new ArrayList<InternetAddress>(); for (String recip : recips.split(",")) { recip = recip.trim(); if (recip.length() > 0) addressTo.add(new InternetAddress(recip)); } // Add the recipient list to the message msg.setRecipients(Message.RecipientType.TO, addressTo.toArray(new InternetAddress[addressTo.size()])); // Set the subject msg.setSubject(attribs.get("subject").evaluateAsString(context)); // Convert the content to a string (we can't use evaluateAsString() since // it only pays attention to the first item in a sequence.) // msg.setText(sequenceToString(content, context), "UTF-8"); msg.saveChanges(); // Finally, send the message. Transport tr = session.getTransport(protocol); tr.connect(); tr.sendMessage(msg, msg.getAllRecipients()); try { tr.close(); } catch (MessagingException e) { // ignore errors during close() } } catch (MessagingException e) { throw new DynamicError(e); } catch (XPathException e) { throw e; } return null; } } } // class SendElement