+1 looks good to me. Thanks, Tim
On Thu, Jan 14, 2016 at 10:06 AM, Chinmay Kolhatkar <[email protected] > wrote: > Considering Tim's suggestiom, I'm thinking about modifying the interface in > following way: > > So there will be 3 interfaces: > > public interface Expression<O> > { > O execute(Object... obj); > } > > public interface ExpressionEvaluator > { > <O> ExpressionEvaluator.Expression<O> createExecutableFunction(String > expression, Class<?> returnType); > > <O> ExpressionEvaluator.Expression<O> createExecutableExpression(String > expression, Class<?> returnType); > > void setExpressionParser(ExpressionParser parser); > } > > public interface ExpressionParser > { > String convertToCompilableExpression(String expression, Class<?> > returnType, boolean containsReturnStatement); > } > > Description of interfaces: > 1. Expression interface is the final output which will have executable code > of expression. > 2. ExpressionEvaluator interface will be implemented for specific type if > implementation. For eg. In this case the concrete implementation will be > JavaExpressionEvaluator which will evaluate quasi-Java expression > 3. ExpressionParser interface will defined how expression need to be parsed > and can be plugin to ExpressionEvaluator interface via setExpressionParser > method. > > This way, > 1. One can override parsing logic for specific evaluator. > 2. Override the expression evaluation logic all together. > 3. Sticking to a common interface of ExpressionEvaluator & Expression will > make the user code not to change even if parser or evaluator changes. > > Thoughts? > > Thanks, > Chinmay. > > On Thu, Jan 14, 2016 at 2:17 PM, Chinmay Kolhatkar < > [email protected]> > wrote: > > > I think think is doable. > > I'll take a look. > > > > Thanks, > > Chinmay. > > > > On Thu, Jan 14, 2016 at 1:59 PM, Timothy Farkas <[email protected]> > > wrote: > > > >> Haven't gone though you're PR, so I'm not sure how this would fit in. > But > >> I > >> think introducing an interface like below, and allowing it to be set may > >> be > >> sufficient. > >> > >> public interface ExpressionParser > >> { > >> public String convertToJavaExpression(String expression); > >> } > >> > >> Thanks, > >> Tim > >> > >> On Thu, Jan 14, 2016 at 12:19 AM, Chinmay Kolhatkar < > >> [email protected] > >> > wrote: > >> > >> > Ah got it. That's a good point. Maybe its good to separate the parsing > >> and > >> > compilation part of the evaluation. > >> > And let one override the parsing logic. > >> > > >> > I'll see how to incorporate that, but if you have idea about achieving > >> it, > >> > please share it. > >> > > >> > Thanks, > >> > Chinmay. > >> > > >> > > >> > On Thu, Jan 14, 2016 at 1:43 PM, Timothy Farkas <[email protected]> > >> > wrote: > >> > > >> > > Hey Chinmay, > >> > > > >> > > It is possible the user may want to define a syntax radically > >> different > >> > > from Java style syntax. I've proposed a syntax similar to yours to > >> one of > >> > > our users for expression evaluation but they didn't like it because > >> the > >> > > syntax needs to be something easily validated by a UI. It may be > >> possible > >> > > that the user wants expressions to be sent to an operator as json, > >> > because > >> > > that is easy to parse and validate in javascript: > >> > > > >> > > {"param":"myField1","operation":">","threshold":"1"} > >> > > > >> > > If the syntax is pluggable then an implementation of this syntax > >> could be > >> > > swapped with with an implementation of the syntax you've already > >> provided > >> > > without changing operator code. > >> > > > >> > > Thanks, > >> > > Tim > >> > > > >> > > On Wed, Jan 13, 2016 at 11:34 PM, Chinmay Kolhatkar < > >> > > [email protected] > >> > > > wrote: > >> > > > >> > > > Hi tim, > >> > > > > >> > > > I agree with you. The expression here we're talking about is > really > >> a > >> > > > quasi-Java expression. One can do anything which java does. > >> > > > Only change with java syntax here is how variables are accessed. > >> > > > > >> > > > They're by default accessed as ${...}. > >> > > > > >> > > > But this is also made configurable via a setter property on > >> > > > ExpressionEvaluator. The pull request has it. > >> > > > > >> > > > If this is what you're talking about then this is taken care of. > >> > > > > >> > > > Thanks, > >> > > > Chinmay. > >> > > > > >> > > > > >> > > > On Thu, Jan 14, 2016 at 1:00 PM, Timothy Farkas < > >> [email protected]> > >> > > > wrote: > >> > > > > >> > > > > Hi Chinmay, > >> > > > > > >> > > > > I think this is a very good first implementation. My only > concern > >> is > >> > > that > >> > > > > people will get caught up in the details of the syntax for this > >> > > > expression > >> > > > > language. I think a way to avoid that is to make the syntax > >> > pluggable. > >> > > > For > >> > > > > example is there an interface for expression evaluation which > can > >> be > >> > > > > implemented by different syntaxes? This would allow operators > >> which > >> > use > >> > > > > expression evaluation to have the syntax configured via a > >> property. > >> > > That > >> > > > > way if someone discovers a limitation in the syntax down the > >> line, a > >> > > new > >> > > > > syntax can be introduced without breaking backwards > compatibility > >> and > >> > > > > without requiring operator code to be changed. > >> > > > > > >> > > > > Thanks, > >> > > > > Tim > >> > > > > > >> > > > > On Wed, Jan 13, 2016 at 10:52 PM, Chinmay Kolhatkar < > >> > > > > [email protected] > >> > > > > > wrote: > >> > > > > > >> > > > > > Hi All, > >> > > > > > > >> > > > > > I'm working on APEXCORE-1972 which adds support for a > quasi-Java > >> > > > > Expression > >> > > > > > Language and its expression evaluator. > >> > > > > > > >> > > > > > All the detailed functionality and design details along with > >> > examples > >> > > > are > >> > > > > > present in Jira. > >> > > > > > > >> > > > > > I've summarized the ExpressionEvaluator feature & Expression > >> > language > >> > > > > > below. > >> > > > > > > >> > > > > > The pull request created for this at here: > >> > > > > > https://github.com/apache/incubator-apex-malhar/pull/170 > >> > > > > > > >> > > > > > Please share your thought on this. > >> > > > > > > >> > > > > > Thanks, > >> > > > > > Chinmay. > >> > > > > > > >> > > > > > > >> > > > > > *Summary of functionality of ExpressionEvaluator:* > >> > > > > > > >> > > > > > 1. Support quasi-Java Expression which defines a single > line > >> > > > > executable > >> > > > > > expression > >> > > > > > 2. Support for quasi-Java expression based function code, > >> which > >> > > will > >> > > > > be > >> > > > > > compiled on the fly and made available for execution. > >> > > > > > 3. Should support accessing multiple fields from multiples > >> input > >> > > > POJOs > >> > > > > > while addressing the conversion of private variables to > >> public > >> > > > getter > >> > > > > > method for all levels. > >> > > > > > 4. Should support nested field support > >> > > > > > 5. quasi-Java expressions should support operands to be > >> > mentioned > >> > > in > >> > > > > > following ways: > >> > > > > > - ${input.fieldName} > >> > > > > > - Access fieldName via a object name. > >> > > > > > - ${fieldName} > >> > > > > > - Accessing fieldName directly when a single object > is > >> > > > > registered > >> > > > > > for operation. > >> > > > > > - ${input} > >> > > > > > - Accessing object variable directly > >> > > > > > - ${input.fieldName.internalField} > >> > > > > > - Accessing nested fields > >> > > > > > 6. There should be some predefined function provided to > >> > > > expression > >> > > > > > writer which one can directly use in expression for > invoking > >> > > certain > >> > > > > > functionality. > >> > > > > > 7. These are simple String based, Date time based etc > >> functions. > >> > > > > > 8. On-need-basic one should be able to easily update > >> Expression > >> > > > > > Evaluator to easily add new predefined functions to be made > >> > > > available > >> > > > > > for > >> > > > > > expression writer. > >> > > > > > 9. User of ExpressionEvaluator should be able to add a > custom > >> > > method > >> > > > > > externally to be made available to in expression. > >> > > > > > 10. Though operands are defined, placeholder for the > operand > >> in > >> > > > > > expression should be allowed to be overridden. By default, > >> > > > expression > >> > > > > > language should support bash type syntax for operand - {…} > >> > > > > > 11. The library should not introduce any serialization > >> related > >> > > > issues. > >> > > > > > 12. All the java operators should be supported. > >> > > > > > > >> > > > > > > >> > > > > > > >> > > > > > *The examples of quasi-Java Expression:* > >> > > > > > > >> > > > > > - ${inp.field1} > >> > > > > > - Will return value of field1 from registered input > POJO. > >> > > > > > - ${inp.field1} + ${inp.field2} > >> > > > > > - Will return sum of field1 & field2 from given POJO > >> > > > > > - ${field1} + ${field2} > >> > > > > > - Equivalent to above > >> > > > > > - ${inpA.field1} > ${inpA.field2} ? ${inpA.field3} : > >> > > ${inpB.field3} > >> > > > > > - Executes ternary expression and returns value > >> accordingly. > >> > > > Works > >> > > > > on > >> > > > > > 2 POJOs. inpA & inpB are two placeholder registered for > >> given > >> > > > POJO > >> > > > > > with > >> > > > > > ExpressionEvaluator library. > >> > > > > > - pow(${inpA.field1}, ${inpB.field2}) > >> > > > > > - Executes pow function coming from java.lang.Math > >> library. > >> > > This > >> > > > > and > >> > > > > > other with lot other basic functions is available to > >> > expression > >> > > > > > writer out > >> > > > > > of the box to use in expression. > >> > > > > > - ${inpA.field1} > 0 ? ${inpB.innerPOJO.field3} : > >> > > > > > ${inpA.innerPOJO.field3} > >> > > > > > - Shows how nested POJOs can be accessed in expression. > >> The > >> > > > > variables > >> > > > > > will evaluate to correct public getter method is > required. > >> > > > > > - ${inp.firstname} + “ “ + ${inp.lastname} > >> > > > > > - Generate the full name as per given expression from > >> > firstname > >> > > > and > >> > > > > > lastname field. > >> > > > > > - long retVal=1; for (int i=0; ${inpF.value1}; i++) > {retVal = > >> > > > retVal * > >> > > > > > ${inpF.value1}; } return retVal; > >> > > > > > - This tells a complete method content to > >> > ExpressionEvaluator. > >> > > > The > >> > > > > > library create an executable and compiled method using > >> this > >> > > > > > expression. > >> > > > > > > >> > > > > > > >> > > > > > > >> > > > > > >> > > > > >> > > > >> > > >> > > > > >
