I would like to create a list inside an activiti expression like in the following example:
<serviceTask activiti:class="com.example.workflow.servicetask.Foo" activiti:exclusive="true" id="foo" >
<extensionElements>
<activiti:field expression="${listf(host1, host2, host3)}" name="hosts"/>
</extensionElements>
</serviceTask>
This seems to be not supported by default, but JUEL (the unified expression language implementation used by Activiti) provides some methods for adding custom functions.
In the debugger I was able to come up with some code that could evaluate a list expression:
org.activiti.engine.impl.juel.SimpleContext c = new org.activiti.engine.impl.juel.SimpleContext();
c.setFunction("list", "of", Arrays.class.getMethod("asList", Object[].class));
Context.getProcessEngineConfiguration().getExpressionManager()
.expressionFactory
.createValueExpression(c, "${listf(host1, host2)}", Object.class)
.getValue(((ExecutionEntity) activityExecution).cachedElContext)
How can I configure Activiti to use custom functions like this?
Solved! Go to Solution.
Since then I managed to make this work by extending the ExpressionManager and overriding a few things. But this is a bit brittle, I afraid a API change will break this. Hopefully there is a better way to do this.
public class ExpressionManagerWithPredefinedFunctions extends ExpressionManager {
private final SimpleContext context = new SimpleContext();
public ExpressionManagerWithPredefinedFunctions() {
try {
context.setFunction("list", "of", Arrays.class.getMethod("asList",Object[].class));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@Override
public Expression createExpression(String expression) {
ValueExpression valueExpression = expressionFactory.createValueExpression(context, expression.trim(), Object.class);
return new JuelExpression(valueExpression, expression);
}
}
private ProcessEngine processEngine() {
return new StandaloneProcessEngineConfiguration()
.setExpressionManager(new ExpressionManagerWithPredefinedFunctions())
.setAsyncExecutorEnabled(true)
.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")
.setJdbcUsername("sa")
.setJdbcPassword("")
.setJdbcDriver("org.h2.Driver")
.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE)
.buildProcessEngine();
}
Since then I managed to make this work by extending the ExpressionManager and overriding a few things. But this is a bit brittle, I afraid a API change will break this. Hopefully there is a better way to do this.
public class ExpressionManagerWithPredefinedFunctions extends ExpressionManager {
private final SimpleContext context = new SimpleContext();
public ExpressionManagerWithPredefinedFunctions() {
try {
context.setFunction("list", "of", Arrays.class.getMethod("asList",Object[].class));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@Override
public Expression createExpression(String expression) {
ValueExpression valueExpression = expressionFactory.createValueExpression(context, expression.trim(), Object.class);
return new JuelExpression(valueExpression, expression);
}
}
private ProcessEngine processEngine() {
return new StandaloneProcessEngineConfiguration()
.setExpressionManager(new ExpressionManagerWithPredefinedFunctions())
.setAsyncExecutorEnabled(true)
.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")
.setJdbcUsername("sa")
.setJdbcPassword("")
.setJdbcDriver("org.h2.Driver")
.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE)
.buildProcessEngine();
}
Ask for and offer help to other Alfresco Process Services and Activiti Users and members of the Alfresco team.
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.