Giter VIP home page Giter VIP logo

expression-evaluator-demo's Introduction

Expression Evaluator (Demo)

Build Status

A general purpose java library which offers excel or Google spreadsheet like formula/ expression support. The library also allows easy addition of new functions.

The project contains examples\ tests to demonstrate what is already on offer and also give some examples to extend or add new functionality. The sequence of topics is as below:

  • Arithmetic Functions
  • String Functions
  • Date Functions
  • Format Functions
  • Condition/ Operator based Functions
  • User Defined Functions (Ability to customize or add new functions)
  • Performance Considerations

#####Arithmetic Functions

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("2+3*4-6/2");  
  assertEquals(BigDecimal.valueOf(11), evalExpr.eval());  
  //mathematical functions  
  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("tan(toRadians(45.0)) + sqrt(9.0)");  
  assertEquals(Double.valueOf(4), evalExpr.eval());  
  //variable driven functions  
  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("log10(var1)");  
  Map<String, Object> variables = new HashMap<String, Object>();  
  variables.put("var1", 100);  
  assertEquals(Double.valueOf(2), evalExpr.eval(variables));  

#####String Functions

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("LEFT('New York', 3)");
  assertEquals("New", evalExpr.eval());
  //variable driven String function
  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("LEFT(City, 3)");
  Map<String, Object> variables = new HashMap<String, Object>();
  variables.put("City", "New York");
  assertEquals("New", evalExpr.eval(variables));
  //composite String function
  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("CONCATENATE(LEFT('New York', 3), ' Hampshire')");
  assertEquals("New Hampshire", evalExpr.eval());

Some of the included functions are LEFT, RIGHT, CONCATENATE, LEN, TRIM, UPPER, LOWER, FIND, REPLACE and a few more. New functions can be added easily as explained later in the blog.

#####Date Functions

The library internally uses the joda-time library; however it exposes the date as java.util in order to ensure compatibility with standard jdk distribution.

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("DATE()");
  assertEquals(new Date().toString(), evalExpr.eval().toString());
  //date representation of a custom date
  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("ASDATE('20141229','yyyyMMdd')");
  Calendar calendar = Calendar.getInstance();
  calendar.set(2014, Calendar.DECEMBER, 29, 0, 0, 0);
  assertEquals(calendar.getTime().toString(), evalExpr.eval().toString());

The keyword DATESTR returns the string representation of a date while DATETIME returns the string representation of both the date as well as the time.

#####Format Functions for Date or Number

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("FORMAT(ASDATE('20141229','yyyyMMdd'),'MMM-dd-yyyy')");
  assertEquals("Dec-29-2014", evalExpr.eval());
  //number formatting
  assertEquals("9,876.54", ExpressionsFactory.create("FORMAT(9876.543, '#,##0.00')").eval());
  assertEquals("9877", ExpressionsFactory.create("FORMAT(9876.543, '#')").eval());
  assertEquals("54%", ExpressionsFactory.create("FORMAT(0.543, '0%')").eval());

#####Logical/ Conditional Operators (AND, OR, IF)

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("IF(AND(Score>0,Score<=40), 'Fail', IF(AND(Score>40, Score<=65), 'Grade II','Grade I'))");
  Map<String, Object> variables = new HashMap<String, Object>();
  variables.put("Score", 90);
  assertEquals("Grade I", evalExpr.eval(variables));
  variables.put("Score", 50);
  assertEquals("Grade II", evalExpr.eval(variables));

The above is a great example of how business logic can be made configuration driven rather than code driven; this makes it easier to just change the expressions and get the updated result rather than changing the code and going through the release-deploy cycle.

#####Customize (Add user defined functions)

A sample implementation for EXACT function in excel which compares the equality of two string can be done by creating a class CustomKeywords with the method below

    public static boolean EXACT(String str1, String str2) {
        return str1.equals(str2);
    }

and then an example would look like

  ExpressionsEvaluator evalExpr = new ExpressionsBuilder("EXACT(\"Hello\", inputStr)").withImports(Arrays.asList(new String[] { "static com.stst.core.expression.demo.CustomKeywords.*" })).build();
  Map<String, Object> variables = new HashMap<String, Object>();
  variables.put("inputStr", "Helo");
  assertEquals(false, evalExpr.eval(variables));
  variables.put("inputStr", "Hello");
  assertEquals(true, evalExpr.eval(variables));

#####Performance

The performance of the expression engine is comparable to the existing solutions like jexl, embedded javascript engine in jdk et-all. This is based on a benchmark that I had done previously but I would recommend running your own benchmarks and analyze the pros and cons. The following tricks should definitely be included for the performance analysis

  • Minimize new creation of GroovyShell (ExpressionsBuilder allows groovy shell re-use). In a multi-threaded environment use a thread local as groovy shell isn't thread safe.
  • Minimize creation of expression evaluator - as it has one time cost of running the parser. An expression once created can be cached and then run for different set of variables.

A new class is loaded for every new instance of expression - this leads to a slight increase in perm gen memory. This shouldn't be a concern in the majority of cases. However, even in cases where this is a concern the gc option to support class unloading should take care of it. Do reach out in case you need any help with this.

#####Conclusion

As you may have guessed all the functions can be used in conjunction so feel free to explore. All the tests mentioned in the examples above can be found in this maven project.

Do let me know your experience and any questions or feedback you may have.

expression-evaluator-demo's People

Contributors

shy-ta avatar

Watchers

James Cloos avatar zhifu.chang avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.