Java tutorial
/** * Copyright 2007-2010 ? * All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses. * */ package org.fireflow.engine.modules.script; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptException; import javax.script.SimpleScriptContext; import javax.xml.namespace.QName; import org.apache.commons.jexl2.JexlEngine; import org.apache.commons.jexl2.UnifiedJEXL; import org.apache.commons.jxpath.JXPathContext; import org.fireflow.client.WorkflowSession; import org.fireflow.client.impl.WorkflowSessionLocalImpl; import org.fireflow.engine.context.RuntimeContext; import org.fireflow.engine.entity.runtime.ActivityInstance; import org.fireflow.engine.entity.runtime.ProcessInstance; import org.fireflow.engine.exception.InvalidOperationException; import org.fireflow.engine.invocation.Message; import org.fireflow.engine.modules.script.functions.DateTimeUtil; import org.fireflow.engine.modules.script.functions.JexlContext4Fireflow; import org.fireflow.engine.modules.script.functions.XPath; import org.fireflow.model.binding.Assignment; import org.fireflow.model.data.Expression; import org.firesoa.common.jxpath.model.dom.W3CDomFactory; import org.firesoa.common.schema.NameSpaces; import org.firesoa.common.util.JavaDataTypeConvertor; import org.firesoa.common.util.ScriptLanguages; /** * * * @author ? * @version 2.0 */ public class ScriptEngineHelper { // private static final Dom4JFactory dom4JFactory = new Dom4JFactory(); private static final W3CDomFactory w3cDomFactory = new W3CDomFactory(); // static{ // JXPathContextReferenceImpl.addNodePointerFactory(new Dom4JPointerFactory()); // } private static final Map<String, Object> jexlFunctionsMap = new HashMap<String, Object>(); private static final JexlEngine jexlEngine = new JexlEngine(); static { //TODO functionxml jexlFunctionsMap.put("DateUtil", DateTimeUtil.getInstance()); jexlFunctionsMap.put("Xpath", XPath.class); jexlEngine.setFunctions(jexlFunctionsMap); } //??? public static Object evaluateExpression(RuntimeContext rtCtx, Expression fireflowExpression, Map<String, Object> contextObjects) { if (fireflowExpression == null) return null; if (fireflowExpression.getNamespaceMap() != null && fireflowExpression.getNamespaceMap().size() > 0) { contextObjects.put(XPath.NAMESPACE_PREFIX_URI_MAP, fireflowExpression.getNamespaceMap()); } if (ScriptLanguages.JEXL.name().equalsIgnoreCase(fireflowExpression.getLanguage())) { return evaluateJexlExpression(fireflowExpression, contextObjects); } else if (ScriptLanguages.UNIFIEDJEXL.name().equalsIgnoreCase(fireflowExpression.getLanguage())) { return evaluateUnifiedJexlExpression(fireflowExpression, contextObjects); } else if (ScriptLanguages.XPATH.name().equalsIgnoreCase(fireflowExpression.getLanguage())) { return evaluateXpathExpression(fireflowExpression, contextObjects); } else { return evaluateJSR233Expression(rtCtx, fireflowExpression, contextObjects); } } private static Object evaluateJSR233Expression(RuntimeContext rtCtx, Expression fireflowExpression, Map<String, Object> contextObjects) { ScriptEngine scriptEngine = rtCtx.getScriptEngine(fireflowExpression.getLanguage()); ScriptContext scriptContext = new SimpleScriptContext(); Bindings engineScope = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE); engineScope.putAll(contextObjects); try { Object result = scriptEngine.eval(fireflowExpression.getBody(), scriptContext); return result; } catch (ScriptException e) { throw new RuntimeException("Can NOT evaluate the expression. ", e); } } private static Object evaluateJexlExpression(Expression fireflowExpression, Map<String, Object> contextObjects) { JexlContext4Fireflow context = new JexlContext4Fireflow(); context.setAllContextObject(contextObjects); org.apache.commons.jexl2.Expression jexlExp = jexlEngine.createExpression(fireflowExpression.getBody()); return jexlExp.evaluate(context); } private static Object evaluateUnifiedJexlExpression(Expression fireflowExpression, Map<String, Object> contextObjects) { JexlContext4Fireflow context = new JexlContext4Fireflow(); context.setAllContextObject(contextObjects); UnifiedJEXL ujexl = new UnifiedJEXL(jexlEngine); UnifiedJEXL.Expression jexlExp = ujexl.parse(fireflowExpression.getBody()); Object result = jexlExp.evaluate(context); return result == null ? null : result.toString(); } private static Object evaluateXpathExpression(Expression fireflowExpression, Map<String, Object> contextObjects) { Map<String, String> namespacePrefixUriMap = fireflowExpression.getNamespaceMap(); JXPathContext jxpathContext = JXPathContext.newContext(contextObjects); jxpathContext.setFactory(w3cDomFactory); if (namespacePrefixUriMap != null) { Iterator<String> prefixIterator = namespacePrefixUriMap.keySet().iterator(); while (prefixIterator.hasNext()) { String prefix = prefixIterator.next(); String nsUri = namespacePrefixUriMap.get(prefix); jxpathContext.registerNamespace(prefix, nsUri); } } //W3C DOM //TODO ?dom4j document?jdom document Object obj = null; Object _node = jxpathContext.selectSingleNode(fireflowExpression.getBody()); if (_node instanceof org.w3c.dom.Node) { if (_node instanceof org.w3c.dom.Document) { obj = _node; } else { obj = ((org.w3c.dom.Node) _node).getTextContent(); } } else { obj = _node; } return obj; } /** * Context, * * @param session * @param processInstance * @param activityInstance * @return */ public static Map<String, Object> fulfillScriptContext(WorkflowSession session, RuntimeContext runtimeContext, ProcessInstance processInstance, ActivityInstance activityInstance) { WorkflowSessionLocalImpl localSession = (WorkflowSessionLocalImpl) session; Map<String, Object> engineScope = new HashMap<String, Object>(); engineScope.put(ScriptContextVariableNames.CURRENT_PROCESS_INSTANCE, processInstance); engineScope.put(ScriptContextVariableNames.CURRENT_ACTIVITY_INSTANCE, activityInstance); Map<String, Object> varValues = processInstance.getVariableValues(session); engineScope.put(ScriptContextVariableNames.PROCESS_VARIABLES, varValues); if (activityInstance != null) { Map<String, Object> varValues2 = activityInstance.getVariableValues(session); engineScope.put(ScriptContextVariableNames.ACTIVITY_VARIABLES, varValues2); } engineScope.put(ScriptContextVariableNames.SESSION_ATTRIBUTES, localSession.getAllAttributes()); engineScope.put(ScriptContextVariableNames.WORKFLOW_SESSION, session); engineScope.put(ScriptContextVariableNames.RUNTIME_CONTEXT, runtimeContext); return engineScope; } public static Map<String, Object> resolveAssignments(RuntimeContext runtimeContext, List<Assignment> assignments, Map<String, Object> contextVars) throws ScriptException { if (assignments == null || assignments.size() == 0) { return null; } Map<String, Object> jxpathRoot = new HashMap<String, Object>(); if (contextVars.get(ScriptContextVariableNames.INPUTS) != null) { jxpathRoot.put(ScriptContextVariableNames.INPUTS, contextVars.get(ScriptContextVariableNames.INPUTS)); } else { jxpathRoot.put(ScriptContextVariableNames.INPUTS, new HashMap<String, Object>()); } if (contextVars.get(ScriptContextVariableNames.OUTPUTS) != null) { jxpathRoot.put(ScriptContextVariableNames.OUTPUTS, contextVars.get(ScriptContextVariableNames.OUTPUTS)); } else { jxpathRoot.put(ScriptContextVariableNames.OUTPUTS, new HashMap<String, Object>()); } jxpathRoot.put(ScriptContextVariableNames.PROCESS_VARIABLES, new HashMap<String, Object>()); jxpathRoot.put(ScriptContextVariableNames.ACTIVITY_VARIABLES, new HashMap<String, Object>()); jxpathRoot.put(ScriptContextVariableNames.SESSION_ATTRIBUTES, new HashMap<String, Object>()); for (Assignment assignment : assignments) { Expression fromExpression = assignment.getFrom(); Object obj = evaluateExpression(runtimeContext, fromExpression, contextVars); if (fromExpression.getDataType() != null && obj != null) { try { obj = JavaDataTypeConvertor.dataTypeConvert(fromExpression.getDataType(), obj, null); } catch (ClassCastException e) { throw new ScriptException(e); } catch (ClassNotFoundException e) { throw new ScriptException(e); } } // TODO To ?JXpath??? Expression toExpression = assignment.getTo(); QName dataType = toExpression.getDataType(); if (dataType != null && dataType.getNamespaceURI().equals(NameSpaces.JAVA.getUri()) && obj != null) {// ?? try { obj = JavaDataTypeConvertor.dataTypeConvert(dataType, obj, null); } catch (ClassCastException e) { throw new ScriptException(e); } catch (ClassNotFoundException e) { throw new ScriptException(e); } } else { // XSD?? //TODO (?)datestring if (obj instanceof java.util.Date) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); obj = df.format((java.util.Date) obj); } } JXPathContext jxpathContext = JXPathContext.newContext(jxpathRoot); jxpathContext.setFactory(w3cDomFactory); Map<String, String> nsMap = toExpression.getNamespaceMap(); Iterator<String> prefixIterator = nsMap.keySet().iterator(); while (prefixIterator.hasNext()) { String prefix = prefixIterator.next(); String nsUri = nsMap.get(prefix); jxpathContext.registerNamespace(prefix, nsUri); } //? jxpathContext.createPathAndSetValue(toExpression.getBody(), obj); } return jxpathRoot; } /** * ?? * * @return */ @SuppressWarnings({ "rawtypes", "restriction", "unchecked" }) public static Map<String, Object> resolveInputParameters(RuntimeContext runtimeContext, List<Assignment> inputAssignments, Map<String, Object> contextVars) throws ScriptException { Map<String, Object> result = resolveAssignments(runtimeContext, inputAssignments, contextVars); if (result != null) { Map tmp = (Map) result.get(ScriptContextVariableNames.INPUTS); return tmp; } else { return null; } } @SuppressWarnings({ "restriction", "rawtypes", "unchecked" }) public static void assignOutputToVariable(WorkflowSession session, RuntimeContext runtimeContext, ProcessInstance processInstance, ActivityInstance activityInstance, List<Assignment> assignmentsList, Map<String, Object> contextVars) throws ScriptException { WorkflowSessionLocalImpl localSession = (WorkflowSessionLocalImpl) session; if (assignmentsList == null || assignmentsList.size() == 0) return; Map<String, Object> result = resolveAssignments(runtimeContext, assignmentsList, contextVars); //System.out.println("===??Assignment is "+result); if (result == null) return; Map<String, Object> procInstVars = (Map<String, Object>) result .get(ScriptContextVariableNames.PROCESS_VARIABLES); if (procInstVars != null && procInstVars.size() > 0) { Iterator<String> keys = procInstVars.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); try { Object value = procInstVars.get(key); if (value instanceof Message) { processInstance.setVariableValue(session, key, ((Message) value).getPayload(), ((Message) value).getHeaders()); } else { processInstance.setVariableValue(session, key, value); } } catch (InvalidOperationException e) { throw new ScriptException(e); } } } Map<String, Object> actInstVars = (Map<String, Object>) result .get(ScriptContextVariableNames.ACTIVITY_VARIABLES); if (actInstVars != null && actInstVars.size() > 0) { Iterator<String> keys = actInstVars.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); try { Object value = actInstVars.get(key); if (value instanceof Message) { activityInstance.setVariableValue(session, key, ((Message) value).getPayload(), ((Message) value).getHeaders()); } else { activityInstance.setVariableValue(session, key, value); } } catch (InvalidOperationException e) { throw new ScriptException(e); } } } Map<String, Object> sessionAttrs = (Map<String, Object>) result .get(ScriptContextVariableNames.SESSION_ATTRIBUTES); if (sessionAttrs != null && sessionAttrs.size() > 0) { Iterator<String> keys = sessionAttrs.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); localSession.setAttribute(key, sessionAttrs.get(key)); } } } }