Example: using JavaScript in Java

| 2 Comments | 1 TrackBack

Java 6.0 ("Mustang") includes a JavaScript interpreter and a javax.script package for interacting with it. The code below is an example of how it works...

import javax.script.*;
import java.util.*;
import java.io.*;

/**
 * This class is like java.util.Properties, but allows property values to
 * be determined by evaluating JavaScript expressions.
 */
public class ScriptedDefaults {
    // Here is where we store name/value pairs of defaults
    Map<String,Object> defaults = new HashMap<String,Object>();

    // Accessors for getting and setting values in the map
    public Object get(String key) { return defaults.get(key); }
    public void put(String key, Object value) { defaults.put(key, value); }

    // Initialize the contents of the Map from a file of name:value pairs.
    // If a value is enclosed in curly braces, evaluate it as javscript.
    public void load(String filename) throws IOException, ScriptException {
        // Get a JavaScript interpreter
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByExtension("js");

        // Use our own name/value pairs as JavaScript variables
        Bindings bindings = new SimpleBindings(defaults);

        // Create a context for evaluating scripts in 
        ScriptContext context = new SimpleScriptContext();

        // Set those Bindings in the Context so that they are readable
        // by the scripts, but that variables defined by the scripts do
        // not get placed into our Map object.
        context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);

        BufferedReader in = new BufferedReader(new FileReader(filename));
        String line;
        while((line = in.readLine()) != null) {
            line = line.trim();  // strip leading and trailing space
            if (line.length() == 0) continue;    // skip blank lines
            if (line.charAt(0) == '#') continue; // skip comments
            
            int pos = line.indexOf(":");
            if (pos == -1)
                throw new IllegalArgumentException("syntax: " + line);
            
            String name = line.substring(0, pos).trim();
            String value = line.substring(pos+1).trim();
            char firstchar = value.charAt(0);
            int len = value.length();
            char lastchar = value.charAt(len-1);

            if (firstchar == '"' && lastchar == '"') {
                // Double-quoted quoted values are strings
                defaults.put(name, value.substring(1, len-1));
            }
            else if (Character.isDigit(firstchar)) {
                // If it begins with a number try to parse a number
                try {
                    double d = Double.parseDouble(value);
                    defaults.put(name, d);
                }
                catch(NumberFormatException e) {
                    // Oops.  Not a number.  Store as a string
                    defaults.put(name, value); 
                }
            }
            else if (value.equals("true"))         // handle boolean values
                defaults.put(name, Boolean.TRUE);
            else if (value.equals("false"))
                defaults.put(name, Boolean.FALSE);
            else if (value.equals("null"))
                defaults.put(name, null);
            else if (firstchar == '{' && lastchar == '}') {
                // If the value is in curly braces, evaluate as JavaScript code
                String script = value.substring(1, len-1);
                Object result = engine.eval(script, context);
                defaults.put(name, result);
            }
            else {
                // In the default case, just store the value as a string
                defaults.put(name, value);
            }
        }
    }

    public static void main(String[] args)
        throws IOException, ScriptException
    {
        ScriptedDefaults defaults = new ScriptedDefaults();
        defaults.load(args[0]);
        Set<Map.Entry<String,Object>> entryset = defaults.defaults.entrySet();
        for(Map.Entry<String,Object> entry : entryset) {
            System.out.printf("%s: %s%n", entry.getKey(), entry.getValue());
        }
    }
}

1 TrackBack

David Flanagan has this look at using the new javax.script package in Mustang and it's associated Ja. . . Read More

2 Comments

Your HTML converter does not encode > > correct. I cannot see

Set > entryset = defaults.defaults.entrySet();

Oops. Fixed the angle brackets and ampersands so they are properly escaped, and the Java 5 generics goodness shines through!

Thanks for pointing this out, anonymous commenter.

Books

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

The classic Java quick-reference

Advertising

Pages

Hosted By

Powered by Movable Type 4.21-en