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
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to