Package org.jboss.soa.esb.services.jbpm

Source Code of org.jboss.soa.esb.services.jbpm.JBpmObjectMapper

/**
*
*/
package org.jboss.soa.esb.services.jbpm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.crypto.SealedObject;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.tree.DefaultElement;
import org.jboss.internal.soa.esb.assertion.AssertArgument;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.message.format.MessageFactory;
import org.jboss.soa.esb.message.mapping.ObjectMapper;
import org.jboss.soa.esb.message.mapping.ObjectMappingException;
import org.jboss.soa.esb.services.security.SecurityService;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.Token;
import org.mvel2.MVEL;

/**
* Mapping glue between jBPM and ESB. Handles setting up the replyTo of the
* JBpmCallback Service, and is a wrapper around org.jboss.soa.esb.message.mapping.ObjectMapper
* to handle jBPM specifics around mapping variables from jBPM to ESB and back.
*
* @author kstam
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
*/
public class JBpmObjectMapper {

    public JBpmObjectMapper() {
        super();
    }

    private Logger log = Logger.getLogger(getClass());
    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * Creates an ESB Message, giving the mapping specified in the jbpmToEsbVars Element.
     * This element is defined in the jBPM process-definition.xml as child element
     * of either the EsbNotifier ActionHandler, or the EsbActionHandler.
     *
     * @param jbpmToEsbVars - the configuration of the mapping.
     * @param isGlobalProcessScope - Variables will be looked up using either the token scope or the process-definition (global) scope
     * See the jBPM documentation for more details.
     * @param executionContext - the jBPM ExecutionContext.
     * @return the newly created ESB message.
     *
     * @throws Exception
     */
    public Message mapFromJBpmToEsbMessage (final DefaultElement bpmToEsbVars, final Boolean isGlobalProcessScope, final ExecutionContext executionContext)
    {
        Message message = MessageFactory.getInstance().getMessage();
        boolean gblPrcScope = (null == isGlobalProcessScope) ? false : isGlobalProcessScope;

        // Map SecurityContext and AuthRequest if they exist.
        mapSecurityInfoFromJbpmToEsb(gblPrcScope, executionContext, message);

        if (bpmToEsbVars==null) {
            return message;
        }
        List mappings = bpmToEsbVars.elements(Constants.MAPPING_TAG);
        if (mappings.size() < 1) {
            setAllOnEsbMessage(gblPrcScope, executionContext, message);
        } else {
            for (Object mappingElement : mappings) {
                Element element = (Element) mappingElement;
                try {
                    Mapping mapping = Mapping.parseMappingElement(element);
                    setOnEsbMessage(mapping, gblPrcScope, executionContext, message);
                } catch (ConfigurationException ce) {
                    log.error(ce.getMessage(), ce);
                } catch (ObjectMappingException ome) {
                    log.error(ome.getMessage(), ome);
                }
            }
        }
        return message;
    }
    /**
     * Sets all the Objects in the jBPM VariableMap in the body of the ESB Message using the
     * the jBPM object names as the Esb Message body keys.
     *
     * @param gblPrcScope
     * @param executionContext
     * @param message
     */
    private void setAllOnEsbMessage(final boolean gblPrcScope, final ExecutionContext executionContext, Message message)
    {
        Token token = executionContext.getToken();
        ContextInstance ctxInstance = token.getProcessInstance().getContextInstance();
        log.debug("The user has not mapped anything (jbpmToEsbVars is null) " +
                  "so add all the variables using their jBPM name");
        Map map = (gblPrcScope) ? ctxInstance.getVariables() : ctxInstance.getVariables(token);
        if (null != map) {
            for (Iterator iter = map.entrySet().iterator(); iter.hasNext();){
                Map.Entry jBPMVariable = (Map.Entry) iter.next();
                message.getBody().add(jBPMVariable.getKey().toString(), jBPMVariable.getValue());
            }
        }
    }
    /**
     * Sets a jBPM object onto the ESB Message. The mapping is defined in the Mapping element.
     *
     * @param mapping          - Mapping object, used to extract the object from jBPM and used to set the object on the ESB Message
     * @param gblPrcScope      - Global setting for the jBPM scope
     * @param message          - ESB Message
     * @param executionContext - jBPM ExcutionContext
     *
     * @throws ObjectMappingException
     */
    private void setOnEsbMessage(final Mapping mapping, final boolean gblPrcScope, final ExecutionContext executionContext, Message message)
    throws ObjectMappingException, ConfigurationException
    {
        if (mapping.getBpm()==null || "".equals(mapping.getBpm())) {
            throw new ConfigurationException("The 'bpm' attribute is a required attribute");
        }
        if (mapping.getEsb()==null || "".equals(mapping.getEsb())) {
            mapping.setEsb(mapping.getBpm());
        }
        Token token = executionContext.getToken();
        ContextInstance ctxInstance = token.getProcessInstance().getContextInstance();
        //Each mapping can override the global setting
        boolean isPrcScope = (null == mapping.getIsProcessScope()) ? gblPrcScope : mapping.getIsProcessScope();
        //By default assume the object is part of the jBPM variableMap
        Object object = getObjectFromJBpmVariableMap(isPrcScope, mapping.getBpm(), ctxInstance, token);
        //if that fails then try to get it from the ExecutionContext
        if (object==null) {
            object = MVEL.getProperty(mapping.getBpm(), executionContext);
        }
        if (null != object) {
            ObjectMapper mapper = new ObjectMapper();
            mapper.setObjectOnMessage(message, mapping.getEsb(), object);
        } else {
            log.warn("The object " + mapping.getBpm() + " is null and cannot not be set on the message");
        }
    }
    /**
     * Obtains an Object from the jBPM variableMap.
     *
     * @param isPrcScope - if true, within process-instance scope, if false, within token scope, or up the token hierarchy.
     * @param expression - MVEL expression String.
     * @param ctxInstance - jBPM ContextInstance where the jBPM variableMap lives.
     * @param token - the current jBPM token, needed if isPrcScope is false.
     * @return
     */
    private Object getObjectFromJBpmVariableMap(final boolean isPrcScope, final String expression, final ContextInstance ctxInstance, final Token token)
    {
        Object object = null;
        String objectName = expression;
        String remainingExpression = null;
        int dotPosition=expression.indexOf(".");
        if (dotPosition > 0) {
            objectName = expression.substring(0, dotPosition);
            remainingExpression = expression.substring(dotPosition+1);
        }
        if (isPrcScope) {
            object = ctxInstance.getVariable(objectName);
        } else {
            object = ctxInstance.getVariable(objectName, token);
        }
        if (object !=null && remainingExpression!=null) {
            log.debug("Using MVEL to obtain the object from " + object + " using expression: " + remainingExpression);
            object = MVEL.getProperty(remainingExpression, object);
        }
        return object;
    }
    /**
     *
     * @param message
     * @param esbToBpmXml
     * @return
     */
    public HashMap<String,Object> mapFromEsbMessageToJBpmMap(Message message, final String esbToBpmXml)
    throws ConfigurationException
    {
        return mapFromEsbMessageToJBpmMap(message, getMappingList(esbToBpmXml));
    }
    /**
     * This
     * @param message
     * @param token
     * @throws Exception
     */
    public HashMap<String,Object> mapFromEsbMessageToJBpmMap (Message message, final List<Mapping> mappingList)
    {
        HashMap<String,Object> map = new HashMap<String, Object>();
        if (null==mappingList || mappingList.size()<1) {
            return null;
        }
        for (Mapping mapping: mappingList) {
            if (mapping.getBpm()==null || "".equals(mapping.getBpm())) {

                mapping.setBpm(mapping.getEsb());
            }
            Object value = null;
            try {
                value = getObjectFromMessage(message, mapping);
            } catch (ConfigurationException ce) {
                log.error(ce.getMessage(), ce);
            }
            // only put it in the map if it's not null
            if (null!=value)
                map.put(mapping.getBpm(), value);
        }
        map.putAll(mapSecurityContextFromEsbMessageToJBpmMap(message));
        map.putAll(mapAuthRequestFromEsbMessageToJBpmMap(message));
        return map;
    }
    /**
     *
     * @param message
     * @param esbToBpmXml
     * @return
     */
    public HashMap<Mapping,Object> mapFromEsbMessageToJBpmMapping(Message message, final String esbToBpmXml)
    throws ConfigurationException
    {
        return mapFromEsbMessageToJBpmMapping(message, getMappingList(esbToBpmXml));
    }
    /**
     * This
     * @param message
     * @param token
     * @throws Exception
     */
    public HashMap<Mapping,Object> mapFromEsbMessageToJBpmMapping(Message message, final List<Mapping> mappingList)
    {
        HashMap<Mapping,Object> map = new HashMap<Mapping, Object>();
        if (null==mappingList || mappingList.size()<1) {
            return null;
        }
        for (Mapping mapping: mappingList) {
            if (mapping.getBpm()==null || "".equals(mapping.getBpm())) {

                mapping.setBpm(mapping.getEsb());
            }
            Object value = null;
            try {
                value = getObjectFromMessage(message, mapping);
            } catch (ConfigurationException ce) {
                log.error(ce.getMessage(), ce);
            }
            // only put it in the map if it's not null
            if (null!=value)
                map.put(mapping, value);
        }
        return map;
    }

    private List<Mapping> getMappingList(final String esbToBpmXml)
      throws ConfigurationException
    {
        final List<Mapping> mappingList = new ArrayList<Mapping>();
        if (esbToBpmXml!=null) {
            try {
                Document document = DocumentHelper.parseText(esbToBpmXml);
                Element element = document.getRootElement();
                Iterator iterator=element.elementIterator();
                while(iterator.hasNext()) {
                    Element mappingElement = (Element) iterator.next();
                    Mapping mapping = Mapping.parseMappingElement(mappingElement);
                    mappingList.add(mapping);
                }
            } catch (DocumentException de) {
                throw new ConfigurationException(de.getMessage(), de);
            }
        }
        return mappingList ;
    }

    private Object getObjectFromMessage(Message message, Mapping mapping)
    throws ConfigurationException
    {
        Object value = null;
        if (mapping.getEsb()==null || "".equals(mapping.getEsb())) {
            throw new ConfigurationException("The 'esb' attribute is a required attribute");
        }
        try {
            value = objectMapper.getObjectFromMessage(message, mapping.getEsb());
        } catch (ObjectMappingException ome) {
            log.info(mapping.getEsb() + " not found");
        }
        if (value == null) {
            value = mapping.getDefaultValue();
        }
        log.debug("value=" + value);
        return value;
    }

    public HashMap<String, Object> mapSecurityContextFromEsbMessageToJBpmMap(final Message message)
    {
        final HashMap<String, Object> map = new HashMap<String, Object>();
        final SealedObject sealedObject = (SealedObject) message.getContext().getContext(SecurityService.CONTEXT);
        if (sealedObject !=null)
        {
            map.put(Constants.SECURITY_CONTEXT, sealedObject);
        }
        return map;
    }

    public HashMap<String, ?> mapAuthRequestFromEsbMessageToJBpmMap(final Message message)
    {
        final HashMap<String, Object> map = new HashMap<String, Object>();
        final byte[] encryptedAuthRequest = (byte[]) message.getContext().getContext(SecurityService.AUTH_REQUEST);
        if (encryptedAuthRequest != null)
        {
            map.put(Constants.AUTH_REQUEST, encryptedAuthRequest);
        }
        return map;
    }

    /**
     * Will map the SecurityContext and AuthenticationRequest from a jBPM
     * variable to ESB Message context.
     *
     * @param gblPrcScope   True if the process scope is global.
     * @param executionContext The jBPM execution context.
     * @param esbMessage The distination ESB message
     * @return
     */
    public Message mapSecurityInfoFromJbpmToEsb(final boolean gblPrcScope, final ExecutionContext executionContext, final Message esbMessage)
    {
        AssertArgument.isNotNull(executionContext, "executionContext");
        AssertArgument.isNotNull(esbMessage, "esbMessage");

        final Token token = executionContext.getToken();
        final ContextInstance ctxInstance = token.getProcessInstance().getContextInstance();
        final Map jbpmMap = (gblPrcScope) ? ctxInstance.getVariables() : ctxInstance.getVariables(token);

        if (jbpmMap == null)
        {
            return esbMessage;
        }

        final Object sealedObject = jbpmMap.get(Constants.SECURITY_CONTEXT);
        if (sealedObject != null)
        {
           esbMessage.getContext().setContext(SecurityService.CONTEXT, sealedObject);
        }

        final Object encrypedAutRequest = jbpmMap.get(Constants.AUTH_REQUEST);
        if (encrypedAutRequest != null)
        {
           esbMessage.getContext().setContext(SecurityService.AUTH_REQUEST, encrypedAutRequest);
        }

        return esbMessage;
    }
}
TOP

Related Classes of org.jboss.soa.esb.services.jbpm.JBpmObjectMapper

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.