summaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/net.appjet.bodylock/bodylock.scala
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/infrastructure/net.appjet.bodylock/bodylock.scala')
-rw-r--r--trunk/infrastructure/net.appjet.bodylock/bodylock.scala291
1 files changed, 0 insertions, 291 deletions
diff --git a/trunk/infrastructure/net.appjet.bodylock/bodylock.scala b/trunk/infrastructure/net.appjet.bodylock/bodylock.scala
deleted file mode 100644
index e24d55c..0000000
--- a/trunk/infrastructure/net.appjet.bodylock/bodylock.scala
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * Copyright 2009 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS-IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.appjet.bodylock;
-
-import net.appjet.common.rhino.rhinospect;
-
-import scala.collection.mutable.{SynchronizedMap, ArrayBuffer, HashMap};
-
-import org.mozilla.javascript.{Context, Scriptable, ScriptableObject, Script, JavaScriptException, NativeJavaObject, WrappedException, IdScriptableObject};
-
-trait Executable {
- def execute(scope: Scriptable): Object;
-}
-
-trait JSStackFrame {
- def errorLine: Int; // 1-indexed.
- def errorContext(rad: Int): (Int, Int, Seq[String]); // 1-indexed
- def name: String;
-}
-
-class ExecutionException(message: String, cause: Throwable) extends RuntimeException(message, cause) {
- def this(message: String) = this(message, null);
-}
-
-class JSRuntimeException(val message: String, val cause: Throwable) extends ExecutionException(message, cause) {
- private val i_frames: Seq[JSStackFrame] = if (cause == null) List() else {
- val ab = new ArrayBuffer[JSStackFrame];
- for (elt <- cause.getStackTrace() if (elt.getFileName != null && BodyLock.map.filter(_.contains(elt.getFileName)).isDefined && elt.getLineNumber >= 0)) {
- ab += new JSStackFrame {
- val errorLine = elt.getLineNumber;
- val name = elt.getFileName;
- val code = BodyLock.map.getOrElse(Map[String, String]()).getOrElse(elt.getFileName, "").split("\n"); // 0-indexed.
- def errorContext(rad: Int) = {
- val start_i = Math.max(errorLine-rad, 1)-1;
- val end_i = Math.min(errorLine+rad, code.length)-1;
- (start_i+1, end_i+1, code.slice(start_i, end_i+1));
- }
- }
- }
- ab;
- }
- def frames = i_frames;
-}
-
-class JSCompileException(message: String, cause: org.mozilla.javascript.EvaluatorException) extends JSRuntimeException(message, cause) {
- override val frames =
- List(new JSStackFrame {
- val errorLine = cause.lineNumber();
- val name = cause.sourceName();
- val code = BodyLock.map.getOrElse(Map[String, String]()).getOrElse(cause.sourceName(), "").split("\n"); // 0-indexed.
- def errorContext(rad: Int) = {
- val start_i = Math.max(errorLine-rad, 1)-1;
- val end_i = Math.min(errorLine+rad, code.length)-1;
- (start_i+1, end_i+1, code.slice(start_i, end_i+1));
- }
- }).concat(List(super.frames: _*));
-}
-
-private[bodylock] class InnerExecutable(val code: String, val script: Script) extends Executable {
- def execute(scope: Scriptable) = try {
- BodyLock.runInContext { cx =>
- script.exec(cx, scope);
- }
- } catch {
- case e: Throwable => {
- val orig = BodyLock.unwrapExceptionIfNecessary(e);
- orig match {
- case e: JSRuntimeException => throw e;
- case e: org.mortbay.jetty.RetryRequest => throw e;
- case _ => throw new JSRuntimeException("Error while executing: "+orig.getMessage, orig);
- }
- }
- }
-
- override def toString() =
- rhinospect.dumpFields(script, 1, "");
-}
-
-object CustomContextFactory extends org.mozilla.javascript.ContextFactory {
- val wrapFactory = new org.mozilla.javascript.WrapFactory {
- setJavaPrimitiveWrap(false); // don't wrap strings, numbers, booleans
- }
-
- class CustomContext() extends Context() {
- setWrapFactory(wrapFactory);
- }
-
- override def makeContext(): Context = new CustomContext();
-}
-
-object BodyLock {
- var map: Option[SynchronizedMap[String, String]] = None;
-
- def runInContext[E](expr: Context => E): E = {
- val cx = CustomContextFactory.enterContext();
- try {
- expr(cx);
- } finally {
- Context.exit();
- }
- }
-
- def newScope = runInContext { cx =>
- cx.initStandardObjects(null, true);
- }
- def subScope(scope: Scriptable) = runInContext { cx =>
- val newObj = cx.newObject(scope).asInstanceOf[ScriptableObject];
- newObj.setPrototype(scope);
- newObj.setParentScope(null);
- newObj;
- }
-
- def evaluateString(scope: Scriptable, source: String, sourceName: String,
- lineno: Int /*, securityDomain: AnyRef = null */) = runInContext { cx =>
- cx.evaluateString(scope, source, sourceName, lineno, null);
- }
- def compileString(source: String, sourceName: String, lineno: Int
- /*, securityDomain: AnyRef = null */) = runInContext { cx =>
- map.foreach(_(sourceName) = source);
- try {
- new InnerExecutable(source, compileToScript(source, sourceName, lineno));
- } catch {
- case e: org.mozilla.javascript.EvaluatorException => {
- throw new JSCompileException(e.getMessage(), e);
- }
- }
- }
-
- private val classId = new java.util.concurrent.atomic.AtomicInteger(0);
-
- private def compileToScript(source: String, sourceName: String, lineNumber: Int): Script = {
- val className = "JS$"+sourceName.replaceAll("[^a-zA-Z0-9]", "\\$")+"$"+classId.incrementAndGet();
- compilationutils.compileToScript(source, sourceName, lineNumber, className);
- }
-
- def executableFromBytes(bytes: Array[byte], className: String) =
- new InnerExecutable("(source not available)", compilationutils.bytesToScript(bytes, className));
-
- def unwrapExceptionIfNecessary(e: Throwable): Throwable = {
- e match {
- case e: JavaScriptException => e.getValue() match {
- case njo: NativeJavaObject => Context.jsToJava(njo, classOf[Object]) match {
- case e: Throwable => e;
- case _ => e;
- }
- case ne: IdScriptableObject => new JSRuntimeException("Error: "+ne.get("message", ne), e);
- case t: Throwable => t;
- case _ => e;
- }
- case e: WrappedException => unwrapExceptionIfNecessary(e.getWrappedException());
- case _ => e;
- }
- }
-}
-
-private[bodylock] object compilationutils {
- class Loader(parent: ClassLoader) extends ClassLoader(parent) {
- def this() = this(getClass.getClassLoader);
- def defineClass(className: String, bytes: Array[Byte]): Class[_] = {
- // call protected method
- defineClass(className, bytes, 0, bytes.length);
- }
- }
-
- def compileToBytes(source: String, sourceName: String, lineNumber: Int,
- className: String): Array[Byte] = {
- val environs = new org.mozilla.javascript.CompilerEnvirons;
- BodyLock.runInContext(environs.initFromContext(_));
- environs.setGeneratingSource(false);
- val compiler = new org.mozilla.javascript.optimizer.ClassCompiler(environs);
-
- // throws EvaluatorException
- val result:Array[Object] =
- compiler.compileToClassFiles(source, sourceName, lineNumber, className);
-
- // result[0] is class name, result[1] is class bytes
- result(1).asInstanceOf[Array[Byte]];
- }
-
- def compileToScript(source: String, sourceName: String, lineNumber: Int,
- className: String): Script = {
- bytesToScript(compileToBytes(source, sourceName, lineNumber, className), className);
- }
-
- def bytesToScript(bytes: Array[Byte], className: String): Script = {
- (new Loader()).defineClass(className, bytes).newInstance.asInstanceOf[Script];
- }
-}
-
-
-import java.io.File;
-import scala.collection.mutable.HashMap;
-import net.appjet.common.util.BetterFile;
-import net.appjet.common.cli._;
-
-object Compiler {
- val optionsList = Array(
- ("destination", true, "Destination for class files", "path"),
- ("cutPrefix", true, "Drop this prefix from files", "path"),
- ("verbose", false, "Print debug information", "")
- );
- val chosenOptions = new HashMap[String, String];
- val options =
- for (opt <- optionsList) yield
- new CliOption(opt._1, opt._3, if (opt._2) Some(opt._4) else None)
-
-// var o = new Options;
-// for (m <- optionsList) {
-// o.addOption({
-// if (m._2) {
-// withArgName(m._4);
-// hasArg();
-// }
-// withDescription(m._3);
-// // withLongOpt(m.getName());
-// create(m._1);
-// });
-// }
-// o;
-// }
-
- var verbose = true;
- def vprintln(s: String) {
- if (verbose) println(s);
- }
-
- def printUsage() {
- println((new CliParser(options)).usage);
- }
- def extractOptions(args0: Array[String]) = {
- val parser = new CliParser(options);
- val (opts, args) =
- try {
- parser.parseOptions(args0);
- } catch {
- case e: ParseException => {
- println("error: "+e.getMessage());
- printUsage();
- System.exit(1);
- null;
- }
- }
- for ((k, v) <- opts) {
- chosenOptions(k) = v;
- }
- args
- }
- def compileSingleFile(src: File, dst: File) {
- val source = BetterFile.getFileContents(src);
- vprintln("to: "+dst.getPath());
- val classBytes = compilationutils.compileToBytes(source, src.getName(), 1, dst.getName().split("\\.")(0));
-
- val fos = new java.io.FileOutputStream(dst);
- fos.write(classBytes);
- }
-
- def main(args0: Array[String]) {
- // should contain paths, relative to PWD, of javascript files to compile.
- val args = extractOptions(args0);
- val dst = chosenOptions("destination");
- val pre = chosenOptions.getOrElse("cutPrefix", "");
- verbose = chosenOptions.getOrElse("verbose", "false") == "true";
- for (p <- args) {
- val srcFile = new File(p);
- if (srcFile.getParent() != null && ! srcFile.getParent().startsWith(pre))
- throw new RuntimeException("srcFile "+srcFile.getPath()+" doesn't start with "+pre);
- val parentDir =
- if (srcFile.getParent() != null) {
- new File(dst+"/"+srcFile.getParent().substring(pre.length));
- } else {
- new File(dst);
- }
- parentDir.mkdirs();
- compileSingleFile(srcFile, new File(parentDir.getPath()+"/JS$"+srcFile.getName().split("\\.").reverse.drop(1).reverse.mkString(".").replaceAll("[^a-zA-Z0-9]", "\\$")+".class"));
- }
- }
-}