3 method to evaluate expressions in Java

August 7, 2011 by · Comments Off on 3 method to evaluate expressions in Java
Filed under: java 

The problem: You need to evaluate dynamic expression in your java code. Some common situation includes on a program contest evaluation system, on a dynamic business logic control,  on evaluation of dynamic math expression, or even on evaluation of test case.

There is many ways evaluate expression. These methods can be categorized into 3 different ways generally.

Method 1. Leverage dynamic compilation in Java.

You can add the dynamic expressions to codes of a skeleton class  template; and then compile the class.  It is the most original and flexible way to evaluate expressions. For full instructions see my last post:

3 steps to dynamically compile, instantiate and run a Java class.

Method 2. Evaluate expressions by java libraries.

There’s dozens of libraries to evaluate expression in java. The most intuitive and powerful library should be jexl and expressionoasis.

http://commons.apache.org/jexl/

http://code.google.com/p/expressionoasis/

When evaluating expressions, JEXL merges an Expression with a JexlContext. An Expression is created using JexlEngine#createExpression(), passing a String containing valid JEXL syntax. A simple JexlContext can be created by instantiating a MapContext; a map of variables that will be internally wrapped can be optionally provided through its constructor. The following example, takes a variable named foo, and invokes the bar() method on the property innerFoo:

// Create or retrieve a JexlEngine
JexlEngine jexl = new JexlEngine();
// Create an expression object
String jexlExp = "foo.innerFoo.bar()";
Expression e = jexl.createExpression( jexlExp );

// Create a context and add data
JexlContext jctx = new MapContext();
jctx.set("foo", new Foo() );

// Now evaluate the expression, getting the result
Object o = e.evaluate(jctx);

Method 3. Evaluate expression by scripting engine

You can evaluate expression in your java code by scripting engine supported by Java platform. You are free to script the expressions in your favorite language.  To show all available scripting engines in your system:

    private static void availableEngine()
    {
        ScriptEngineManager mgr = new ScriptEngineManager();
        List<ScriptEngineFactory> factories = mgr.getEngineFactories();
        for (ScriptEngineFactory factory : factories)
        {
            System.out.println("ScriptEngineFactory Info");
            String engName = factory.getEngineName();
            String engVersion = factory.getEngineVersion();
            String langName = factory.getLanguageName();
            String langVersion = factory.getLanguageVersion();
            System.out.printf("\tScript Engine: %s (%s)\n", engName, engVersion);
            List<String> engNames = factory.getNames();
            for (String name : engNames)
            {
                System.out.printf("\tEngine Alias: %s\n", name);
            }
            System.out.printf("\tLanguage: %s (%s)\n", langName, langVersion);
        }
    }

By default, JavaScript engine is included in JVM. So you can write expression in javascript with java variable support, and evaluate it in java code. Example code:

    private static void jsEvalWithVariable()
    {
        List<String> namesList = new ArrayList<String>();
        namesList.add("Jill");
        namesList.add("Bob");
        namesList.add("Laureen");
        namesList.add("Ed");

        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");

        jsEngine.put("namesListKey", namesList);
        System.out.println("Executing in script environment...");
        try
        {
          jsEngine.eval("var x;" +
                        "var names = namesListKey.toArray();" +
                        "for(x in names) {" +
                        "  println(names[x]);" +
                        "}" +
                        "namesListKey.add(\"Dana\");");
        }
        catch (ScriptException ex)
        {
            ex.printStackTrace();
        }
    }

You can also script in groovy, ruby, python… Groovy can be well integrated with jvm, let’s take groovy as an example.  Firstly include groovy 1.7.10 in pom file if you’re using maven ( or include groovy engine jar groovy-engine.jar in the classpath of the project if not using maven).

  <dependency>
  	<groupId>org.codehaus.groovy</groupId>
  	<artifactId>groovy</artifactId>
  	<version>1.7.10</version>
  </dependency>

Secondly write scripts in groovy, and finally evaluate them by ScriptEngine.

It is a common practice to access java variables and objects in you expressions only if you binds the variables/objects to your script engine object. You can evaluate expression in your groovy engine like this:

    private static class Position
    {
        private int x;
        private int y;
        public Position(int x, int y)
        {
            super();
            this.x = x;
            this.y = y;
        }

    }

    //require(jar:'groovy-engine.jar')
    // or include any version of groovy 1.7.10 or above in your pom file
    private static void groovyEval()
    {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");

        if(null==engine)
        {
            System.err.println("Could not find groovy script engine,make sure to include groovy engine in your classpath");
        }
        try
        {
            // basic groovy expression example
            System.out.println(engine.eval("(1..10).sum()"));

            // example showing scripting with variables (object method invoking)
            engine.put("first", "HELLO");
            engine.put("second", "world");
            System.out.println(engine.eval("first.toLowerCase() + second.toUpperCase()"));

            //example with boolean expression
            engine.put("m", 3);
            engine.put("n", 9);
            System.out.println(engine.eval("m<n"));

            //example with variable object and object member access:
            Position pos = new Position(100, 200);
            engine.put("p", pos);
            System.out.println(engine.eval("p.y-p.x>0"));
        }
        catch (ScriptException e)
        {
            e.printStackTrace();
        }
    }

Finally, if you just want to evaluate and debug complicated math expression, Math Expression Evaluator may help:

http://www.beyondlinux.com/blog/handy-utilities/math-expression-calculator/

 

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Json and flexjson on exchanging abstract object data

August 7, 2011 by · 1 Comment
Filed under: java 

JSON is a lightweight text-based open standard designed for human-readable data interchange.  It is widely used in java applications as a replacement of XML. Many times we need to convert java object to json text and vice versa.

You can use Gson to convert java object to JSON format, and convert JSON into java object. And you can export your interface by JSON RPC using jsonrpc4j or json-rpc.

public class Employee
{
    private String name;
    private int salary;
    private String dateOfBirth;

    public static void main(String[] args)
    {
        Employee emp = new Employee();
        emp.setName("david");
        emp.setDateOfBirth("20080801");

        Gson gson = new Gson();
        String jsonString = gson.toJson(emp, Employee.class);
        System.out.println(jsonString);
    }
}

The output would be:

{“name”:”david”,”salary”:0,”dateOfBirth”:”20080801″}

Now you can deserialize the jsonString to an Employee object.

   Employee employee = gson.fromJson(jsonString, Employee.class);
   System.out.println(employee.getName());

The problem with Gson is that it loses the type information on serialization, and you need to provide type information explicitly on deserialization like the above example.

How to serialize and deserialize with automatic type recognization?

Flex Json is the answer. FlexJson would add a “class” attribute in the serialized json string to represent the full qualified class name. Thus you can exchange interface/abstract object by json format. Here’s an example.

        JSONSerializer serializer = new JSONSerializer();
        String empString = serializer.serialize(emp);
        System.out.println(empString);

        JSONDeserializer<Object> deserializer = new JSONDeserializer<Object>();

        Employee eee = (Employee) deserializer.deserialize(empString);
        //System.out.println(eee);

The output would be like this:

{“class“:”com.beyondlinux.demo.bean.Employee”,”dateOfBirth”:”20080801″,”name”:”david”,”salary”:0}

Reference List:

http://en.wikipedia.org/wiki/JSON-RPC

http://code.google.com/p/jsonrpc4j/

http://code.google.com/p/json-rpc/

http://flexjson.sourceforge.net/

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Noticeable Hacker News I Read(2011/07)

August 1, 2011 by · Comments Off on Noticeable Hacker News I Read(2011/07)
Filed under: tech watch 

Post for Startup:
How to use A/B testing for better product design

Hackers to follow on Google+

Which domain registrar is best?

Why you should’nt keep your startup idea secret

How has your profession affected your non-professional thinking?

Post for Tech:

Google Running About 900,000 Servers (datacenterknowledge.com)

Stop A/B Testing and Make Out like a Bandit (untyped.com)

Why We Prefer Founding CEOs (bhorowitz.com)

Early Unix history and evolution (mit.edu)

LevelDB: A Fast Persistent Key-Value Store

Better Understanding Link-based Spam Analysis Techniques (seomoz.org)

Understanding the Git Workflow (sandofsky.com)

So you want to write a fast Python? (alexgaynor.net)

Awesome Python and django related projects (elweb.co)

Twitter Shifting More Code to JVM, Citing Performance and Encapsulation As Primary Drivers

Setting Up SSL on Tomcat in 5 minutes

Introduction to Algorithms

All About Time

JavaScript language advanced Tips & Tricks

Finagle is a library for building asynchronous RPC servers and clients in Java, Scala, or any JVM language.

Protocol buffer socket rpc in python/java

Akka and the java memory model

Things Everyone Should Do: Code Review (scientopia.org)

Why I read Hacker News even though I understand very little of it (alexrosen.com)

Realtime image processing in Python

http://prizes.org/
Why Every Maker Should Learn Chinese

Learn core python in one week (my way)

Find is a beautiful tool

 

On Education and Life: 

Harvard and Class

How to raise a global kid?

11 Unusual Methods for Being a Great Public Speaker (jamesaltucher.com)

 

 

 

 

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)