12 Replies Latest reply on Oct 27, 2008 3:53 AM by Tom Baeyens

    Expression Evaluation in ActionHandler Properties

    Bernd Ruecker Master

      Hi!

      Another requirement I am facing quite often is, that the parameters for an ActionHandler should be able to use Expressions in it.

      So you could write

      <action class="...">
       <x>#{someObject.x}</x>
      </action>
      


      This could be done in the FieldInstatiator class (around line 67 we are right "setPropertyValue(Class clazz, Object newInstance, String propertyName, Element propertyElement)"), but there I don't have the jbpmContext available...

      What do you guys think? Skip it and tell the people they should do the evaluation themselves in the ActionHandler (basically that is my recommendation at the moment)?

      Or support it out the box? Ideas how to implement it then?

      Cheers
      Bernd

        • 1. Re: Expression Evaluation in ActionHandler Properties
          Ronald van Kuijk Master

           


          What do you guys think? Skip it and tell the people they should do the evaluation themselves in the ActionHandler (basically that is my recommendation at the moment)?


          Currently I'd go for this option if by 'telling'
          you mean a nice example in the docs.

          Supporting it out of the box is (I think) the 'seam' way. So in 4 I'd go for it.... I have no idea how to implement it since I do not know that part of jBPM core code

          • 3. Re: Expression Evaluation in ActionHandler Properties
            Tom Baeyens Master

            great. there it will get looked at for jpdl 4.

            i'll be switching from this wiki page to a real xsd + xsddocs for jPDL 4 as the next step in the coming weeks.

            • 4. Re: Expression Evaluation in ActionHandler Properties
              Alejandro Guizar Master

              I find this feature quite useful. It makes data extraction and manipulation very transparent.

              Perhaps we could add it as early as jPDL 3.3? The challenge would be to pass the ExecutionContext all the way down to Instantiator.instantiate(). This requires changing the signature of a number of methods, but other than that, the coding seems straightforward.

              • 5. Re: Expression Evaluation in ActionHandler Properties
                Thomas Diesler Master

                All BPM functionality will eventually have to go through the public API.

                If this is needed please add it to

                http://jira.jboss.com/jira/browse/JBPM-1250

                with a reference to this forum thread.

                • 6. Re: Expression Evaluation in ActionHandler Properties
                  Edward Staub Expert

                  Something like this is really important for building reusable ActionHandlers that aren't tied to a particular process definition.

                  The workaround that I've used is to write the ActionHandler so that it expects a variable name as a parameter. The ActionHandler then gets the value of the variable at run-time. This works pretty good, except that you end up with more process variables.

                  -Ed Staub

                  • 7. Re: Expression Evaluation in ActionHandler Properties
                    Bernd Ruecker Master

                     

                    Perhaps we could add it as early as jPDL 3.3? The challenge would be to pass the ExecutionContext all the way down to Instantiator.instantiate(). This requires changing the signature of a number of methods, but other than that, the coding seems straightforward.


                    Yeah, I would agree. But it invloves really some changes in the internals...

                    All BPM functionality will eventually have to go through the public API.

                    I don't get the connection to th epublic API, can you please explain a bit further?

                    Thanks and regards
                    Bernd

                    • 9. Re: Expression Evaluation in ActionHandler Properties
                      brittm Novice

                      (I've posted this against the JIRA issue, but I'm also posting it here for any who might be searching/following the thread.)

                      I have a fear that automatic expression evaluation for ActionHandler configuration could interfere with the ability to solve some interesting problems. I'll provide an example below.

                      A recommendation:

                      Rather than hard coding the expression handling logic, provide an example of a base class that users can extend if they want to take advantage of expression handling/syntax in any of their Handlers. With a base class, users can take advantage of expression handling when they want to, customize it if they need to, or intentionally ignore it. Below is a class that I use consistently--if you like it, just re-brand it, re-write it or whatever you like.

                      As an example of customizing the handling of expressions, this particular class provides a specialized 'concatenateEL' method--for instance, if you want to assign swimlanes to a particular Sales queue based on Market, in your AssignmentHandler configuration you could write

                      <group>Sales-#{market}</group>
                      which would evaluate to something like "Sales-London". The stock JbpmExpressionEvaluator doesn't provide for this type of evaluation (and I really don't know if it should.)

                      No, this is not completely automatic for the user, they have to call one of the methods from their Handler, but it does allow them much more flexibility.
                      /*
                       * GenericHandler.java
                       * Created on April 1, 2008, 7:06 PM
                       * Copyright 2008, Britt Miner.
                       */
                      package org.bminer.jbpm.pd;
                      
                      import java.util.regex.*;
                      import org.jbpm.graph.exe.ExecutionContext;
                      import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
                      
                      /**
                       * @author bminer
                       */
                      public abstract class GenericHandler {
                      
                       // Prepare to identify any EL expressions, #{...}, regex: "#\{.*?}"
                       String elPatternStr = "#\\{.*?}";
                       Pattern elPattern = Pattern.compile(elPatternStr);
                      
                       protected String conditionExpression = null;
                      
                       /* Evaluate the input as a possible EL expression. */
                       protected Object evaluateEL(String inputStr, ExecutionContext ec) {
                       if (inputStr == null) {
                       return null;
                       }
                      
                       Matcher matcher = elPattern.matcher(inputStr);
                       if (matcher.matches()) { //input is one big EL expression
                       return JbpmExpressionEvaluator.evaluate(inputStr, ec);
                       } else {
                       return inputStr;
                       }
                       }
                      
                       /* Treats input as a possible series of EL expressions and concatenates what
                       * is found.
                       */
                       protected String concatenateEL(String inputStr, ExecutionContext ec) {
                       if (inputStr == null) {
                       return null;
                       }
                      
                       Matcher matcher = elPattern.matcher(inputStr);
                       StringBuffer buf = new StringBuffer();
                       while (matcher.find()) {
                       // Get the match result
                       String elExpr = matcher.group();
                       // Evaluate EL expression
                       Object o = JbpmExpressionEvaluator.evaluate(elExpr, ec);
                       String elValue = "";
                       if (o != null) {
                       elValue = String.valueOf(JbpmExpressionEvaluator.evaluate(elExpr, ec));
                       }
                       // Insert the calculated value in place of the EL expression
                       matcher.appendReplacement(buf, elValue);
                       }
                       matcher.appendTail(buf);
                      
                       // Deliver result
                       if (buf.length() > 0) {
                       return buf.toString();
                       } else {
                       return null;
                       }
                       }
                      
                       /* Returns true if the value is a String which contains the pattern delineating
                       * an EL expression.
                       */
                       protected boolean hasEL(Object value) {
                       if (value instanceof String) {
                       Matcher matcher = elPattern.matcher((String) value);
                       return matcher.find();
                       }
                       return false;
                       }
                      
                       /* Returns true if the value is a String which in its entirety composes
                       * one EL expression.
                       */
                       protected boolean isEL(Object value) {
                       if (value instanceof String) {
                       Matcher matcher = elPattern.matcher((String) value);
                       return matcher.matches();
                       }
                       return false;
                       }
                      
                       public void setConditionExpression(String condition) {
                       this.conditionExpression = condition;
                       }
                      
                       public void setCondition(String condition) {
                       this.conditionExpression = condition;
                       }
                      }


                      • 10. Re: Expression Evaluation in ActionHandler Properties
                        Alejandro Guizar Master

                        From a SF developer's perspective, something like Sales-#{market} should evaluate to something like "Sales-London". If the JbpmExpressionEvaluator does not do it, then it probably should. This change could go in jBPM 3.3.0, tough we'd have to discuss the consequences.

                        • 11. Re: Expression Evaluation in ActionHandler Properties
                          Ronald van Kuijk Master

                          I think it is even more widely an interesting subject. Currently only part of the attributes are accept EL, not all of them. This confuses people from time to time. I'll add this to the meeting context

                          • 12. Re: Expression Evaluation in ActionHandler Properties
                            Tom Baeyens Master

                            i also think that we should address improvements of el usage in jpdl 4 only