Send email
The workflow module lets use email besides the process document context. The class must be put in the development section of the process version.
Example of code:
public class WorkflowEmailSender extends BaseWorkflowExtension {
final public static String SYSADMIN_LOGIN = "sysadmin";
final public static String USER_LOGIN_USERMAIL1 = "user_1";
final public static String USER_LOGIN_USERMAIL2 = "user_2";
final public static String TASK_NAME = "NameOfTheTask";
// Emails are sent when a task instance is created
@Override
public void onCreateTaskInstance(ITaskInstance taskInstance) {
IWorkflowModule workflowmodule = getWorkflowModule();
IContext SysadminContext = workflowmodule.getContextByLogin(SYSADMIN_LOGIN);
IMailForm emailform = taskInstance.getTask().getMailForm(IMailForm.INFORMATION);
Collection<IUser> entries = new ArrayList<>();
String taskname = taskInstance.getTask().getName();
try {
if (StringUtils.equals(taskname, TASK_NAME)) {
IUser usermail1 = workflowmodule.getUserByLogin(USER_LOGIN_USERMAIL1);
IUser usermail2 = workflowmodule.getUserByLogin(USER_LOGIN_USERMAIL2);
Collection<IUser> mail_to = new ArrayList<>();
mail_to.add(usermail1);
mail_to.add(usermail2);
String comment_taskInstance = "Email sending to a IUSER collection from a taskInstance";
String comment_resource = "Email sending to a IUSER collection from a resource";
IWorkflowInstance myWorkflowInst = taskInstance.getWorkflowInstance();
IResource resource = myWorkflowInst;
//Sending email from a taskInstance using the new method (15.0)
workflowmodule.send(SysadminContext, taskInstance, emailform, mail_to, comment_taskInstance);
//Sending email from a resource using the new method (15.0)
workflowmodule.send(SysadminContext, resource, emailform, mail_to, comment_resource);
}
} catch (
WorkflowModuleException e) {
// TODO Auto-generated catch block
throw new SDKException(e);
}
}
}
Using customization attributes
The workflow module lets use email forms besides the process document context.
For this, a generic resource is used. It is manipulated in the same way as the interfaces IWorkflowInstance and ILinkedResource.
This example displays the sending of an electronic message using a generic resource (fictive) besides the process document context:
public void general_sendMail( IContext context, IWorkflowModule workflowModule ) throws Exception {
// creation of a users list
ArrayList arrUsers = new ArrayList();
arrUsers.add( workflowModule.getUserByLogin( "froggy" ) );
arrUsers.add( workflowModule.getUserByLogin( "zorgly" ) );
// select the form name to use
String formName = "MY_CUSTOM_MAIL_FORM";
// create a fictive resource
IResource resource = workflowModule.createGenericResource();
// supply with some fields present in the selected email form
resource.setValue( IProperty.System.REFERENCE, "REF-ZRG-0001" );
resource.setValue( IProperty.System.TITLE, "My lovely document" );
resource.setValue( "any-property-name", "any-value" );
// retrieve the process version that contains the selected email form
IWorkflow workflow = workflowModule.getWorkflow( context, "DocumentManagement_1.0" );
// send the mail
workflowModule.send( context, workflow, resource, formName, arrUsers );
}
If a messaging extension is defined in the used email form, then it will be called on the sending of the electronic messages on the events beforeSend()
and afterSend()
.
The messaging extensions
Process lets the integrators develop Java classes that can react on events triggered when sending electronic messages. This notion of extension must be used if you would like, for example, complete the list of the default recipients who will receive the message. These extension classes may be defined on the message forms.
Principle
On step change, for example, if the messaging system is properly configured and the message form assigned to the action is activated, an email will be sent by Process.
Lifecycle
Before this email sending is effective, the message extension classes are called on the method beforeSend()
. On this event, it is then possible to suppress or complete the message sending.
After the email is sent, Process calls the extension class on the method afterSend()
. On this event, it is possible to perform additional tasks but in keeping in mind that it is no more possible to act on the message sending.
Developing an extension class
To develop an email extension class, you just have to branch off the class named BaseMailExtension.
The BaseMailExtension class
The class com.axemble.vdoc.sdk.mail.extensions.BaseMailExtension
provides direct access to the APIs methods and offers shortcuts for the following elements:
- the Workflow module;
- the last operator;
- the active document;
- the active task;
Methods of the BaseMailExtension class
public abstract class BaseMailExtension implements IMailExtensionSupport {
// helper methods
protected final IWorkflowModule getWorkflowModule();
protected final IWorkflowInstance getWorkflowInstance();
protected final IResource getResource();
protected final ITaskInstance getTaskInstance();
protected final IUser getPreviousTaskInstanceOperator();
protected final MimeMessage getMessage();
// dynamic management of the xml format's form customization
public void onPrepare(IBlockDefinition blockDefinition);
// mail events
protected abstract boolean beforeSend();
protected abstract void afterSend();
protected String onFillLanguage();
// mail recipients
public void onFillRecipients(MailRecipients mailRecipients);
}
The onPrepare()
method enables to dynamically modify the body of the email presentation before it has been processed by the render engine.
The onFillRecipients()
method enables to dynamically change or complete the recipients of the message.
The onFillLanguage()
method enables to force the language.
Code extract of the NewMailExtension class
The following code completes the list of the message recipients by adding all the members of the operator role “HRManager”.
public class BuildMailExtension extends BaseMailExtension {
/* (non-Javadoc)
* @see com.axemble.vdoc.sdk.mail.extensions.BaseMailExtension beforeSend()
*/
@Override
protected boolean beforeSend() {
MimeMessage message = this.getMessage();
try {
Multipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(message.getContent(), "text/html; charset=UTF-8");
multipart.addBodyPart(messageBodyPart);
@SuppressWarnings("unchecked")
Collection<IAttachment> attachments = (Collection<IAttachment>) this.getWorkflowModule().getAttachments(this.getWorkflowInstance(), "fldAttachments");
if (attachments != null) {
for (IAttachment attachment : attachments) {
DataSource fileDataSource = new FileDataSource(attachment.getName());
attachment.getContent(fileDataSource.getOutputStream());
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.setHeader("Content-Transfer-Encoding", "binary");
attachmentPart.setDataHandler(new DataHandler(fileDataSource));
attachmentPart.setFileName(attachment.getName());
multipart.addBodyPart(attachmentPart);
}
}
message.setContent(multipart);
} catch (WorkflowModuleException | MessagingException | IOException e) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see com.axemble.vdoc.sdk.mail.extensions.BaseMailExtension afterSend()
*/
@Override
protected void afterSend() {
}
/*
* (non-Javadoc)
* @see com.axemble.vdoc.sdk.mail.extensions.BaseMailExtension onPrepare(com.axemble.vdoc.sdk.interfaces.ui.definitions.IBlockDefinition)
*/
@Override
public void onPrepare(IBlockDefinition blockDefinition) {
// retrieve the fragment by its name
IFragmentDefinition fragmentDefinition = blockDefinition.getFragmentByName("marker");
if (fragmentDefinition == null)
return;
// retrieve the section underneath the fragment
IFormSectionBlockDefinition sectionDefinition = (IFormSectionBlockDefinition) fragmentDefinition.getChildren().iterator().next();
// get the definitions factory to build objects
IDefinitionsFactory definitionsFactory = this.getWorkflowModule().getDefinitionsFactory();
// build a table
IFormTableBlockDefinition table = definitionsFactory.newFormTableBlockDefinition();
sectionDefinition.addNode(table);
// retrieve all the properties of the current
Collection<IProperty> properties = (Collection<IProperty>) getWorkflowInstance().getDefinition().getProperties();
if (properties != null) {
// step through the properties
for (IProperty property : properties) {
if (!(property.getType() == IProperty.IType.STRING || property.getType() == IProperty.IType.DATE || property.getType() == IProperty.IType.FLOAT || property.getType() == IProperty.IType.LONG))
continue;
// build a line
IFormLineBlockDefinition fieldLine = definitionsFactory.newFormLineBlockDefinition();
table.addNode(fieldLine);
// with two cells
IFormCellBlockDefinition leftCell = definitionsFactory.newFormCellBlockDefinition();
leftCell.setCssClass("cell-left");
IFormCellBlockDefinition rightCell = definitionsFactory.newFormCellBlockDefinition();
rightCell.setCssClass("cell-right");
fieldLine.addNode(leftCell);
fieldLine.addNode(rightCell);
ITextDefinition fieldLabelDef = definitionsFactory.newTextDefinition();
fieldLabelDef.setContent(property.getLabel());
IContentDefinition contentDef = null;
if (property.getType() == IProperty.IType.STRING) {
ITextInputDefinition fieldValueDef = definitionsFactory.newTextInputDefinition();
fieldValueDef.setProperty((IProtocolSupport) property);
contentDef = fieldValueDef;
} else if (property.getType() == IProperty.IType.DATE) {
IDateInputDefinition fieldValueDef = definitionsFactory.newDateInputDefinition();
fieldValueDef.setProperty((IProtocolSupport) property);
contentDef = fieldValueDef;
} else if (property.getType() == IProperty.IType.LONG) {
if (property.getElementType() == IProperty.IElementType.USER) {
if (property.isCollection()) {
IMultipleUserInputDefinition fieldValueDef = definitionsFactory.newMultipleUserInputDefinition();
fieldValueDef.setProperty((IProtocolSupport) property);
contentDef = fieldValueDef;
} else {
ISingleUserInputDefinition fieldValueDef = definitionsFactory.newSingleUserInputDefinition();
fieldValueDef.setProperty((IProtocolSupport) property);
contentDef = fieldValueDef;
}
}
} else if (property.getType() == IProperty.IType.FLOAT) {
IFloatInputDefinition fieldValueDef = definitionsFactory.newFloatInputDefinition();
fieldValueDef.setProperty((IProtocolSupport) property);
contentDef = fieldValueDef;
}
leftCell.addNode(fieldLabelDef);
rightCell.addNode(contentDef);
}
}
}
/*
* (non-Javadoc)
* @see com.axemble.vdoc.sdk.mail.extensions.BaseMailExtension onFillRecipients(com.axemble.vdoc.sdk.structs.MailRecipients)
*/
@Override
public void onFillRecipients(MailRecipients mailRecipients) {
super.onFillRecipients(mailRecipients);
try {
// retrieve the catalog from the current workflow instance
ICatalog catalog = this.getWorkflowInstance().getCatalog();
// assign all the members of the 'HRManager' operator role to the copy message recipient
IOperatorRole operatorRole = catalog.getOperatorRole("Manager");
if (operatorRole != null)
mailRecipients.addUserRecipients(Message.RecipientType.CC, operatorRole.getAllMembers());
Address address = new InternetAddress("dream.team@clouds.com", "Dream Team");
mailRecipients.addRecipient(Message.RecipientType.CC, address);
Collection<InternetAddress> externalAddresses = new ArrayList<InternetAddress>();
externalAddresses.add(new InternetAddress("nadra.xela@clouds.com", "Nadra Xela"));
externalAddresses.add(new InternetAddress("avi.lio@clouds.com", "Avi Lio"));
externalAddresses.add(new InternetAddress("vannyly.burton@clouds.com", "Vannyly Burton"));
externalAddresses.add(new InternetAddress("phil.loxera@clouds.com", "Phil Loxera"));
mailRecipients.addRecipients(Message.RecipientType.CC, externalAddresses);
} catch (Exception e) {
throw new SDKException(e);
}
}
/*
* (non-Javadoc)
* @see com.axemble.vdoc.sdk.mail.extensions.BaseMailExtension onFillLanguage()
*/
@Override
protected String onFillLanguage() {
// force the language to Greek, LOL!
return super.onFillLanguage();
}
}