001/* 002 * Copyright (c) 2004-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.sdm.spa; 031 032import java.util.Date; 033import java.util.Properties; 034 035import javax.mail.Message; 036import javax.mail.MessagingException; 037import javax.mail.Session; 038import javax.mail.Transport; 039import javax.mail.internet.InternetAddress; 040import javax.mail.internet.MimeMessage; 041 042import ptolemy.actor.TypedAtomicActor; 043import ptolemy.actor.TypedIOPort; 044import ptolemy.actor.parameters.PortParameter; 045import ptolemy.data.StringToken; 046import ptolemy.data.Token; 047import ptolemy.data.expr.StringParameter; 048import ptolemy.data.type.BaseType; 049import ptolemy.kernel.CompositeEntity; 050import ptolemy.kernel.util.Attribute; 051import ptolemy.kernel.util.IllegalActionException; 052import ptolemy.kernel.util.NameDuplicationException; 053 054////////////////////////////////////////////////////////////////////////// 055//// Email 056/** 057 * <p> 058 * Email actor is a notification actor that allows communication with the user 059 * via email especially from the remote execution of the long-runing workflows. 060 * </p> 061 * 062 * <p> 063 * Given the configuration parameters for the host SMTP server, to and from 064 * addresses, the Email actor sends the data that is linked to its "messageBody" 065 * multi-port as an output notification email from Kepler. 066 * </p> 067 * 068 * @UserLevelDocumentation <p> 069 * An example usage of the Email actor can be found at 070 * "workflows/test/emailTest.xml" in your SPA directory. 071 * </p> 072 * 073 * @author Ilkay Altintas 074 * @version $Id: Email.java 24234 2010-05-06 05:21:26Z welker $ 075 */ 076 077public class Email extends TypedAtomicActor { 078 079 /** 080 * Construct an Email actor with the given container and name. 081 * 082 * @param container 083 * The container. 084 * @param name 085 * The name of this actor. 086 * @exception IllegalActionException 087 * If the actor cannot be contained by the proposed 088 * container. 089 * @exception NameDuplicationException 090 * If the container already has an actor with this name. 091 */ 092 public Email(CompositeEntity container, String name) 093 throws IllegalActionException, NameDuplicationException { 094 super(container, name); 095 toAddress = new StringParameter(this, "toAddress"); 096 toAddress.setExpression("your_login@yourisp.com"); 097 fromAddress = new StringParameter(this, "fromAddress"); 098 fromAddress.setExpression("your_login@yourisp.com"); 099 host = new StringParameter(this, "host"); 100 host.setExpression("smtp.yourisp.com"); 101 102 subject = new PortParameter(this, "subject"); 103 subject.setStringMode(true); 104 subject.setTypeEquals(BaseType.STRING); 105 subject.setExpression("Notification email from Kepler"); 106 107 messageBody = new TypedIOPort(this, "messageBody", true, false); 108 messageBody.setMultiport(true); 109 messageBody.setTypeEquals(BaseType.GENERAL); 110 new Attribute(messageBody, "_showName"); 111 112 _attachText("_iconDescription", "<svg>\n" + "<text x=\"0\" y=\"30\"" 113 + "style=\"font-size:40; fill:blue; font-family:SansSerif\">" 114 + "@</text>\n" + "</svg>\n"); 115 116 } // end of constructor 117 118 // ///////////////////////////////////////////////////////////////// 119 // // ports and parameters //// 120 121 /** 122 * Email address that the email will be sent to. 123 */ 124 public StringParameter toAddress; 125 /** 126 * Email address that the email will be sent from. 127 */ 128 public StringParameter fromAddress; 129 /** 130 * The SMTP host of the from address. 131 */ 132 public StringParameter host; 133 /** 134 * Generic typed message body. It is a multi-port meaning more than one 135 * input of different types could be connected to it. 136 */ 137 public TypedIOPort messageBody; 138 139 /** 140 * @entity.description Generic typed message subject. 141 */ 142 public PortParameter subject; 143 144 // ///////////////////////////////////////////////////////////////// 145 // // public methods //// 146 147 /** 148 * Given a ...., Email actor ... 149 * 150 * @exception IllegalActionException 151 * If there is no director. 152 */ 153 public void fire() throws IllegalActionException { 154 155 String _host = ((StringToken) host.getToken()).stringValue(); 156 String _toAddress = ((StringToken) toAddress.getToken()).stringValue(); 157 String _fromAddress = ((StringToken) fromAddress.getToken()) 158 .stringValue(); 159 160 // _messageBodyStr = ( (StringToken) 161 // (messageBody.get(0))).stringValue(); 162 String _messageBodyStr = ""; 163 int i = 0; 164 int width = messageBody.getWidth(); 165 for (i = 0; i < width; i++) { 166 if (messageBody.hasToken(i)) { 167 Token tokenArg = messageBody.get(i); 168 String value = tokenArg.toString(); 169 _debug("messageBody(i) = " + value); 170 value = value.substring(1, value.length() - 1); 171 _messageBodyStr += value + "\n"; 172 } 173 } 174 // _debug(_host + "===" + _toAddress + "===" + 175 // _fromAddress + "===" +_messageBodyStr); 176 177 subject.update(); 178 String messageSubject = ((StringToken) subject.getToken()) 179 .stringValue(); 180 181 // Create properties, get Session 182 Properties props = new Properties(); 183 184 // If using static Transport.send(), 185 // need to specify which host to send it to 186 props.put("mail.smtp.host", _host); 187 // To see what is going on behind the scene 188 props.put("mail.debug", "false"); 189 // props.put("mail.smtp.auth", "true"); 190 Session session = Session.getInstance(props); 191 192 try { 193 // Instantiate a message 194 Message msg = new MimeMessage(session); 195 196 // Set message attributes 197 msg.setFrom(new InternetAddress(_fromAddress)); 198 InternetAddress[] address = { new InternetAddress(_toAddress) }; 199 msg.setRecipients(Message.RecipientType.TO, address); 200 msg.setSubject(messageSubject); 201 msg.setSentDate(new Date()); 202 203 // Set message content 204 msg.setText(_messageBodyStr); 205 206 // Send the message 207 Transport.send(msg); 208 // Transport transport = session.getTransport("smtp"); 209 // transport.connect(_host, _fromAddress, password); 210 211 } catch (MessagingException mex) { 212 // Prints all nested (chained) exceptions as well 213 mex.printStackTrace(); 214 } 215 216 } // end of fire 217 218 /** 219 * Post fire the actor. Return false to indicate that the process has 220 * finished. If it returns true, the process will continue indefinitely. 221 */ 222 public boolean postfire() { 223 return false; 224 } // end of postfire 225 226 /** 227 * Callback for changes in attribute values. 228 * 229 * @param at 230 * The attribute that changed. 231 * @exception IllegalActionException 232 * If the offsets array is not nondecreasing and nonnegative. 233 */ 234 /* 235 * public void attributeChanged(Attribute at) throws IllegalActionException 236 * { if (at == host){ _host = ((StringToken)host.getToken()).stringValue(); 237 * _debug("host set to: " + _host); } else if (at == toAddress) { _toAddress 238 * = ((StringToken)toAddress.getToken()).stringValue(); 239 * _debug("to address set to: " + _toAddress); } else if (at == fromAddress) 240 * { _fromAddress = ((StringToken)fromAddress.getToken()).stringValue(); 241 * _debug("from address set to: " + _fromAddress); } } // end of 242 * attributeChanged 243 */ 244 245 // //////////////////////////////////////////////////////////////////// 246 // // private variables //// 247 // private static String _host = ""; 248 // private static String _toAddress = ""; 249 // private static String _fromAddress = ""; 250}