Package org.jbpm.pvm.internal.email.impl

Source Code of org.jbpm.pvm.internal.email.impl.MailProducerImpl

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jbpm.pvm.internal.email.impl;

import java.io.File;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
import org.jbpm.api.identity.Group;
import org.jbpm.api.identity.User;
import org.jbpm.pvm.internal.email.spi.AddressResolver;
import org.jbpm.pvm.internal.email.spi.MailProducer;
import org.jbpm.pvm.internal.env.Environment;
import org.jbpm.pvm.internal.identity.spi.IdentitySession;
import org.jbpm.pvm.internal.script.ScriptManager;

/**
* Default mail producer.
*
* @author Alejandro Guizar
*/
public class MailProducerImpl implements MailProducer, Serializable {

  private static final long serialVersionUID = 1L;

  private MailTemplate template;

  public MailTemplate getTemplate() {
    return template;
  }

  public void setTemplate(MailTemplate template) {
    this.template = template;
  }

  public Collection<Message> produce(Execution execution) {
    Message email = instantiateEmail();
    fillFrom(execution, email);
    fillRecipients(execution, email);
    fillSubject(execution, email);
    fillContent(execution, email);
    return Collections.singleton(email);
  }

  protected Message instantiateEmail() {
    return new MimeMessage((Session) null);
  }

  /**
   * Fills the <code>from</code> attribute of the given email. The sender addresses are an optional
   * element in the mail template. If absent, each mail server supplies the current user's email
   * address.
   *
   * @see {@link InternetAddress#getLocalAddress(Session)}
   */
  protected void fillFrom(Execution execution, Message email) {
    AddressTemplate fromTemplate = template.getFrom();
    // "from" attribute is optional
    if (fromTemplate == null) return;

    // resolve and parse addresses
    String addresses = fromTemplate.getAddresses();
    if (addresses != null) {
      addresses = evaluateExpression(addresses, execution);
      try {
        email.addFrom(InternetAddress.parse(addresses));
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to add " + addresses + " to senders", e);
      }
    }

    Environment environment = Environment.getCurrent();
    IdentitySession identitySession = environment.get(IdentitySession.class);
    AddressResolver addressResolver = environment.get(AddressResolver.class);

    // resolve and tokenize users
    String userList = fromTemplate.getUsers();
    if (userList != null) {
      String[] userIds = tokenizeActors(userList, execution);
      List<User> users = identitySession.findUsersById(userIds);
      addSenders(resolveAddresses(users, addressResolver), email);
    }

    // resolve and tokenize groups
    String groupList = fromTemplate.getGroups();
    if (groupList != null) {
      for (String groupId : tokenizeActors(groupList, execution)) {
        Group group = identitySession.findGroupById(groupId);
        addSenders(addressResolver.resolveAddresses(group), email);
      }
    }
  }

  private String evaluateExpression(String expression, Execution execution) {
    ScriptManager scriptManager = Environment.getFromCurrent(ScriptManager.class);
    Object value = scriptManager.evaluateExpression(expression, template.getLanguage());
    if (!(value instanceof String)) {
      throw new JbpmException("expected expression '"
          + expression
          + "' to return string, but was: "
          + value);
    }
    return (String) value;
  }

  private String[] tokenizeActors(String recipients, Execution execution) {
    String[] actors = evaluateExpression(recipients, execution).split("[,;|\\s]+");
    if (actors.length == 0) throw new JbpmException("recipient list is empty: " + recipients);
    return actors;
  }

  /** construct recipient addresses from user entities */
  private Address[] resolveAddresses(List<User> users, AddressResolver addressResolver) {
    int userCount = users.size();
    Address[] addresses = new Address[userCount];
    for (int i = 0; i < userCount; i++) {
      addresses[i] = addressResolver.resolveAddress(users.get(i));
    }
    return addresses;
  }

  /** add senders to message */
  private void addSenders(Address[] addresses, Message email) {
    try {
      email.addFrom(addresses);
    }
    catch (MessagingException e) {
      throw new JbpmException("failed to add " + Arrays.toString(addresses) + " to senders", e);
    }
  }

  protected void fillRecipients(Execution execution, Message email) {
    // to
    AddressTemplate to = template.getTo();
    if (to != null) fillRecipients(to, execution, email, RecipientType.TO);

    // cc
    AddressTemplate cc = template.getCc();
    if (cc != null) fillRecipients(cc, execution, email, RecipientType.CC);

    // bcc
    AddressTemplate bcc = template.getBcc();
    if (bcc != null) fillRecipients(bcc, execution, email, RecipientType.BCC);
  }

  private void fillRecipients(AddressTemplate addressTemplate, Execution execution, Message email,
      RecipientType recipientType) {
    // resolve and parse addresses
    String addresses = addressTemplate.getAddresses();
    if (addresses != null) {
      addresses = evaluateExpression(addresses, execution);
      try {
        email.addRecipients(recipientType, InternetAddress.parse(addresses));
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to add "
            + addresses
            + " to recipients of type "
            + recipientType, e);
      }
    }

    Environment environment = Environment.getCurrent();
    IdentitySession identitySession = environment.get(IdentitySession.class);
    AddressResolver addressResolver = environment.get(AddressResolver.class);

    // resolve and tokenize users
    String userList = addressTemplate.getUsers();
    if (userList != null) {
      String[] userIds = tokenizeActors(userList, execution);
      List<User> users = identitySession.findUsersById(userIds);
      addRecipients(resolveAddresses(users, addressResolver), email, recipientType);
    }

    // resolve and tokenize groups
    String groupList = addressTemplate.getGroups();
    if (groupList != null) {
      for (String groupId : tokenizeActors(groupList, execution)) {
        Group group = identitySession.findGroupById(groupId);
        addRecipients(addressResolver.resolveAddresses(group), email, recipientType);
      }
    }
  }

  /** add recipient addresses to message */
  private void addRecipients(Address[] addresses, Message email, RecipientType recipientType) {
    try {
      email.addRecipients(recipientType, addresses);
    }
    catch (MessagingException e) {
      throw new JbpmException("failed to add "
          + Arrays.toString(addresses)
          + " to recipients of type "
          + recipientType, e);
    }
  }

  protected void fillSubject(Execution execution, Message email) {
    String subject = template.getSubject();
    if (subject != null) {
      subject = evaluateExpression(subject, execution);
      try {
        email.setSubject(subject);
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to set subject to " + subject, e);
      }
    }
  }

  protected void fillContent(Execution execution, Message email) {
    String text = template.getText();
    String html = template.getHtml();
    List<AttachmentTemplate> attachmentTemplates = template.getAttachmentTemplates();

    if (html != null || !attachmentTemplates.isEmpty()) {
      // multipart
      Multipart multipart = new MimeMultipart("related");

      // text
      if (text != null) {
        BodyPart textPart = new MimeBodyPart();
        text = evaluateExpression(text, execution);
        try {
          textPart.setText(text);
          multipart.addBodyPart(textPart);
        }
        catch (MessagingException e) {
          throw new JbpmException("failed to add text content: " + text, e);
        }
      }

      // html
      if (html != null) {
        BodyPart htmlPart = new MimeBodyPart();
        html = evaluateExpression(html, execution);
        try {
          htmlPart.setContent(html, "text/html");
          multipart.addBodyPart(htmlPart);
        }
        catch (MessagingException e) {
          throw new JbpmException("failed to add html content: " + html, e);
        }
      }

      // attachments
      if (!attachmentTemplates.isEmpty()) {
        addAttachments(execution, multipart);
      }

      try {
        email.setContent(multipart);
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to set multipart content: " + multipart, e);
      }
    }
    else if (text != null) {
      // unipart
      text = evaluateExpression(text, execution);
      try {
        email.setText(text);
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to add text content: " + text, e);
      }
    }
  }

  protected void addAttachments(Execution execution, Multipart multipart) {
    for (AttachmentTemplate attachmentTemplate : template.getAttachmentTemplates()) {
      BodyPart attachmentPart = new MimeBodyPart();

      // resolve and set description
      String description = attachmentTemplate.getDescription();
      if (description != null) {
        description = evaluateExpression(description, execution);
        try {
          attachmentPart.setDescription(description);
        }
        catch (MessagingException e) {
          throw new JbpmException("failed to set attachment description: " + description, e);
        }
      }

      // resolve name; if absent, it will be taken from file or url
      String name = attachmentTemplate.getName();
      if (name != null) {
        name = evaluateExpression(name, execution);
      }

      // resolve and read file
      String file = attachmentTemplate.getFile();
      if (file != null) {
        File targetFile = new File(evaluateExpression(file, execution));
        if (!targetFile.isFile()) {
          throw new JbpmException("could not read attachment content, file not found: "
              + targetFile);
        }
        // set content from target file
        try {
          attachmentPart.setDataHandler(new DataHandler(new FileDataSource(targetFile)));
          // extract attachment name from file
          if (name == null) {
            name = targetFile.getName();
          }
        }
        catch (MessagingException e) {
          throw new JbpmException("failed to add attachment content: " + targetFile, e);
        }
      }
      else {
        URL targetUrl;
        // resolve and read external url
        String url = attachmentTemplate.getUrl();
        if (url != null) {
          try {
            url = evaluateExpression(url, execution);
            targetUrl = new URL(url);
          }
          catch (MalformedURLException e) {
            throw new JbpmException("could not read attachment content, malformed url: " + url, e);
          }
        }
        // resolve and read classpath resource
        else {
          String resource = evaluateExpression(attachmentTemplate.getResource(), execution);
          targetUrl = Environment.getCurrent().getClassLoader().getResource(resource);
          if (targetUrl == null) {
            throw new JbpmException("could not read attachment content, resource not found: "
                + resource);
          }
        }
        // set content from url
        try {
          attachmentPart.setDataHandler(new DataHandler(targetUrl));
          // extract attachment name from target url
          if (name == null) {
            name = extractResourceName(targetUrl);
          }
        }
        catch (MessagingException e) {
          throw new JbpmException("failed to add attachment content: " + targetUrl, e);
        }
      }

      // set name, must be resolved at this point
      try {
        attachmentPart.setFileName(name);
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to set attachment name: " + name, e);
      }

      try {
        multipart.addBodyPart(attachmentPart);
      }
      catch (MessagingException e) {
        throw new JbpmException("failed to add attachment part: " + attachmentPart, e);
      }
    }
  }

  private static String extractResourceName(URL url) {
    String path = url.getPath();
    if (path == null || path.length() == 0) return null;

    int sepIndex = path.lastIndexOf('/');
    return sepIndex != -1 ? path.substring(sepIndex) : null;
  }
}
TOP

Related Classes of org.jbpm.pvm.internal.email.impl.MailProducerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.