import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* This class is responsible for reading the Javascript source
* and parses the content to JSONMLAst format as discussed in
* http://code.google.com/p/es-lab/wiki/JsonMLASTFormat#AST_Format
*
* Javascript parser is based on an OMeta-based parser for Ecmascript 5, written in Javascript,
* generating a JsonML-based AST
* http://code.google.com/p/es-lab/
*
* This class uses the javax.script API to integrate the script into the JAVA program.
*/
public class JS2AST {
private ScriptEngine engine;
private Object AST;
public JS2AST() throws ScriptException {
// jav8 depends in google's V8 javascript engine
ScriptEngineManager factory = new ScriptEngineManager();
engine = factory.getEngineByName("jav8");
// we can use the standard engine or create our own scripting engine
//ScriptEngineManager factory = new ScriptEngineManager();
//engine = factory.getEngineByName("javascript");
// Java Script API does not support load function. This is a hack to include the definition of load into the script
this.engine.put("JS2AST", this);
this.engine.eval("function load(filename) { JS2AST.load(filename); }");
// prerequisite scripts including the full es5 Javascript parser
load("jslib/json2.js");
load("jslib/lib.js");
load("jslib/ometa-base.js");
load("jslib/es5parser.js");
load("jslib/unicode.js");
}
/**
* Using the es5 parser written in Javascript, invokes the
* parse2AST method of the wrapper (jslib/parse2AST.js) to parse the input file,
* and outputs JSONML array string storing the AST
*
* @param parser Reader for the Javascript parser
* @param jsfile String source of the Javascript file to be parsed
* @throws Exception
*/
public Object createAST(Reader parser, String jsfile) throws Exception{
try {
engine.eval(parser);
Invocable invocableEngine = (Invocable)engine;
// Store the script in a String
String js = readFile2String(jsfile);
//String js = getURLContent(codeURL);
// (function name, script source, boolean for position details)
AST = (String)invocableEngine.invokeFunction("parse2AST", js, true);
//AST = invocableEngine.invokeFunction("parse2JSON", js, true);
} catch (Exception ex) {
ex.printStackTrace();
}
return AST;
}
/**
* Returns the data from URL as String
*
* @param URL URL address of the source
* @throws IOException
*/
private static String getURLContent(URL u) throws IOException
{
URLConnection uc=u.openConnection();
StringBuffer buffer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String line;
while((line=reader.readLine())!=null) {
buffer.append(line+"\n");
}
return buffer.toString();
}
/**
* Returns the data from file as String
*
* @param filename Full path of the file
*/
private static String readFile2String(String filename){
StringBuffer buffer = new StringBuffer();
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(filename));
String line;
while((line=reader.readLine())!=null) {
buffer.append(line+"\n");
}
} catch (IOException e) {
throw new RuntimeException("Error loading file: " + filename, e);
}
return buffer.toString();
}
/**
* Load content of the file into the script
*
* @param filename Full path of the file
*/
public void load(String filename) throws ScriptException {
try {
this.engine.eval(new FileReader(filename));
}
catch(FileNotFoundException e) {
throw new RuntimeException("Error loading javascript file: " + filename, e);
}
}
}