6.11.3. Example Code of the Mail Action

Here we list the partial process definition and the simple implementation of an action sending emails. The action is implemented as a SimpleAction with predefined timeout. If you need to increase the timeout, you should implement interface LongAction instead, which is better suited for long-running actions.

Assuming there are process variables field and document the mail action can be defined as follows:

<?xml version="1.0" encoding="iso-8859-1"?>
<Workflow>
  <Process name="SendMailProcess" startTask="SendMail">

   <Variable name="receiver" type="String">
      <String value="default@test.com"/>
   </Variable>

   <Variable name="field" type="String"/>
   <Variable name="document" type="Resource"/>

   <Variable name="delivered" type="Boolean">
      <Boolean value="false"/>
   </Variable>

   <AutomatedTask name="SendMail"
                   description="mail-task" final="true">
     <Action class="com.coremedia.extension.workflow.mail.SendMail"
              receiverVariable="receiver"
              documentVariable="document"
              fieldVariable="field"
              successVariable="delivered"/>
   </AutomatedTask>

   ...
  </Process>
</Workflow>

The implementation then looks as follows:

package com.coremedia.extension.workflow.mail;

import com.coremedia.cap.content.Content;
import com.coremedia.cap.workflow.Process;
import com.coremedia.cap.workflow.plugin.SimpleAction;
import com.coremedia.xml.Markup;
import org.slf4j.*;
import javax.mail.*;
import javax.mail.event.*;
import javax.mail.internet.*;

public class SendMail extends SimpleAction {

  private static final Logger LOG =
                          LoggerFactory.getLogger(SendMail.class);
  static final long serialVersionUID = 1258062873454333627L;

  protected String transportType = "smtp";
  protected String host = "smtp.coremedia.com";
  protected String user = "testuser";
  protected String password = "testpassword";
  protected String from = "testuser@coremedia.com";
  protected String subject = "This is a test mail";

  protected String receiverVariable;
  protected String fieldVariable;
  protected String documentVariable;

  protected Message createMessage(Session session,
                                  String from, String to,
                                  String subject, String text)
                    throws MessagingException {

    MimeMessage message = new MimeMessage(session);
    message.setFrom(new InternetAddress(from));
    message.addRecipient(Message.RecipientType.TO,
                         new InternetAddress(to));
    message.setSubject(subject);
    message.setText(text);
    message.saveChanges();
    return message;
  }

  protected boolean send(String host, String username,
                         String password, String from,
                         String to, String subject, String text,
                         String transport_type)
            throws MessagingException {

    Session session = Session.getDefaultInstance
                                   (System.getProperties(), null);

    Message message = createMessage(session,from,to,subject,text);
    MessageDelivery delivery = new MessageDelivery();

    Transport transport = session.getTransport(transport_type);
    transport.addTransportListener(delivery);
    transport.connect(host, username, password);
    transport.sendMessage(message, message.getAllRecipients());
    transport.close();
    transport.removeTransportListener(delivery);

    return delivery.isMailDelivered();
  }

  @Override
  protected boolean doExecute(Process process) {

    String to = process.getString(receiverVariable);
    Content content = process.getLink(documentVariable);
    if (content == null) {
      return false;
    }
    String field = process.getString(fieldVariable);
    Markup markup = content.getMarkup(field);
    String body = markup == null ? "" : markup.toString();
    try {
      return send(host, user, password, from, to, subject,
                                        body, transportType);
    } catch (MessagingException e) {
      LOG.error(e.getMessage());
    }
    return false;
  }

  // Setters for configuring the action in a process definition.
  public void setReceiverVariable(String receiverVariable) {
    this.receiverVariable = receiverVariable;
  }

  public void setFieldVariable(String fieldVariable) {
    this.fieldVariable = fieldVariable;
  }

  public void setDocumentVariable(String documentVariable) {
    this.documentVariable = documentVariable;
  }

  protected static class MessageDelivery
                         implements TransportListener{

    // wait a second for delivery
    // (If you need to increase the timeout, you should instead
    // implement interface LongAction which is better suited
    // for long-running actions. You should also implement method
    // #abort correctly so that the execution of the action does
    // not interfere with the shutdown of the Workflow Server.)
    private static final long TIMEOUT = 1000;

    private Boolean delivered = null;

    protected synchronized boolean isMailDelivered() {
      long timeout = System.currentTimeMillis() + TIMEOUT;
      while (delivered == null) {
        long now = System.currentTimeMillis();
        if (now >= timeout) {
          break;
        }
        try {
          wait(timeout - now);
        } catch (InterruptedException e) {
          LOG.error(e.getMessage());
        }
      }
      return Boolean.TRUE.equals(delivered);
    }

    private synchronized void deliverySuccess(boolean state) {
      delivered = state;
      notifyAll();
    }

    public void messageDelivered(TransportEvent e) {
      deliverySuccess(true);
    }

    public void messageNotDelivered(TransportEvent e) {
      deliverySuccess(false);
    }

    public void messagePartiallyDelivered(TransportEvent e) {
      deliverySuccess(false);
    }
  }
}
        

Example 6.4. The SendMail action