[jbpm-commits] JBoss JBPM SVN: r6272 - in jbpm4/trunk/modules: examples/src/test/java/org/jbpm/examples/mail/template and 9 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Apr 21 12:51:11 EDT 2010


Author: alex.guizar at jboss.com
Date: 2010-04-21 12:51:07 -0400 (Wed, 21 Apr 2010)
New Revision: 6272

Added:
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/AttachmentTest.java
   jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/activity/
   jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/activity/mail/
   jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/activity/mail/strip.gif
Modified:
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/inline/InlineMailTest.java
   jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/template/TemplateMailTest.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/AttachmentTemplate.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptManager.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailTemplateBinding.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/CustomMailProducerTest.java
   jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
Log:
JBPM-2426: code and document mail attachment example

Modified: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/inline/InlineMailTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/inline/InlineMailTest.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/inline/InlineMailTest.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -44,48 +44,44 @@
  */
 public class InlineMailTest extends JbpmTestCase {
 
-  Wiser wiser = null;
-  
-  String groupId1;
-  
-  String groupId2;
+  private Wiser wiser = new Wiser();
 
   protected void setUp() throws Exception {
     super.setUp();
 
     // deploy process
     String deploymentId = repositoryService.createDeployment()
-        .addResourceFromClasspath("org/jbpm/examples/mail/inline/process.jpdl.xml")
-        .deploy();
+      .addResourceFromClasspath("org/jbpm/examples/mail/inline/process.jpdl.xml")
+      .deploy();
     registerDeployment(deploymentId);
 
     // create actors
     identityService.createUser("bb", "Big Brother", null, "bb at oceania");
     identityService.createUser("obrien", null, "O'Brien", "obrien at miniluv");
     identityService.createUser("charr", null, "Charrington", "charr at miniluv");
-    groupId1 = identityService.createGroup("thinkpol");
-    groupId2 = identityService.createGroup("innerparty");
-    identityService.createMembership("obrien", groupId2);
-    identityService.createMembership("charr", groupId1);
-    identityService.createMembership("obrien", groupId1);
-    
+    identityService.createGroup("thinkpol");
+    identityService.createGroup("innerparty");
+    identityService.createMembership("obrien", "innerparty");
+    identityService.createMembership("charr", "thinkpol");
+    identityService.createMembership("obrien", "thinkpol");
+
     // start mail server
-    wiser = new Wiser();
     wiser.setPort(2525);
     wiser.start();
   }
 
   protected void tearDown() throws Exception {
+    // stop mail server
     wiser.stop();
 
     // delete actors
     identityService.deleteUser("bb");
     identityService.deleteUser("obrien");
     identityService.deleteUser("charr");
-    
-    identityService.deleteGroup(groupId1);
-    identityService.deleteGroup(groupId2);
-    
+
+    identityService.deleteGroup("thinkpol");
+    identityService.deleteGroup("innerparty");
+
     super.tearDown();
   }
 
@@ -117,13 +113,13 @@
       // to
       Address[] expectedTo = InternetAddress.parse("winston at minitrue");
       Address[] to = message.getRecipients(RecipientType.TO);
-      assert Arrays.equals(expectedTo, to) : Arrays.asList(to);
+      assert Arrays.equals(expectedTo, to) : Arrays.toString(to);
       // cc
       Address[] expectedCc = InternetAddress.parse("bb at oceania, obrien at miniluv");
       System.out.println(Arrays.toString(expectedCc));
       Address[] cc = message.getRecipients(RecipientType.CC);
       System.out.println(Arrays.toString(cc));
-      assert Arrays.equals(expectedCc, cc) : Arrays.asList(cc);
+      assert Arrays.equals(expectedCc, cc) : Arrays.toString(cc);
       // bcc - recipients undisclosed
       assertNull(message.getRecipients(RecipientType.BCC));
       // subject

Modified: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/template/TemplateMailTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/template/TemplateMailTest.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/mail/template/TemplateMailTest.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -44,7 +44,7 @@
  */
 public class TemplateMailTest extends JbpmTestCase {
 
-  private Wiser wiser;
+  private Wiser wiser = new Wiser();
 
   protected void setUp() throws Exception {
     super.setUp();
@@ -66,12 +66,12 @@
     identityService.createMembership("obrien", "thinkpol");
 
     // start mail server
-    wiser = new Wiser();
     wiser.setPort(2525);
     wiser.start();
   }
 
   protected void tearDown() throws Exception {
+    // stop mail server
     wiser.stop();
 
     // delete actors

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptActivity.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptActivity.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptActivity.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -23,10 +23,8 @@
 
 import org.jbpm.api.model.OpenExecution;
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
 import org.jbpm.pvm.internal.script.ScriptManager;
 
-
 /**
  * @author Tom Baeyens
  */

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/AttachmentTemplate.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/AttachmentTemplate.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/AttachmentTemplate.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -32,6 +32,10 @@
 
   private String name;
   private String description;
+
+  private String expression;
+  private String mimeType;
+
   private String url;
   private String resource;
   private String file;
@@ -39,7 +43,6 @@
   public String getName() {
     return name;
   }
-
   public void setName(String name) {
     this.name = name;
   }
@@ -47,15 +50,27 @@
   public String getDescription() {
     return description;
   }
-
   public void setDescription(String description) {
     this.description = description;
   }
 
+  public String getExpression() {
+    return expression;
+  }
+  public void setExpression(String expression) {
+    this.expression = expression;
+  }
+
+  public String getMimeType() {
+    return mimeType;
+  }
+  public void setMimeType(String mimeType) {
+    this.mimeType = mimeType;
+  }
+
   public String getUrl() {
     return url;
   }
-
   public void setUrl(String url) {
     this.url = url;
   }
@@ -63,7 +78,6 @@
   public String getResource() {
     return resource;
   }
-
   public void setResource(String resource) {
     this.resource = resource;
   }
@@ -71,9 +85,7 @@
   public String getFile() {
     return file;
   }
-
   public void setFile(String file) {
     this.file = file;
   }
-
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -30,7 +30,9 @@
 import java.util.List;
 
 import javax.activation.DataHandler;
+import javax.activation.DataSource;
 import javax.activation.FileDataSource;
+import javax.activation.URLDataSource;
 import javax.mail.Address;
 import javax.mail.BodyPart;
 import javax.mail.Message;
@@ -105,7 +107,7 @@
     // resolve and parse addresses
     String addresses = fromTemplate.getAddresses();
     if (addresses != null) {
-      addresses = evaluateExpression(addresses, execution);
+      addresses = evaluateExpression(addresses);
       email.addFrom(InternetAddress.parse(addresses));
     }
 
@@ -131,20 +133,18 @@
     }
   }
 
-  private String evaluateExpression(String expression, Execution execution) {
-    ScriptManager scriptManager = EnvironmentImpl.getFromCurrent(ScriptManager.class);
+  private String evaluateExpression(String expression) {
+    return evaluateExpression(expression, String.class);
+  }
+
+  private <T> T evaluateExpression(String expression, Class<T> type) {
+    ScriptManager scriptManager = ScriptManager.getScriptManager();
     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;
+    return type.cast(value);
   }
 
   private String[] tokenizeActors(String recipients, Execution execution) {
-    String[] actors = evaluateExpression(recipients, execution).split("[,;|\\s]+");
+    String[] actors = evaluateExpression(recipients).split("[,;|\\s]+");
     if (actors.length == 0) throw new JbpmException("recipient list is empty: " + recipients);
     return actors;
   }
@@ -178,7 +178,7 @@
     // resolve and parse addresses
     String addresses = addressTemplate.getAddresses();
     if (addresses != null) {
-      addresses = evaluateExpression(addresses, execution);
+      addresses = evaluateExpression(addresses);
       email.addRecipients(recipientType, InternetAddress.parse(addresses));
     }
 
@@ -207,7 +207,7 @@
   protected void fillSubject(Execution execution, Message email) throws MessagingException {
     String subject = template.getSubject();
     if (subject != null) {
-      subject = evaluateExpression(subject, execution);
+      subject = evaluateExpression(subject);
       email.setSubject(subject);
     }
   }
@@ -224,7 +224,7 @@
       // text
       if (text != null) {
         BodyPart textPart = new MimeBodyPart();
-        text = evaluateExpression(text, execution);
+        text = evaluateExpression(text);
         textPart.setText(text);
         multipart.addBodyPart(textPart);
       }
@@ -232,7 +232,7 @@
       // html
       if (html != null) {
         BodyPart htmlPart = new MimeBodyPart();
-        html = evaluateExpression(html, execution);
+        html = evaluateExpression(html);
         htmlPart.setContent(html, "text/html");
         multipart.addBodyPart(htmlPart);
       }
@@ -246,7 +246,7 @@
     }
     else if (text != null) {
       // unipart
-      text = evaluateExpression(text, execution);
+      text = evaluateExpression(text);
       email.setText(text);
     }
   }
@@ -256,76 +256,89 @@
     for (AttachmentTemplate attachmentTemplate : template.getAttachmentTemplates()) {
       BodyPart attachmentPart = new MimeBodyPart();
 
-      // resolve and set description
+      // resolve description
       String description = attachmentTemplate.getDescription();
       if (description != null) {
-        description = evaluateExpression(description, execution);
-        attachmentPart.setDescription(description);
+        attachmentPart.setDescription(evaluateExpression(description));
       }
 
-      // resolve name; if absent, it will be taken from file or url
+      // obtain interface to data
+      DataHandler dataHandler = createDataHandler(attachmentTemplate);
+      attachmentPart.setDataHandler(dataHandler);
+      
+      // resolve file name
       String name = attachmentTemplate.getName();
       if (name != null) {
-        name = evaluateExpression(name, execution);
+        attachmentPart.setFileName(evaluateExpression(name));
       }
-
-      // 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
-        attachmentPart.setDataHandler(new DataHandler(new FileDataSource(targetFile)));
-        // extract attachment name from file
-        if (name == null) {
-          name = targetFile.getName();
-        }
-      }
       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);
-          }
+        // fall back on data source
+        DataSource dataSource = dataHandler.getDataSource();
+        if (dataSource instanceof URLDataSource) {
+          name = extractResourceName(((URLDataSource) dataSource).getURL());
         }
-        // resolve and read classpath resource
         else {
-          String resource = evaluateExpression(attachmentTemplate.getResource(), execution);
-          targetUrl = EnvironmentImpl.getCurrent().getClassLoader().getResource(resource);
-          if (targetUrl == null) {
-            throw new JbpmException("could not read attachment content, resource not found: "
-              + resource);
-          }
+          name = dataSource.getName();
         }
-        // set content from url
-        attachmentPart.setDataHandler(new DataHandler(targetUrl));
-        // extract attachment name from target url
-        if (name == null) {
-          name = extractResourceName(targetUrl);
+        if (name != null) {
+          attachmentPart.setFileName(name);
         }
       }
 
-      // set name, must be resolved at this point
-      attachmentPart.setFileName(name);
       multipart.addBodyPart(attachmentPart);
     }
   }
 
+  private DataHandler createDataHandler(AttachmentTemplate attachmentTemplate) {
+    // evaluate expression
+    String expression = attachmentTemplate.getExpression();
+    if (expression != null) {
+      Object object = evaluateExpression(expression, Object.class);
+      return new DataHandler(object, attachmentTemplate.getMimeType());
+    }
+
+    // resolve local file
+    String file = attachmentTemplate.getFile();
+    if (file != null) {
+      File targetFile = new File(evaluateExpression(file));
+      if (!targetFile.isFile()) {
+        throw new JbpmException("could not read attachment content, file not found: "
+          + targetFile);
+      }
+      // set content from file
+      return new DataHandler(new FileDataSource(targetFile));
+    }
+
+    // resolve external url
+    URL targetUrl;
+    String url = attachmentTemplate.getUrl();
+    if (url != null) {
+      url = evaluateExpression(url);
+      try {
+        targetUrl = new URL(url);
+      }
+      catch (MalformedURLException e) {
+        throw new JbpmException("could not read attachment content, malformed url: " + url, e);
+      }
+    }
+    // resolve classpath resource
+    else {
+      String resource = evaluateExpression(attachmentTemplate.getResource());
+      targetUrl = Thread.currentThread().getContextClassLoader().getResource(resource);
+      if (targetUrl == null) {
+        throw new JbpmException("could not read attachment content, resource not found: "
+          + resource);
+      }
+    }
+    // set content from url
+    return new DataHandler(targetUrl);
+  }
+
   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;
+    return sepIndex != -1 ? path.substring(sepIndex + 1) : null;
   }
 }

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptManager.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptManager.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/script/ScriptManager.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -31,7 +31,6 @@
 import org.jbpm.api.JbpmException;
 import org.jbpm.internal.log.Log;
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
 import org.jbpm.pvm.internal.wire.WireContext;
 import org.jbpm.pvm.internal.wire.WireDefinition;
 import org.jbpm.pvm.internal.wire.xml.WireParser;

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailTemplateBinding.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailTemplateBinding.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/MailTemplateBinding.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -21,6 +21,7 @@
  */
 package org.jbpm.pvm.internal.wire.binding;
 
+import org.w3c.dom.Attr;
 import org.w3c.dom.DocumentFragment;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -46,18 +47,20 @@
 
   public Object parse(Element element, Parse parse, Parser parser) {
     // MailTemplateRegistry is added to the WireDescriptor with a ProvidedObjectDescriptor
-    // The MailTemplateRegistry descriptor is lazy initialized by this binding 
-    // mail-template will add a MailTemplate to the MailTemplateRegistry 
+    // The MailTemplateRegistry descriptor is lazy initialized by this binding
+    // mail-template will add a MailTemplate to the MailTemplateRegistry
     ProvidedObjectDescriptor templateRegistryDescriptor;
     MailTemplateRegistry templateRegistry;
 
     WireDefinition wireDefinition = parse.contextStackFind(WireDefinition.class);
-    String templateRegistryDescriptorName = (wireDefinition != null ? wireDefinition.getDescriptorName(MailTemplateRegistry.class) : null);
-    
-    if (templateRegistryDescriptorName != null) {
-      templateRegistryDescriptor = (ProvidedObjectDescriptor) wireDefinition.getDescriptor(templateRegistryDescriptorName);
+    String templateRegistryName;
+
+    if (wireDefinition != null
+      && (templateRegistryName = wireDefinition.getDescriptorName(MailTemplateRegistry.class)) != null) {
+      templateRegistryDescriptor = (ProvidedObjectDescriptor) wireDefinition.getDescriptor(templateRegistryName);
       templateRegistry = (MailTemplateRegistry) templateRegistryDescriptor.getProvidedObject();
-    } else {
+    }
+    else {
       templateRegistry = new MailTemplateRegistry();
       templateRegistryDescriptor = new ProvidedObjectDescriptor(templateRegistry, true);
     }
@@ -107,15 +110,49 @@
         AttachmentTemplate attachmentTemplate = new AttachmentTemplate();
         mailTemplate.addAttachmentTemplate(attachmentTemplate);
 
-        attachmentTemplate.setUrl(XmlUtil.attribute(attachmentElement, "url"));
-        attachmentTemplate.setResource(XmlUtil.attribute(attachmentElement, "resource"));
-        attachmentTemplate.setFile(XmlUtil.attribute(attachmentElement, "file"));
+        attachmentTemplate.setName(XmlUtil.attribute(attachmentElement, "name"));
+        attachmentTemplate.setDescription(XmlUtil.attribute(attachmentElement, "description"));
+
+        // expression attribute
+        Attr expressionAttr = attachmentElement.getAttributeNode("expression");
+        if (expressionAttr != null) {
+          attachmentTemplate.setExpression(expressionAttr.getValue());
+          attachmentTemplate.setMimeType(XmlUtil.attribute(attachmentElement, "mime-type"));
+        }
+        else {
+          // expression element
+          Element expressionElem = XmlUtil.element(attachmentElement, "expression");
+          if (expressionElem != null) {
+            attachmentTemplate.setExpression(XmlUtil.getContentText(expressionElem));
+            attachmentTemplate.setMimeType(XmlUtil.attribute(attachmentElement, "mime-type"));
+          }
+          else {
+            // file
+            Attr file = attachmentElement.getAttributeNode("file");
+            if (file != null) {
+              attachmentTemplate.setFile(file.getValue());
+            }
+            else {
+              // url
+              Attr url = attachmentElement.getAttributeNode("url");
+              if (url != null) {
+                attachmentTemplate.setUrl(url.getValue());
+              }
+              else {
+                // resource
+                Attr resource = attachmentElement.getAttributeNode("resource");
+                if (resource != null) attachmentTemplate.setResource(resource.getValue());
+              }
+            }
+          }
+        }
       }
     }
     return mailTemplate;
   }
 
-  private static AddressTemplate parseRecipientTemplate(Element element, String tagName, Parse parse) {
+  private static AddressTemplate parseRecipientTemplate(Element element, String tagName,
+    Parse parse) {
     Element recipientElement = XmlUtil.element(element, tagName);
     if (recipientElement == null) return null;
 

Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/AttachmentTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/AttachmentTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/AttachmentTest.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -0,0 +1,208 @@
+/*
+ * 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.test.activity.mail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.internet.MimeMessage;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.pvm.internal.util.IoUtil;
+import org.jbpm.test.JbpmTestCase;
+import org.subethamail.wiser.Wiser;
+import org.subethamail.wiser.WiserMessage;
+
+/**
+ * @author Alejandro Guizar
+ */
+public class AttachmentTest extends JbpmTestCase {
+
+  private Wiser wiser = new Wiser();
+
+  protected void setUp() throws Exception {
+    super.setUp();
+    // start mail server
+    wiser.setPort(2525);
+    wiser.start();
+  }
+
+  protected void tearDown() throws Exception {
+    // stop mail server
+    wiser.stop();
+    super.tearDown();
+  }
+
+  public void testVariableAttachment() throws MessagingException, IOException {
+    // deploy process definition
+    deployJpdlXmlString("<process name='varattachment'>"
+      + "  <start>"
+      + "    <transition to='send mail' />"
+      + "  </start>"
+      + "  <mail name='send mail'>"
+      + "    <to addresses='dilbert at office' />"
+      + "    <subject>review</subject>"
+      + "    <text>did you review the document I emailed?</text>"
+      + "    <attachments>"
+      + "      <attachment name='strip.gif' expression='${strip}' mime-type='image/gif'/>"
+      + "    </attachments>"
+      + "    <transition to='end' />"
+      + "  </mail>"
+      + "  <end name='end'/>"
+      + "</process>");
+
+    byte[] strip = IoUtil.readBytes(getClass().getResourceAsStream("strip.gif"));
+
+    // start process instance
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("varattachment", Collections.singletonMap("strip", strip));
+    assertProcessInstanceEnded(processInstance);
+
+    // examine produced messages
+    examineMessages(wiser.getMessages());
+  }
+
+  public void testFileAttachment() throws MessagingException, IOException, URISyntaxException {
+    File file = new File(getClass().getResource("strip.gif").toURI());
+
+    // deploy process definition
+    deployJpdlXmlString("<process name='fileattachment'>"
+      + "  <start>"
+      + "    <transition to='send mail' />"
+      + "  </start>"
+      + "  <mail name='send mail'>"
+      + "    <to addresses='dilbert at office' />"
+      + "    <subject>review</subject>"
+      + "    <text>did you review the document I emailed?</text>"
+      + "    <attachments>"
+      + "      <attachment file='"
+      + file
+      + "'/>"
+      + "    </attachments>"
+      + "    <transition to='end' />"
+      + "  </mail>"
+      + "  <end name='end'/>"
+      + "</process>");
+
+    // start process instance
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("fileattachment");
+    assertProcessInstanceEnded(processInstance);
+
+    // examine produced messages
+    examineMessages(wiser.getMessages());
+  }
+
+  public void testUrlAttachment() throws MessagingException, IOException {
+    URL url = getClass().getResource("strip.gif");
+
+    // deploy process definition
+    deployJpdlXmlString("<process name='urlattachment'>"
+      + "  <start>"
+      + "    <transition to='send mail' />"
+      + "  </start>"
+      + "  <mail name='send mail'>"
+      + "    <to addresses='dilbert at office' />"
+      + "    <subject>review</subject>"
+      + "    <text>did you review the document I emailed?</text>"
+      + "    <attachments>"
+      + "      <attachment url='"
+      + url
+      + "'/>"
+      + "    </attachments>"
+      + "    <transition to='end' />"
+      + "  </mail>"
+      + "  <end name='end'/>"
+      + "</process>");
+
+    // start process instance
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("urlattachment");
+    assertProcessInstanceEnded(processInstance);
+
+    // examine produced messages
+    examineMessages(wiser.getMessages());
+  }
+
+  public void testResourceAttachment() throws MessagingException, IOException {
+    // deploy process definition
+    deployJpdlXmlString("<process name='resattachment'>"
+      + "  <start>"
+      + "    <transition to='send mail' />"
+      + "  </start>"
+      + "  <mail name='send mail'>"
+      + "    <to addresses='dilbert at office' />"
+      + "    <subject>review</subject>"
+      + "    <text>did you review the document I emailed?</text>"
+      + "    <attachments>"
+      + "      <attachment resource='org/jbpm/test/activity/mail/strip.gif'/>"
+      + "    </attachments>"
+      + "    <transition to='end' />"
+      + "  </mail>"
+      + "  <end name='end'/>"
+      + "</process>");
+
+    // start process instance
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("resattachment");
+    assertProcessInstanceEnded(processInstance);
+
+    // examine produced messages
+    examineMessages(wiser.getMessages());
+  }
+
+  private static void examineMessages(List<WiserMessage> wiserMessages)
+    throws MessagingException, IOException {
+    assertEquals(1, wiserMessages.size());
+
+    WiserMessage wisMessage = wiserMessages.get(0);
+    MimeMessage message = wisMessage.getMimeMessage();
+
+    // multipart content
+    Multipart multipart = (Multipart) message.getContent();
+    assertEquals(2, multipart.getCount());
+
+    // text part
+    BodyPart textPart = multipart.getBodyPart(0);
+    assert textPart.getContentType().startsWith("text/plain") : textPart.getContentType();
+    assertEquals("did you review the document I emailed?", textPart.getContent());
+
+    // binary part
+    BodyPart gifPart = multipart.getBodyPart(1);
+    assertEquals("strip.gif", gifPart.getFileName());
+    assert gifPart.getContentType().startsWith("image/gif") : gifPart.getContentType();
+    // check gif magic numbers
+    InputStream gifStream = gifPart.getInputStream();
+    try {
+      assertEquals('G', gifStream.read());
+      assertEquals('I', gifStream.read());
+      assertEquals('F', gifStream.read());
+    }
+    finally {
+      gifStream.close();
+    }
+  }
+}


Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/AttachmentTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/CustomMailProducerTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/CustomMailProducerTest.java	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/mail/CustomMailProducerTest.java	2010-04-21 16:51:07 UTC (rev 6272)
@@ -48,14 +48,10 @@
  */
 public class CustomMailProducerTest extends JbpmTestCase {
 
-  private Wiser wiser;
+  private Wiser wiser = new Wiser();
 
   protected void setUp() throws Exception {
     super.setUp();
-    // start mail server
-    wiser = new Wiser();
-    wiser.setPort(2525);
-    wiser.start();
     // create actors
     identityService.createUser("bb", "Big Brother", null, "bb at oceania");
     identityService.createUser("obrien", null, "O'Brien", "obrien at miniluv");
@@ -65,17 +61,20 @@
     identityService.createMembership("obrien", "innerparty");
     identityService.createMembership("charr", "thinkpol");
     identityService.createMembership("obrien", "thinkpol");
+    // start mail server
+    wiser.setPort(2525);
+    wiser.start();
   }
 
   protected void tearDown() throws Exception {
+    // stop mail server
+    wiser.stop();
     // delete actors
     identityService.deleteGroup("thinkpol");
     identityService.deleteGroup("innerparty");
     identityService.deleteUser("bb");
     identityService.deleteUser("obrien");
     identityService.deleteUser("charr");
-    // stop mail server
-    wiser.stop();
     super.tearDown();
   }
 
@@ -118,8 +117,7 @@
     variables.put("date", date);
     variables.put("details", details);
     // start process instance
-    ProcessInstance processInstance = executionService.startProcessInstanceByKey("custommail",
-      variables);
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("custommail", variables);
     assertProcessInstanceEnded(processInstance);
 
     // examine produced messages
@@ -143,14 +141,16 @@
 
     @Override
     protected void fillRecipients(Execution execution, Message email) throws MessagingException {
+      // add recipients from template
       super.fillRecipients(execution, email);
 
-      // bcc every email sent to the spy group
+      // load audit group from database
       EnvironmentImpl environment = EnvironmentImpl.getCurrent();
       IdentitySession identitySession = environment.get(IdentitySession.class);
+      Group group = identitySession.findGroupById(auditGroup);
+
+      // send a blind carbon copy of every message to the audit group
       AddressResolver addressResolver = environment.get(AddressResolver.class);
-
-      Group group = identitySession.findGroupById(auditGroup);
       email.addRecipients(RecipientType.BCC, addressResolver.resolveAddresses(group));
     }
   }

Added: jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/activity/mail/strip.gif
===================================================================
(Binary files differ)


Property changes on: jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/test/activity/mail/strip.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml	2010-04-21 15:28:50 UTC (rev 6271)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml	2010-04-21 16:51:07 UTC (rev 6272)
@@ -2279,13 +2279,20 @@
     
     <section id="mail">
       <title><literal>mail</literal></title>
+
       <para>Through the <literal>mail</literal> activity, process authors are
         able to specify the content of an email message to be sent to multiple
         recipients at once. Every email message is produced from a template.
         Templates may be specified inline or in the <literal>process-engine-context
         </literal> section of the configuration file.</para>
+
       <table><title><literal>mail</literal> attributes</title>
         <tgroup cols="5" rowsep="1" colsep="1">
+          <colspec colname="attribute" colwidth="*" />
+          <colspec colname="type" colwidth="*" />
+          <colspec colname="default" colwidth="*" />
+          <colspec colname="required" colwidth="*" />
+          <colspec colname="description" colwidth="4*" />
           <thead>
             <row>
               <entry>Attribute</entry>
@@ -2308,8 +2315,12 @@
           </tbody>
         </tgroup>
       </table>
+
       <table><title><literal>mail</literal> elements</title>
         <tgroup cols="3" rowsep="1" colsep="1">
+          <colspec colname="element" colwidth="*" />
+          <colspec colname="multiplicity" colwidth="*" />
+          <colspec colname="description" colwidth="2*" />
           <thead>
             <row>
               <entry>Element</entry>
@@ -2356,17 +2367,90 @@
             <row>
               <entry>attachments</entry>
               <entry>0..1</entry>
-              <entry>attachments can be specified as URLs, classpath resources or 
-                local files</entry>
+              <entry>each attachment is configured in a separate subelement</entry>
             </row>
           </tbody>
         </tgroup>
       </table>
-      
-      <para>
-      	Example usage:
-     	<programlisting>
-&lt;process name=&quot;InlineMail&quot; xmlns=&quot;http://jbpm.org/4.3/jpdl&quot;&gt;
+
+      <table><title><literal>attachment</literal> attributes</title>
+      <tgroup cols="3" rowsep="1" colsep="1">
+      <colspec colname="attribute" colwidth="*" />
+      <colspec colname="type" colwidth="*" />
+      <colspec colname="default" colwidth="*" />
+      <colspec colname="required" colwidth="*" />
+      <colspec colname="description" colwidth="4*" />
+      <thead>
+      <row>
+        <entry>Attribute</entry>
+        <entry>Type</entry>
+        <entry>Default</entry>
+        <entry>Required?</entry>
+        <entry>Description</entry>
+      </row>
+      </thead>
+      <tbody>
+      <row>
+        <entry>name</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry>no, unless <literal>expression</literal> is present</entry>
+        <entry><emphasis>File</emphasis> name associated with this attachment.
+          If absent, data sources that encapsulate files such as <literal>resource</literal>,
+          <literal>file</literal> and <literal>url</literal> provide a reasonable
+          fallback value.</entry>
+      </row>
+      <row>
+        <entry>description</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry>no</entry>
+        <entry>Descriptive information associated with this attachment.</entry>
+      </row>
+      <row>
+        <entry>expression</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry morerows="3">one of <literal>expression</literal>, <literal>file</literal>,
+          <literal>url</literal> or <literal>resource</literal> must be present</entry>
+        <entry>Expression that evaluates to a representation of the attachment data
+         in the form of a Java object. Useful to extract content from process variables.</entry>
+      </row>
+      <row>
+        <entry>file</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry>Path to the attachment data in the file system. The denoted
+           file must exist.</entry>
+      </row>
+      <row>
+        <entry>url</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry>Location of the attachment data in the worldwide web. The pointed
+          resource must exist.</entry>
+      </row>
+      <row>
+        <entry>resource</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry>Name of the resource containing the attachment data in the class path.
+          The denoted resource must exist.</entry>
+      </row>
+      <row>
+        <entry>mime-type</entry>
+        <entry>string</entry>
+        <entry></entry>
+        <entry>no, unless <literal>expression</literal> is present</entry>
+        <entry>MIME type of the object returned by the expression.</entry>
+      </row>
+      </tbody>
+      </tgroup>
+      </table>
+
+      <para>Example usage:</para>
+
+      <programlisting>&lt;process name=&quot;InlineMail&quot; xmlns=&quot;http://jbpm.org/4.3/jpdl&quot;&gt;
   &lt;start&gt;
     &lt;transition to=&quot;send birthday reminder note&quot; /&gt;
   &lt;/start&gt;
@@ -2374,21 +2458,23 @@
     &lt;to addresses=&quot;johnDoe at some-company.com&quot; /&gt;
     &lt;subject&gt;Reminder: ${person} celebrates his birthday!&lt;/subject&gt;
     &lt;text&gt;Do not forget: ${date} is the birthday of ${person} &lt;/text&gt;
+    &lt;attachments&gt;
+      &lt;attachment resource=&quot;org/example/birthday_card.png&quot;/&gt;
+      &lt;attachment name=&quot;picture.jpg&quot; expression=&quot;${picture}&quot; mime-type=&quot;image/jpeg&quot;/&gt;
+    &lt;/attachments&gt;
     &lt;transition to=&quot;end&quot; /&gt;
   &lt;/mail&gt;
   &lt;state name=&quot;end&quot;/&gt;
-&lt;/process&gt;     	
-     	</programlisting>
-      </para>
-      <para>
-      	The default configuration after installation contains a 
-      	<literal>jbpm.mail.properties</literal> for specifying the mail server 
-      	to be used by jBPM.  To use another mail server then localhost,  
-      	property <literal>mail.smtp.host</literal> can be updated in that 
-      	configuration file. 
-      </para>
+&lt;/process&gt;</programlisting>
+
+      <para>The default configuration after installation includes a 
+      	<literal>jbpm.mail.properties</literal> file specifying the SMTP host 
+      	that jBPM employs to send mail. To use a mail server other than the
+        local host, set the <literal>mail.smtp.host</literal> property in the
+        mail properties file.</para>
+
       <para>Refer to the Developers Guide for (unsupported) advanced mail 
-      configuration and usage.</para>
+        configuration and usage.</para>
     </section>
 
   </section>



More information about the jbpm-commits mailing list