8 Replies Latest reply on Jun 16, 2010 5:53 AM by swiderski.maciej

    Adding some function in EL ?

    newbeewan

      Hi,

       

      As jbpm 4.3 is using juel to solve it's EL, I will be interested to add some function in the context.

       

      Basically to access some i18n resources in mail activity to send some messages according to locale.

       

      How can I add some functions into EL context ?

       

      Regards

        • 1. Re: Adding some function in EL ?
          rebody

          Hi Jaber,

           

          At this time, I really don't know how to register custom functionMapper for juel.  In jBPM 4.4 trunk, there is a org.jbpm.pvm.internal.el package for the expression operations.  Maybe you could achieve a custom FunctionMapper and register it to the JbpmElFactory.

           

          I think opening a new issue for this feature would be a good idea.  Could you do it?

          • 2. Re: Adding some function in EL ?
            newbeewan

            I create a new feature request (https://jira.jboss.org/browse/JBPM-2887).

             

            In the juel config :

            <script-manager default-expression-language="juel"
                               default-script-language="juel"
                               read-contexts="execution, environment, process-engine, spring"
                               write-context="">
                  <script-language name="juel"
                                   factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
               </script-manager>

             

            What are the definitions of read-contexts ans write-contexts ?

             

            maybe there is something to do with that, but I can't find any documentation about customising script context !

             

            Regards

            • 3. Re: Adding some function in EL ?
              mwohlf

              it's deprecated, see:

              http://community.jboss.org/thread/152316

               

              I ended up extending the ScriptManager to have a writeable context at least:

               

              package net.aux.jbpm4;
              
              import java.util.HashMap;
              import javax.script.Bindings;
              import javax.script.ScriptContext;
              import javax.script.ScriptEngine;
              import javax.script.ScriptEngineManager;
              import javax.script.ScriptException;
              
              import org.jboss.seam.contexts.Contexts;
              import org.jbpm.api.JbpmException;
              import org.jbpm.pvm.internal.script.EnvironmentBindings;
              import org.jbpm.pvm.internal.script.ScriptManager;
              
              
              public class CustomScriptManager extends ScriptManager {
              
                  protected class CustomEnvironmentBindings extends EnvironmentBindings {
                      private HashMap<String, Object> map = new HashMap<String, Object>();
              
                      public CustomEnvironmentBindings() {
                          super(null, null);
                      }
              
                      @Override
                      public Object put(String key, Object value) {
                        return map.put(key, value);
                      }
              
                      @Override
                      public Object get(Object key) {
                          Object result = super.get(key);
                          if (result == null) {
                              result = map.get(key);
                          }
                          return result;
                      }
                  }
              
                  /**
                   * <script-language name="juel" factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
                   * <script-language name="bsh" factory="org.jbpm.pvm.internal.script.BshScriptEngineFactory" />
                   * <script-language name="groovy" factory="org.jbpm.pvm.internal.script.GroovyScriptEngineFactory" />
                   */
                  public CustomScriptManager() {
                      scriptEngineManager = new ScriptEngineManager();
                      scriptEngineManager.registerEngineName("juel", new org.jbpm.pvm.internal.script.JuelScriptEngineFactory());
                      scriptEngineManager.registerEngineName("bsh", new org.jbpm.pvm.internal.script.BshScriptEngineFactory());
                      scriptEngineManager.registerEngineName("groovy", new org.jbpm.pvm.internal.script.GroovyScriptEngineFactory());
                  }
              
                  @Override
                  protected Object evaluate(ScriptEngine scriptEngine, String script) {
                      Bindings bindings = new CustomEnvironmentBindings();
              
                      // add any custom bindings here:
                      bindings.put("pi", "3.14");
                      bindings.put("authenticatedUser", Contexts.getSessionContext().get("authenticatedUser"));
                      scriptEngine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
              
                      try {
                          Object result = scriptEngine.eval(script);
                          return result;
                      } catch (ScriptException e) {
                          throw new JbpmException("script evaluation error: " + e.getMessage(), e);
                      }
                  }
              
              }
              

               

              instead of <script-manager /> in jbpm.cfg.xml:

               

                   <!--  custom script manager implementation -->
                   <object class='net.aux.jbpm4.CustomScriptManager'>
                     <field name='defaultExpressionLanguage'><string value='juel' /></field>
                     <field name='defaultScriptLanguage'><string value='juel' /></field>
                   </object>
              
              • 4. Re: Adding some function in EL ?
                rebody

                Hi Jaber,

                 

                If you want to implement your own function,  please refer org.jbpm.pvm.internal.el.JstlFunction.  And I think Micheal's codes is very helpful.

                 

                BWT, I think custom el function feature is very cool.  But there were lots of works on EL which Tom have not completed yet,  I am afraid we may not finish them on jbpm 4.4.  Maybe on the next release we could make a good plan to finish these unresovled issues.

                 

                Thank you very much.

                • 5. Re: Adding some function in EL ?
                  rebody

                  And if you only want to use i18n in EL.  I could export ResourceBundleELResolver in JbpmElFactoryImpl.  What do you think about this?

                  • 6. Re: Adding some function in EL ?
                    newbeewan

                    It may be a good idea !

                     

                    Adding a parameter in configuration to define resources bundle...

                     

                    Regards

                    • 7. Re: Adding some function in EL ?
                      rebody

                      Hi Jaber,

                       

                      I opened an issue for this feature.

                       

                      https://jira.jboss.org/browse/JBPM-2892

                       

                      At this moment,  if we want to use i18n in EL.  we have to create ResourceBundle instance and set it as a process instance.

                      • 8. Re: Adding some function in EL ?
                        swiderski.maciej

                        Simple way of providing your own functions to be evaluated by jBPM could be to enclose such functions in a class that will be set as process variable.

                        Not perfect but should do it...