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}