[jboss-user] [JBoss jBPM] - Re: dynamic commands
gogoasa
do-not-reply at jboss.com
Fri Sep 21 06:01:33 EDT 2007
Here is my current implementation of BshCommand in case anybody needs it.
It supports passing optional parameters to scripts (in case you keep your script as a resource and want to pass it a parameter without having to String.replaceAll(...):
package org.jbpm.command;
|
| import java.util.HashMap;
| import java.util.Iterator;
| import java.util.Map;
|
| import org.jbpm.JbpmContext;
|
| import bsh.Interpreter;
|
| /**
| * this Command executes a BeanShell script, optionally binding some variables.
| * This way you can dynamically execute arbitrary code on your jBPM installation.
| */
| public class BshCommand implements Command {
|
| String JBPMCONTEXT_BINDING_VARIABLE = "jbpmContext";
|
| // the script code
| protected String code;
|
| // variables to bind
| protected Map scriptVariables;
|
| public BshCommand(String code) {
| this(code, new HashMap());
| }
|
| public BshCommand(String code, Map scriptVariables) {
| this.setCode(code);
| this.setScriptVariables(scriptVariables);
| }
|
| /**
| * as Java does not have inline constructors for Maps but it does have constructors for arrays, you may prefer to provide
| * arguments using this constructor.
| *
| * @see BshCommand(String code, Map scriptVariables)
| */
| public BshCommand(String code, String[] keys, Object[] values) {
| if (keys == null || values == null)
| throw new NullPointerException("cannot accept null keys or values");
| if (keys.length != values.length)
| throw new IllegalArgumentException("keys and values arrays must be of the same length");
|
| Map map = new HashMap();
| for (int i = 0; i < keys.length; i++)
| map.put(keys, values);
|
| this.setCode(code);
| this.setScriptVariables(map);
| }
|
| /**
| * convenient alias for BshCommand(String code, String[] keys, Object[] values) if you only want to pass one argument to
| * your script
| */
| public BshCommand(String code, String key, Object value) {
| this(code, new String[] {key}, new Object[] {value});
| }
|
|
| public Object execute(JbpmContext jbpmContext) throws Exception {
| Interpreter interpreter = new Interpreter();
|
| interpreter.set(JBPMCONTEXT_BINDING_VARIABLE, jbpmContext);
|
| if (this.scriptVariables != null) {
| for (Iterator i = this.scriptVariables.keySet().iterator(); i.hasNext();) {
| String varName = (String) i.next();
| if (varName.equals(JBPMCONTEXT_BINDING_VARIABLE))
| continue;
| Object o = this.scriptVariables.get(varName);
| interpreter.set(varName, o);
| }
| }
| Object result = interpreter.eval(this.getCode());
| return result;
| }
|
| // accessors
|
| public String getCode() {
| return code;
| }
|
| public void setCode(String code) {
| this.code = code;
| }
|
| public Map getScriptVariables() {
| return scriptVariables;
| }
|
| public void setScriptVariables(Map scriptVariables) {
| this.scriptVariables = scriptVariables;
| }
|
| private static final long serialVersionUID = 1L;
| }
|
some usage example. Suppose you have a script like this as a classpath resource (do not call it script.bsh if you deploy under jboss because jboss will think it must deploy it as an ejb. Call it moveTokenToNodeAndSignal.bsh.command for example):
| // forcibly move a process instance's token to "System error" node and signal it to "restart".
|
| pi = jbpmContext.getProcessInstance(pid);
| tk = pi.getRootToken();
|
| pdef = pi.getProcessDefinition();
| node = pdef.getNode("System error");
|
| tk.addLog(new org.jbpm.logging.log.MessageLog("forcing restart of process that has no 'restart' leaving transition"));
| tk.setNode(node);
| tk.signal("restart");
| String script = IOUtils.toString(this.getClass().getClassLoader().getResourceAsStream("moveTokenToNodeAndSignal.bsh.command"));
| commandService.execute(script, "pid", 4);
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4087147#4087147
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4087147
More information about the jboss-user
mailing list