Package com.aicontest.visualizer

Source Code of com.aicontest.visualizer.WebWrapper$Script

package com.aicontest.visualizer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.ReentrantLock;

import javax.swing.JOptionPane;
import javax.swing.UIManager;

import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ErrorReporter;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.GeneratedClassLoader;
import org.mozilla.javascript.IRFactory;
import org.mozilla.javascript.NativeJavaClass;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.SecurityController;
import org.mozilla.javascript.ast.AstRoot;
import org.mozilla.javascript.ast.ScriptNode;
import org.mozilla.javascript.json.JsonParser;
import org.mozilla.javascript.json.JsonParser.ParseException;
import org.mozilla.javascript.optimizer.Codegen;

import com.aicontest.visualizer.js.dom.Console;
import com.aicontest.visualizer.js.dom.HTMLCanvasElement;
import com.aicontest.visualizer.js.dom.HTMLImageElement;
import com.aicontest.visualizer.js.dom.Navigator;
import com.aicontest.visualizer.js.dom.XMLHttpRequest;
import com.aicontest.visualizer.js.tasks.DelayedExecutionUnit;
import com.aicontest.visualizer.js.tasks.EventExecutionUnit;
import com.aicontest.visualizer.js.tasks.IExecutionUnit;

public class WebWrapper {

  private File baseDir;
  private final ReentrantLock lock = new ReentrantLock();
  private final ExecutionUnitQueue queue = new ExecutionUnitQueue();
  private Map<String, String> precompiled = new HashMap<String, String>();
  private Map<String, String> inUse = new HashMap<String, String>();
  private Thread jsThread = Thread.currentThread();
  private Codegen compiler;
  private CompilerEnvirons compilerEnv;
  private ErrorReporter compilationErrorReporter;
  private GeneratedClassLoader loader;
  private volatile boolean running = true;
  private JsonParser jsonParser;
  protected ArrayList<WebWrapper.Script> scripts = new ArrayList<WebWrapper.Script>();
  protected Context cx;
  protected ScriptableObject global;
  protected HTMLCanvasElement canvas;

  public WebWrapper(String baseDir) {
    cx = Context.enter();
    cx.setOptimizationLevel(-1);
    cx.setLanguageVersion(150);
    this.baseDir = (baseDir == null) ? null : new File(baseDir);
    try {
      InputStream is = getClass().getResourceAsStream("/precompiled");
      if (is == null) {
        is = new FileInputStream("precompiled");
      }
      BufferedReader br = new BufferedReader(new InputStreamReader(is));
      try {
        String js;
        while ((js = br.readLine()) != null) {
          String clazz = br.readLine();
          precompiled.put(js, clazz);
        }
      } finally {
        br.close();
      }
    } catch (Exception e) {
    }
    global = cx.initStandardObjects();
    cx.putThreadLocal(WebWrapper.class, this);
    Object image = new NativeJavaClass(global, HTMLImageElement.class);
    global.put("Image", global, image);
    Object xmlHttpRequest = new NativeJavaClass(global,
        XMLHttpRequest.class);
    global.put("XMLHttpRequest", global, xmlHttpRequest);
    new Console(global, "console");
    new Navigator(global, "navigator");
    jsonParser = new JsonParser(cx, global);
    String[] names = { "alert", "prompt", "confirm" };
    global.defineFunctionProperties(names, WebWrapper.class,
        ScriptableObject.DONTENUM);
  }

  public static void alert(Object o) {
    String message = o.toString();
    JOptionPane.showMessageDialog(null, message);
  }

  public static boolean confirm(Object o) {
    String message = o.toString();
    return JOptionPane.showConfirmDialog(null, message,
        UIManager.getString("OptionPane.titleText"),
        JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION;
  }

  public static String prompt(Object o, Object def) {
    String message = o.toString();
    return JOptionPane.showInputDialog(message, def.toString());
  }

  private Class<?> recompile(String file) throws IOException {
    if (compiler == null) {
      compiler = new Codegen();
    }
    FileReader in = new FileReader(new File(baseDir, file));
    try {
      if (compilerEnv == null) {
        compilerEnv = new CompilerEnvirons();
        compilerEnv.initFromContext(cx);
        compilerEnv.setOptimizationLevel(1);
        compilerEnv.setGeneratingSource(false);
      }
      if (compilationErrorReporter == null) {
        compilationErrorReporter = compilerEnv.getErrorReporter();
      }
      Parser p = new Parser(compilerEnv, compilationErrorReporter);
      AstRoot ast = p.parse(in, file.toString(), 1);
      IRFactory irf = new IRFactory(compilerEnv, compilationErrorReporter);
      ScriptNode tree = irf.transformTree(ast);
      Object[] nameBytesPair = (Object[]) (Object[]) compiler.compile(
          compilerEnv, tree, tree.getEncodedSource(), false);
      String className = (String) nameBytesPair[0];
      byte[] classBytes = (byte[]) (byte[]) nameBytesPair[1];
      File outFile = new File(className.replace('.', File.separatorChar)
          + ".class");
      String oldClassName = (String) precompiled.get(file);
      if (oldClassName != null) {
        new File(oldClassName.replace('.', File.separatorChar)
            + ".class").delete();
      }
      System.out.println("Saving compiled " + file + " -> " + outFile);
      outFile.getParentFile().mkdirs();
      FileOutputStream fos = new FileOutputStream(outFile);
      try {
        fos.write(classBytes);
      } finally {
        fos.close();
      }
      if (loader == null) {
        loader = SecurityController.createLoader(getClass()
            .getClassLoader(), null);
      }
      Class<?> clazz = loader.defineClass(className, classBytes);
      loader.linkClass(clazz);
      return clazz;
    } finally {
      in.close();
    }
  }

  public Script loadJs(String file) throws InstantiationException,
      IllegalAccessException, IOException {
    Class<?> clazz = null;
    String objClassName = (String) precompiled.get(file);
    if (objClassName == null) {
      clazz = recompile(file);
      objClassName = clazz.getCanonicalName();
    } else {
      File objFile = new File(objClassName.replace('.',
          File.separatorChar) + ".class");
      boolean useExisting = baseDir == null;
      if (!useExisting) {
        File jsFile = new File(baseDir, file);
        try {
          useExisting = !jsFile.canRead()
              || (jsFile.lastModified() <= objFile.lastModified());
        } catch (AccessControlException e) {
        }
      }
      if (useExisting) {
        try {
          clazz = getClass().getClassLoader().loadClass(objClassName);
        } catch (ClassFormatError e) {
          System.err.println("bundled class " + objClassName
              + " has invalid format");
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      if (clazz == null) {
        clazz = recompile(file);
        objClassName = clazz.getCanonicalName();
      }
    }
    inUse.put(file, objClassName);
    return new Script((org.mozilla.javascript.Script) clazz.newInstance());
  }

  public ScriptableObject construct(String functor, Object[] args) {
    return (ScriptableObject) cx.newObject(global, functor, args);
  }

  public void loop() {
    while (running) {
      try {
        // the thread must not be interrupted during execution
        lock.lock();
        try {
          queue.take().execute(cx, global);
          postExecute();
        } finally {
          lock.unlock();
        }
      } catch (InterruptedException e) {
        Thread.interrupted();
      }
    }
  }

  public Object eval(String script) {
    return cx.evaluateString(global, script, "<anonymous>", 1, null);
  }

  public Object invoke(Scriptable thiz, String functionName, Object[] args) {
    Function f = (Function) ScriptableObject
        .getProperty(thiz, functionName);
    return f.call(cx, global, thiz, args);
  }

  public Object parseJSON(String json) throws ParseException {
    return jsonParser.parseValue(json);
  }

  public static WebWrapper getInstance() {
    Context cx = Context.enter();
    try {
      WebWrapper localWebWrapper = (WebWrapper) cx
          .getThreadLocal(WebWrapper.class);
      return localWebWrapper;
    } finally {
      Context.exit();
    }
  }

  protected void postExecute() {
  }

  public void addTask(IExecutionUnit task) {
    queue.add(task);
  }

  public void addCompressedEventTask(EventExecutionUnit task) {
    queue.compressEvent(task);
  }

  public void removeTask(DelayedExecutionUnit task) {
    queue.remove(task);
  }

  public URL getBaseURL() {
    return null;
  }

  public HTMLCanvasElement getMainCanvas() {
    return canvas;
  }

  public void savePrecompiledList() throws Throwable {
    if (!precompiled.equals(inUse)) {
      BufferedWriter fw = new BufferedWriter(
          new FileWriter("precompiled"));
      try {
        for (Entry<String, String> entry : inUse.entrySet()) {
          fw.write((String) entry.getKey());
          fw.newLine();
          fw.write((String) entry.getValue());
          fw.newLine();
        }
      } finally {
        fw.close();
      }
    }
  }

  public class Script {

    private org.mozilla.javascript.Script script;

    private Script(org.mozilla.javascript.Script script) {
      this.script = script;
    }

    public void run() {
      script.exec(cx, global);
    }
  }

  public void loadProgram(IProgram program) throws InstantiationException,
      IllegalAccessException, IOException {
    String[] files = program.getFiles();
    for (String file : files) {
      scripts.add(loadJs(file));
    }
  }

  public void exit() {
    synchronized (lock) {
      running = false;
      jsThread.interrupt();
    }
    try {
      jsThread.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  public ScriptableObject getGlobal() {
    return global;
  }

  protected void runProgram() {
    for (WebWrapper.Script script : scripts) {
      script.run();
    }
  }
}
TOP

Related Classes of com.aicontest.visualizer.WebWrapper$Script

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.