/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.nmedit.jpatch.js; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.util.HashMap; import java.util.Map; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.Script; import org.mozilla.javascript.Scriptable; public class JSContext { private Context cx; private Scriptable scope; public JSContext() { super(); initialize(); } public Context getContext() { return cx; } public Scriptable getScope() { return scope; } private void initialize() { cx = Context.enter(); cx.setOptimizationLevel(9); scope = cx.initStandardObjects(); } public Script addScript(File source) throws IOException { return addScript(source.toURI().toURL()); } public Script addScript(URL source) throws IOException { Reader r = new BufferedReader(new InputStreamReader(source.openStream())); try { return addScript(r, source.toString()); } finally { r.close(); } } public Script addScript(String source, String sourceName) { Script s = cx.compileString(source, sourceName, 0, null); exec(s); return s; } public Script addScript(Reader in, String sourceName) throws IOException { Script s = cx.compileReader(in, sourceName, 0, null); exec(s); return s; } private void exec(Script script) { script.exec(cx, scope); } protected void finalize() throws Throwable { try { Context.exit(); } catch (Exception e) { e.printStackTrace(); } super.finalize(); } public Function getFormatterFunction(String src) { Function f = getFunction(src); return (f != null) ? f : getBodyFunction(src); } private Map<String, Function> functionBodyMap = new HashMap<String, Function>(); private Function getBodyFunction(String body) { String norm = normalizeFunctionBody(body); Function f = functionBodyMap.get(norm); if (f == null) { f = compileFunctionBody(body); functionBodyMap.put(norm, f); } return f; } private String normalizeFunctionBody(String body) { body = body.toLowerCase(); StringBuilder sb = new StringBuilder(); for (int i=0;i<body.length();i++) { char c = body.charAt(i); if (!Character.isWhitespace(c)) sb.append(c); } return sb.toString(); } private Function compileFunctionBody(String body) { try { return cx.compileFunction(scope, "function(value) {return "+body+";}", "sourceName", 0, null); } catch (RuntimeException e) { e.printStackTrace(); } return null; } private Function getFunction(String name) { Object f = scope.get(name, scope); return f == Scriptable.NOT_FOUND ? null : ((Function)f); } /* public void test() throws IOException { test(cx); } String scriptFile() { return "/home/christian/CVS-Arbeitsbereich/nmedit/libs/nordmodular/data/module-descriptions/nmformat.js"; } private void test(Context cx) throws IOException { addScript(new File(scriptFile())); Function f = getFunction("fmtSemitones"); if (f != null) { // System.out.println(Context.toString(f)); Object[] args = new Object[1]; for (int i=0;i<127;i++) { args[0] = i; Object result = f.call(cx, scope, scope, args); System.out.println("fmt[i]="+result); } } f = getFormatterFunction("fmtSemitones"); System.out.println(Context.toString(f)); f = getFormatterFunction("value-64"); System.out.println(Context.toString(f)); } public static void main(String[] args) throws IOException { JSContext jsc = new JSContext(); jsc.test(); } */ }