简体   繁体   中英

JEXL: How to customize property accessors

I've got data objects, which you could think of as a "simplified map". There are methods get(String) , and put(String,Object) , but that's basically it.

Now, I'd like to use JEXL to evaluate complex expressions on my data objects. I can do so by creating a custom JexlContext, and that works for expressions like "foo" , or foo != null . However, as soon as I attempt to use an expression like "foo.bar" , Jexl fails with an error message "unsolvable property". Obviously, Jexl uses my custom JexlContext to evaluate "foo" , but can't evaluate "bar" on the foo object. My impression is, that I've got to use a custom PropertyResolver. I can implement that, but I can't figure out. how to bring that into the game, as the JexlUberspect doesn't contain a method like setResolvers , or addResolver .

Similar to the duplicate question, I guess you can do:

public class ExtendedJexlArithmetic extends JexlArithmetic
{
    public Object propertyGet(YourCustomClass left, YourCustomClass right)
    {
       // ...
    }
}

JexlEngine jexlEngine=new JexlBuilder().arithmetic(new ExtendedJexlArithmetic (true)).create();
// or
JexlEngine jexl = new JexlEngine(null, new ExtendedJexlArithmetic(), null, null);

From the documentation at: https://commons.apache.org/proper/commons-jexl/apidocs/org/apache/commons/jexl3/package-summary.html

You can also add methods to overload property getters and setters operators behaviors. Public methods of the JexlArithmetic instance named propertyGet/propertySet/arrayGet/arraySet are potential overrides that will be called when appropriate. The following table is an overview of the relation between a syntactic form and the method to call where V is the property value class, O the object class and P the property identifier class (usually String or Integer).

 Expression Method Template foo.property public V propertyGet(O obj, P property); foo.property = value public V propertySet(O obj, P property, V value); foo[property] public V arrayGet(O obj, P property, V value); foo[property] = value public V arraySet(O obj, P property, V value);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM