Thursday, June 13, 2013

Embedding Expressions with JEXL in Talend Open Studio


If your custom Java Talend Open Studio component needs to evaluate script expressions, consider embedding the lightweight Commons JEXL library.


The Commons JEXL library gives a Talend custom component the ability to evaluate script expressions.  This is used for functionality like that in tFilterRow where an expression is defined, filled with data from a Connector or Component View, and evaluated.  The returned value can then be used in the BEGIN or MAIN to control processing.

The expressions are script-like, similar to the popular Velocity or Unified EL syntaxes.  JEXL is much more consise than plain Java.  For example, it's not feasible to have a user enter this:

(input_row != null && input_row.get("field1") != null && input_row.get("field1").equals("Hello, World!")


But the user can enter this:

input_row == 'Hello, World!'


To use JEXL, build or find a commons-jexl-2.0.1.jar.  There is a dependency on Commons Logging, commons-logging-1.1.1.jar.

Initialize the Engine

Create an engine object. 

JexlEngine jexl = new JexlEngine();


Form an Expression

Write an expression referencing a variable that will be found in the JexlContext (to be created later).  The syntax that JEXL supports can be found here:http://commons.apache.org/jexl/reference/syntax.html

String filterExpr = "input_row.field1 == 'Hello, World!'";
Expression filter = jexl.createExpression( filterExpr );


'input_row' will be an object put on a JexlContext.  It will have a child object 'field1'.  The expression will check input_row.field1 for equality with a string constant ("Hello, World!").

Set up the Context

The JexlContext provides the values that will be substituted into the expression.

//
// define data that will pass the filter
//
JexlContext jc = new MapContext();
Map input_row = new HashMap();
input_row.put("field1", "Hello, World!");
jc.set("input_row", input_row);


Finally, make the evaluate() call. The output returns 'true'.

Object o = filter.evaluate(jc); 

System.out.println( "o=" + o );

This is an expression that evaluates to 'false'.  The put() statement is affecting the same Java objects as the previous call, so creating another context and Map isn't needed.

//
// define data that will not pass the filter
//
input_row.put("field1", "Goodbye");
o = filter.evaluate(jc);
System.out.println( "o=" + o );


JEXL is a lightweight library. Copy two JARs over to your component folder and add them to the XML descriptor's IMPORTS.  Add an evaluate() call to the processing logic in a MAIN for dynamic control

Follow this link for the JEXL source

Source: http://commons.apache.org/jexl/source-repository.html
Download: http://commons.apache.org/jexl/download_jexl.cgi

No comments: