You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by re...@apache.org on 2010/06/13 23:30:28 UTC

svn commit: r954313 - in /incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting: BundleContextScalaCompiler.scala BundleContextScalaInterpreter.scala ScriptEngineFactory.scala

Author: reto
Date: Sun Jun 13 21:30:27 2010
New Revision: 954313

URL: http://svn.apache.org/viewvc?rev=954313&view=rev
Log:
CLEREZZA-221: Support for CompiledScripts

Added:
    incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaCompiler.scala
Modified:
    incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaInterpreter.scala
    incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/ScriptEngineFactory.scala

Added: incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaCompiler.scala
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaCompiler.scala?rev=954313&view=auto
==============================================================================
--- incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaCompiler.scala (added)
+++ incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaCompiler.scala Sun Jun 13 21:30:27 2010
@@ -0,0 +1,59 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.apache.clerezza.scala.scripting
+
+import org.osgi.framework.BundleContext
+import org.osgi.framework.Bundle
+import java.io.{File, PrintWriter}
+import scala.tools.nsc._;
+import scala.tools.nsc.interpreter._;
+import scala.tools.nsc.io.{AbstractFile, PlainFile}
+import scala.tools.nsc.util._
+import java.io.PrintWriter
+import java.net._
+import scala.tools.nsc.io.AbstractFile
+import scala.tools.nsc.reporters.Reporter
+import scala.tools.util.PathResolver
+
+/*
+ * unfortunately there seems to be no way to change the classpath, so this doesn't
+ * listen to BundleEvents
+ */
+class BundleContextScalaCompiler(bundleContext : BundleContext,
+		settings: Settings, reporter: Reporter)
+		extends Global(settings, reporter) {
+
+
+	override lazy val classPath: ClassPath[AbstractFile] = {
+
+		val classPathOrig: ClassPath[AbstractFile]  = new PathResolver(settings).result
+		var bundles: Array[Bundle] = bundleContext.getBundles
+		val classPathAbstractFiles = for (bundle <- bundles;
+										  val url = bundle.getResource("/");
+										  if url != null) yield {
+			if ("file".equals(url.getProtocol())) {
+				new PlainFile(new File(url.toURI()))
+			}
+			else {
+				BundleFS.create(bundle);
+			}
+		}
+		val classPaths: List[ClassPath[AbstractFile]] = (for (abstractFile <- classPathAbstractFiles)
+			yield {
+					new DirectoryClassPath(abstractFile, classPathOrig.context)
+				}) toList
+
+		new MergedClassPath[AbstractFile](classPathOrig :: classPaths,
+			   classPathOrig.context)
+
+	}
+
+	override def rootLoader: LazyType = {
+		new loaders.JavaPackageLoader(classPath)
+	}
+}
+
+

Modified: incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaInterpreter.scala
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaInterpreter.scala?rev=954313&r1=954312&r2=954313&view=diff
==============================================================================
--- incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaInterpreter.scala (original)
+++ incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/BundleContextScalaInterpreter.scala Sun Jun 13 21:30:27 2010
@@ -19,8 +19,6 @@
 package org.apache.clerezza.scala.scripting;
 
 import org.osgi.framework.BundleContext
-import org.osgi.framework.Bundle
-import java.io.{File, PrintWriter}
 import scala.tools.nsc._;
 import scala.tools.nsc.interpreter._;
 import scala.tools.nsc.io.{AbstractFile, PlainFile}
@@ -49,41 +47,3 @@ class BundleContextScalaInterpreter(bund
 	}
 }
 
-/*
- * unfortunately there seems to be no way to change the classpath, so this doesn't
- * listen to BunldeEvents
- */
-class BundleContextScalaCompiler(bundleContext : BundleContext,
-		settings: Settings, reporter: Reporter)
-		extends Global(settings, reporter) {
-	
-
-	override lazy val classPath: ClassPath[AbstractFile] = {
-
-		val classPathOrig: ClassPath[AbstractFile]  = new PathResolver(settings).result
-		var bundles: Array[Bundle] = bundleContext.getBundles
-		val classPathAbstractFiles = for (bundle <- bundles;
-										  val url = bundle.getResource("/");
-										  if url != null) yield {
-			if ("file".equals(url.getProtocol())) {
-				new PlainFile(new File(url.toURI()))
-			}
-			else {
-				BundleFS.create(bundle);
-			}
-		}
-		val classPaths: List[ClassPath[AbstractFile]] = (for (abstractFile <- classPathAbstractFiles)
-			yield {
-					new DirectoryClassPath(abstractFile, classPathOrig.context)
-				}) toList
-
-		new MergedClassPath[AbstractFile](classPathOrig :: classPaths,
-			   classPathOrig.context)
-
-	}
-
-	override def rootLoader: LazyType = {
-		new loaders.JavaPackageLoader(classPath)
-	}
-}
-

Modified: incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/ScriptEngineFactory.scala
URL: http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/ScriptEngineFactory.scala?rev=954313&r1=954312&r2=954313&view=diff
==============================================================================
--- incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/ScriptEngineFactory.scala (original)
+++ incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/ScriptEngineFactory.scala Sun Jun 13 21:30:27 2010
@@ -21,24 +21,30 @@ package org.apache.clerezza.scala.script
 
 
 import org.apache.felix.scr.annotations.Component;
+import org.osgi.framework.BundleContext
 import org.osgi.framework.BundleEvent
 import org.osgi.framework.BundleListener
 import org.osgi.service.component.ComponentContext;
 import org.osgi.framework.Bundle
 import java.io.{File, PrintWriter, Reader, StringWriter}
 import java.util.{ArrayList, Arrays};
+//import scala.collection.immutable.Map
 import scala.tools.nsc._;
 import scala.tools.nsc.interpreter._;
-import scala.tools.nsc.io.{AbstractFile, PlainFile}
+import scala.tools.nsc.io.{AbstractFile, PlainFile, VirtualDirectory}
 import scala.tools.nsc.util._
 import scala.tools.nsc.symtab.SymbolLoaders
 import java.net._
 import scala.tools.nsc.reporters.ConsoleReporter
+import scala.tools.nsc.reporters.ConsoleReporter
+import scala.tools.nsc.reporters.ConsoleReporter
 import scala.tools.nsc.reporters.Reporter
 import scala.tools.util.PathResolver
 import scala.tools.nsc.util.{ClassPath, JavaClassPath}
 import javax.script.ScriptContext
-import javax.script.{ScriptEngineFactory => JavaxEngineFactory, ScriptEngine, AbstractScriptEngine, Bindings, SimpleBindings, ScriptException}
+import javax.script.{ScriptEngineFactory => JavaxEngineFactory, Compilable, 
+					 CompiledScript, ScriptEngine, AbstractScriptEngine, Bindings,
+					 SimpleBindings, ScriptException}
 import scala.actors.Actor
 import scala.actors.Actor._
 
@@ -51,6 +57,7 @@ class ScriptEngineFactory() extends  Jav
 
 	var factory: InterpreterFactory = null
 	var _interpreter : Interpreter = null;
+	private var bundleContext: BundleContext = null
 	def interpreter = {
 		if (_interpreter == null) {
 			this.synchronized {
@@ -91,12 +98,12 @@ class ScriptEngineFactory() extends  Jav
 	override def getScriptEngine : ScriptEngine = MyScriptEngine
 
 	def activate(componentContext: ComponentContext)= {
-		val bundleContext = componentContext.getBundleContext
+		bundleContext = componentContext.getBundleContext
 		bundleContext.addBundleListener(this)
 	}
 
 	def deactivate(componentContext: ComponentContext) = {
-		val bundleContext = componentContext.getBundleContext
+		bundleContext = componentContext.getBundleContext
 		bundleContext.removeBundleListener(this)
 	}
 
@@ -110,7 +117,7 @@ class ScriptEngineFactory() extends  Jav
 	}
 	/** Inner object as it accesse interpreter
 	 */
-	object MyScriptEngine extends AbstractScriptEngine() {
+	object MyScriptEngine extends AbstractScriptEngine() with Compilable {
 		override def eval(script : Reader, context : ScriptContext) : Object = {
 			val scriptStringWriter = new StringWriter()
 			var ch = script.read
@@ -176,6 +183,62 @@ class ScriptEngineFactory() extends  Jav
 		override def getFactory() = ScriptEngineFactory.this
 		override def createBindings() : Bindings = new SimpleBindings
 
+		override def compile(script: Reader): CompiledScript = {
+			val scriptStringWriter = new StringWriter()
+			var ch = script.read
+			while (ch != -1) {
+				scriptStringWriter.write(ch)
+				ch = script.read
+			}
+			compile(scriptStringWriter.toString)
+		}
+
+		val virtualDirectory = new VirtualDirectory("(memory)", None)
+		var classCounter = 0
+
+		override def compile(script: String): CompiledScript = {
+			val objectName = "CompiledScript"+classCounter
+			classCounter += 1
+			val classCode = "object " + objectName + """ {
+				|	def run($: Map[String, Object]) = {
+				|""".stripMargin + script +"""
+				|	}
+				|}""".stripMargin
+			val sources: List[SourceFile] = List(new BatchSourceFile("<script>", classCode))
+			(new compiler.Run).compileSources(sources)
+
+			new CompiledScript() {
+				override def eval(context: ScriptContext) = {
+					var map = Map[String, Object]()
+					import _root_.scala.collection.JavaConversions._
+					for (	scope <- context.getScopes;
+							if (context.getBindings(scope.intValue) != null);
+							entry <- context.getBindings(scope.intValue)) {
+						map = map + (entry._1 -> entry._2)
+					}
+					val classLoader = new AbstractFileClassLoader(virtualDirectory, this.getClass.getClassLoader())
+					val runMethod = classLoader.findClass(objectName).getMethod("run", classOf[Map[String, Object]])
+					runMethod.invoke(null, map)
+				}
+				override def getEngine = MyScriptEngine.this
+			}
+		}
+
+		
+
+		lazy val compiler = {
+			val settings = new Settings	
+			settings.outputDirs setSingleOutput virtualDirectory
+			val out = new PrintWriter(System.out)
+			new BundleContextScalaCompiler(bundleContext, settings,										   
+			new ConsoleReporter(settings, null, out) {
+				override def printMessage(msg: String) {
+					out println msg
+					out.flush()
+				}
+			})
+		}
+
 		/**
 		 * returns an accessible class or interface that is implemented by class,
 		 * is doesn't look for superinterfaces of implement interfaces