1 package org.jbpm.graph.action; 2 3 import java.util.HashMap ; 4 import java.util.HashSet ; 5 import java.util.Iterator ; 6 import java.util.Map ; 7 import java.util.Set ; 8 9 import bsh.EvalError; 10 import bsh.Interpreter; 11 12 import org.apache.commons.logging.Log; 13 import org.apache.commons.logging.LogFactory; 14 import org.dom4j.Element; 15 import org.jbpm.context.def.VariableAccess; 16 import org.jbpm.context.exe.ContextInstance; 17 import org.jbpm.graph.def.Action; 18 import org.jbpm.graph.exe.ExecutionContext; 19 import org.jbpm.graph.exe.Token; 20 import org.jbpm.jpdl.xml.JpdlXmlReader; 21 import org.jbpm.jpdl.xml.Parsable; 22 23 public class Script extends Action implements Parsable { 24 25 private static final long serialVersionUID = 1L; 26 27 protected String expression = null; 28 protected Set variableAccesses = null; 29 30 public void read(Element scriptElement, JpdlXmlReader jpdlReader) { 31 if (scriptElement.isTextOnly()) { 32 expression = scriptElement.getTextTrim(); 33 } else { 34 this.variableAccesses = new HashSet (jpdlReader.readVariableAccesses(scriptElement)); 35 expression = scriptElement.element("expression").getTextTrim(); 36 } 37 } 38 39 public void execute(ExecutionContext executionContext) { 40 Map outputMap = eval(executionContext); 41 setVariables(outputMap, executionContext); 42 } 43 44 public Map eval(Token token) { 45 return eval(new ExecutionContext(token)); 46 } 47 48 public Map eval(ExecutionContext executionContext) { 49 Map inputMap = createInputMap(executionContext); 50 Set outputNames = getOutputNames(); 51 return eval(inputMap, outputNames); 52 } 53 54 public Map createInputMap(ExecutionContext executionContext) { 55 Map inputMap = new HashMap (); 56 inputMap.put( "executionContext", executionContext ); 57 inputMap.put( "token", executionContext.getToken() ); 58 inputMap.put( "node", executionContext.getNode() ); 59 inputMap.put( "task", executionContext.getTask() ); 60 inputMap.put( "taskInstance", executionContext.getTaskInstance() ); 61 62 ContextInstance contextInstance = executionContext.getContextInstance(); 64 if (! hasReadableVariable()) { 65 Map variables = contextInstance.getVariables(); 67 if ( variables != null ) { 68 Iterator iter = variables.entrySet().iterator(); 69 while( iter.hasNext() ) { 70 Map.Entry entry = (Map.Entry ) iter.next(); 71 String variableName = (String ) entry.getKey(); 72 Object variableValue = entry.getValue(); 73 inputMap.put(variableName, variableValue); 74 } 75 } 76 77 } else { 78 Iterator iter = variableAccesses.iterator(); 80 while (iter.hasNext()) { 81 VariableAccess variableAccess = (VariableAccess) iter.next(); 82 if (variableAccess.isReadable()) { 83 String variableName = variableAccess.getVariableName(); 84 String mappedName = variableAccess.getMappedName(); 85 Object variableValue = contextInstance.getVariable(variableName); 86 inputMap.put(mappedName, variableValue); 87 } 88 } 89 } 90 91 return inputMap; 92 } 93 94 public Map eval(Map inputMap, Set outputNames) { 95 Map outputMap = new HashMap (); 96 97 try { 98 log.debug("script input: "+inputMap); 99 Interpreter interpreter = new Interpreter(); 100 Iterator iter = inputMap.keySet().iterator(); 101 while (iter.hasNext()) { 102 String inputName = (String ) iter.next(); 103 Object inputValue = inputMap.get(inputName); 104 if (inputValue!=null) { 105 interpreter.set(inputName, inputValue); 106 } 107 } 108 interpreter.eval(expression); 109 iter = outputNames.iterator(); 110 while (iter.hasNext()) { 111 String outputName = (String ) iter.next(); 112 Object outputValue = interpreter.get(outputName); 113 outputMap.put(outputName, outputValue); 114 } 115 log.debug("script output: "+outputMap); 116 } catch (EvalError e) { 117 throw new RuntimeException ("can't evaluate beanshell script '"+expression+"'", e); 118 } 119 120 return outputMap; 121 } 122 123 public void addVariableAccess(VariableAccess variableAccess) { 124 if (variableAccesses==null) variableAccesses = new HashSet (); 125 variableAccesses.add(variableAccess); 126 } 127 128 Set getOutputNames() { 129 Set outputNames = new HashSet (); 130 if (variableAccesses!=null) { 131 Iterator iter = variableAccesses.iterator(); 132 while (iter.hasNext()) { 133 VariableAccess variableAccess = (VariableAccess) iter.next(); 134 if (variableAccess.isWritable()) { 135 outputNames.add(variableAccess.getMappedName()); 136 } 137 } 138 } 139 return outputNames; 140 } 141 142 boolean hasReadableVariable() { 143 if (variableAccesses==null) return false; 144 Iterator iter = variableAccesses.iterator(); 145 while (iter.hasNext()) { 146 VariableAccess variableAccess = (VariableAccess) iter.next(); 147 if (variableAccess.isReadable()) { 148 return true; 149 } 150 } 151 return false; 152 } 153 154 void setVariables(Map outputMap, ExecutionContext executionContext) { 155 if ( (outputMap!=null) 156 && (!outputMap.isEmpty()) 157 && (executionContext!=null) 158 ) { 159 Map variableNames = getVariableNames(); 160 ContextInstance contextInstance = executionContext.getContextInstance(); 161 Token token = executionContext.getToken(); 162 163 Iterator iter = outputMap.keySet().iterator(); 164 while (iter.hasNext()) { 165 String mappedName = (String ) iter.next(); 166 String variableName = (String ) variableNames.get(mappedName); 167 contextInstance.setVariable(variableName, outputMap.get(mappedName), token); 168 } 169 } 170 } 171 172 Map getVariableNames() { 173 Map variableNames = new HashMap (); 174 Iterator iter = variableAccesses.iterator(); 175 while (iter.hasNext()) { 176 VariableAccess variableAccess = (VariableAccess) iter.next(); 177 if (variableAccess.isWritable()) { 178 variableNames.put(variableAccess.getMappedName(), variableAccess.getVariableName()); 179 } 180 } 181 return variableNames; 182 } 183 184 public String getExpression() { 185 return expression; 186 } 187 public void setExpression(String expression) { 188 this.expression = expression; 189 } 190 public Set getVariableAccesses() { 191 return variableAccesses; 192 } 193 public void setVariableAccesses(Set variableAccesses) { 194 this.variableAccesses = variableAccesses; 195 } 196 197 private static final Log log = LogFactory.getLog(Script.class); 198 } 199 | Popular Tags |