org.mule.transport.bpm.jbpm4.customactivity.SendMuleEvent.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.transport.bpm.jbpm4.customactivity.SendMuleEvent.java

Source

/*
 * $Id$
 * --------------------------------------------------------------------------------------
 * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 *
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */

package org.mule.transport.bpm.jbpm4.customactivity;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.jxpath.JXPathContext;
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.mule.api.MuleMessage;
import org.mule.api.config.MuleProperties;
import org.mule.transport.bpm.MessageService;
import org.mule.transport.bpm.ProcessConnector;
import org.mule.transport.bpm.jbpm4.Jbpm4;

/**
 * Sends a Mule message to the specified endpoint. If the message is
 * synchronous, the response from Mule will be automatically stored in
 * PROCESS_VARIABLE_INCOMING.
 * 
 * In mule config -
 * 
 * <spring:bean id="sendMuleEvent"
 * class="org.mule.transport.bpm.jbpm4.customactivity.SendMuleEvent"
 * scope="prototype" > <spring:property name="jbpm4" ref="jbpm4"/>
 * </spring:bean>
 * 
 * In jpdl - <custom expr="#{sendMuleEvent}" g="713,453,130,52" name="step1">
 * <field name="endpoint"><string value="endpointName"/></field> <field
 * name="payloadSource"><string value="variableName"/></field> <!-- variable
 * defaults to "incoming" if not set --> <field name="variableName"><string
 * value="variableNameToStoreResponseIn"/></field> <field
 * name="synchronous"><true/></field> <transition g="-113,-8"
 * name="to processResponse" to="processResponse"/> </custom>
 * 
 * @param endpoint
 *           - the Mule endpoint
 * @param transformers
 *           - any transformers to be applied
 * @param payload
 *           - specify the payload as a string directly in the jPDL
 * @param payloadSource
 *           - process variable from which to generate the message payload,
 *           defaults to {@link ProcessConnector.PROCESS_VARIABLE_DATA} or
 *           {@link ProcessConnector.PROCESS_VARIABLE_INCOMING}
 * @param messageProperties
 *           - any properties to be applied to the message
 */
public class SendMuleEvent extends LoggingCustomActivity {

    boolean synchronous = true;
    String endpoint = null;
    String transformers = null;
    Map<String, Object> properties = null;

    // Use "payload" to easily specify the payload as a string directly in the
    // jPDL.
    // Use "payloadSource" to get the payload from a process variable.
    String payload = null;
    String payloadSource = null;

    // The name of the variable can be changed by setting field "variableName" in
    // the process definition
    String variableName = ProcessConnector.PROCESS_VARIABLE_INCOMING;

    // The actual payload (as an object) will be stored here.
    private Object payloadObject;

    protected Jbpm4 jbpm4 = null;

    @Override
    public void execute(ActivityExecution execution) throws Exception {
        super.execute(execution);
        sendMuleEvent(execution);
        execution.waitForSignal();
    }

    @Override
    public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) {
        execution.takeDefaultTransition();
    }

    public void sendMuleEvent(ActivityExecution execution) throws Exception {
        if (jbpm4 == null) {
            throw new Exception("Configuration problem - Jbpm4 is null. " + "Its reference needs to be set.");
        }
        MessageService mule = jbpm4.getMessageService();

        if (transformers != null) {
            endpoint += "?transformers=" + transformers;
        }

        if (payload == null) {
            if (payloadSource == null) {
                payloadObject = execution.getVariable(ProcessConnector.PROCESS_VARIABLE_DATA);
                if (payloadObject == null) {
                    payloadObject = execution.getVariable(ProcessConnector.PROCESS_VARIABLE_INCOMING);
                }
            } else {
                // The payloadSource may be specified using JavaBean notation (e.g.,
                // "myObject.myStuff.myField" would first retrieve the process
                // variable "myObject" and then call .getMyStuff().getMyField()
                String[] tokens = org.apache.commons.lang.StringUtils.split(payloadSource, ".", 2);
                payloadObject = execution.getVariable(tokens[0]);
                if (tokens.length > 1) {
                    JXPathContext context = JXPathContext.newContext(payloadObject);
                    payloadObject = context.getValue(tokens[1].replaceAll("\\.", "/"));
                }
            }
        } else {
            payloadObject = payload;
        }
        if (payloadObject == null) {
            throw new IllegalArgumentException(
                    "Payload for message is null.  Payload source is \"" + payloadSource + "\"");
        }

        Map<String, Object> props = new HashMap<String, Object>();

        // TODO: this probably isn't the best. I'm casting to an Impl because it's
        // the only way I could see to get the name of the process definition
        props.put(ProcessConnector.PROPERTY_PROCESS_TYPE,
                ((ExecutionImpl) execution).getProcessDefinition().getName());
        props.put(ProcessConnector.PROPERTY_PROCESS_ID, execution.getProcessInstance().getId());
        props.put(MuleProperties.MULE_CORRELATION_ID_PROPERTY, execution.getProcessInstance().getId());
        /*
         * TODO: get process start // looks like we can get this from
         * historyService, but do we really need it? props
         * .put(ProcessConnector.PROPERTY_PROCESS_STARTED, );
         */
        if (properties != null) {
            props.putAll(properties);
        }

        MuleMessage response = mule.generateMessage(endpoint, payloadObject, props, synchronous);
        if (synchronous) {
            if (response != null) {
                execution.setVariable(variableName, response.getPayload());
            } else {
                log.info(
                        "Synchronous message was sent to endpoint " + endpoint + ", but no response was returned.");
            }
        }

    }

    public void setJbpm4(Jbpm4 jbpm4) {
        this.jbpm4 = jbpm4;
    }
}