Author: reto
Date: Sat Nov 20 18:17:23 2010
New Revision: 1037287

URL: http://svn.apache.org/viewvc?rev=1037287&view=rev
Log:
CLEREZZA-362: creating classes to a different virtual directory on every run 
(without instantiating a new compiler)

Added:
    
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/SplittingDirectory.scala
Modified:
    
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/CompilerService.scala
    
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/TrackingCompiler.scala
    
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/Wrapper.scala

Modified: 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/CompilerService.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/CompilerService.scala?rev=1037287&r1=1037286&r2=1037287&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/CompilerService.scala
 (original)
+++ 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/CompilerService.scala
 Sat Nov 20 18:17:23 2010
@@ -20,7 +20,10 @@ package org.apache.clerezza.scala.script
 
 
 import java.security.AccessController
+import java.security.Permission
 import java.security.PrivilegedAction
+import java.security.PrivilegedActionException
+import java.security.PrivilegedExceptionAction
 import org.apache.clerezza.scala.scripting.util.FileWrapper
 import org.apache.clerezza.scala.scripting.util.GenericFileWrapperTrait
 import org.apache.clerezza.scala.scripting.util.VirtualDirectoryWrapper
@@ -46,10 +49,17 @@ class CompileErrorsException(message: St
        def this() = this(null)
 }
 
+class CompilePermission extends Permission("Compile Permssion") {
+       def getActions() = ""
+       def implies(p: Permission) = p.isInstanceOf[CompilePermission]
+       override def equals(o: Any): Boolean = o.isInstanceOf[CompilePermission]
+       override def hashCode = classOf[CompilePermission].hashCode
+}
+
 class CompilerService() extends BundleListener  {
 
        protected var bundleContext : BundleContext = null;
-       protected val sharedVirtualDirectory = new VirtualDirectory("(memory)", 
None)
+       //protected val sharedVirtualDirectory = new 
VirtualDirectory("(memory)", None)
        protected var currentSharedCompilerOutputStream: OutputStream = null
        protected val splipptingOutputStream = new OutputStream() {
                def write(b: Int) {
@@ -66,7 +76,8 @@ class CompilerService() extends BundleLi
                if (currentSharedCompiler == null) {
                        synchronized {
                                if (currentSharedCompiler == null) {
-                                       currentSharedCompiler = 
createCompiler(splittingPrintWriter, sharedVirtualDirectory)
+                                       currentSharedCompiler = 
TrackingCompiler(bundleContext, splittingPrintWriter, None)
+                                       //createCompiler(splittingPrintWriter, 
sharedVirtualDirectory)
                                }
                        }
                }
@@ -88,21 +99,36 @@ class CompilerService() extends BundleLi
        }
 
        def createCompiler(out: PrintWriter, outputSirectory: AbstractFile) : 
TrackingCompiler = {
-               TrackingCompiler(bundleContext, out, outputSirectory)
+               TrackingCompiler(bundleContext, out, Some(outputSirectory))
+       }
+
+       def compile(sources: Array[Array[Char]]): Array[Class[_]] = {
+               compile(sources.toList).toArray
        }
 
        def compile(sources: List[Array[Char]]): List[Class[_]] = {
+               AccessController.checkPermission(new CompilePermission)
                sharedCompiler.synchronized {
-                       val baos = new ByteArrayOutputStream
-                       currentSharedCompilerOutputStream = baos
                        try {
-                               sharedCompiler.compile(sources)
+                               AccessController.doPrivileged[List[Class[_]]](
+                                       new 
PrivilegedExceptionAction[List[Class[_]]] {
+                                               def run(): List[Class[_]] = {
+                                                       val baos = new 
ByteArrayOutputStream
+                                                       
currentSharedCompilerOutputStream = baos
+                                                       try {
+                                                               
sharedCompiler.compile(sources)
+                                                       } catch {
+                                                               case c: 
CompileErrorsException => throw new CompileErrorsException(
+                                                                               
new String(baos.toByteArray, "utf-8"))
+                                                               case e => throw 
e
+                                                       } finally {
+                                                               
currentSharedCompilerOutputStream = null
+                                                       }
+                                               }
+                                       })
                        } catch {
-                               case c: CompileErrorsException => throw new 
CompileErrorsException(
-                                               new String(baos.toByteArray, 
"utf-8"))
+                               case e: PrivilegedActionException => throw 
e.getCause
                                case e => throw e
-                       } finally {
-                               currentSharedCompilerOutputStream = null
                        }
                }
        }
@@ -116,14 +142,24 @@ class CompilerService() extends BundleLi
        }
 
        def compileIsolated(sources: List[Array[Char]], outputDirectory: 
AbstractFile): List[Class[_]] = {
-               val out = new ByteArrayOutputStream
-               val printWriter = new PrintWriter(out)
-               val compiler = createCompiler(printWriter, outputDirectory)
-               try {
-                       compiler.compile(sources)
-               } catch {
-                       case c: CompileErrorsException => throw new 
CompileErrorsException(new String(out.toByteArray, "utf-8"))
-                       case e => throw e
+               AccessController.checkPermission(new CompilePermission)
+               sharedCompiler.synchronized {
+                       try {
+                               AccessController.doPrivileged[List[Class[_]]](
+                                       new 
PrivilegedExceptionAction[List[Class[_]]] {
+                                               def run() = {
+                                                       val out = new 
ByteArrayOutputStream
+                                                       val printWriter = new 
PrintWriter(out)
+                                                       val compiler = 
createCompiler(printWriter, outputDirectory)
+                                                       try {
+                                                               
compiler.compile(sources)
+                                                       } catch {
+                                                               case c: 
CompileErrorsException => throw new CompileErrorsException(new 
String(out.toByteArray, "utf-8"))
+                                                               case e => throw 
e
+                                                       }
+                                               }
+                                       })
+                       }
                }
        }
 

Modified: 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/TrackingCompiler.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/TrackingCompiler.scala?rev=1037287&r1=1037286&r2=1037287&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/TrackingCompiler.scala
 (original)
+++ 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/TrackingCompiler.scala
 Sat Nov 20 18:17:23 2010
@@ -21,6 +21,7 @@ package org.apache.clerezza.scala.script
 
 import org.apache.clerezza.scala.scripting.util.FileWrapper
 import org.apache.clerezza.scala.scripting.util.GenericFileWrapperTrait
+import org.apache.clerezza.scala.scripting.util.SplittingDirectory
 import org.apache.clerezza.scala.scripting.util.VirtualDirectoryWrapper
 import org.osgi.framework.BundleContext
 import scala.collection.mutable
@@ -39,7 +40,7 @@ import java.net._
 /** a compiler that keeps track of classes added to the directory
  */
 class TrackingCompiler private (bundleContext : BundleContext,
-               settings: Settings, reporter: Reporter, outputDirectory: 
AbstractFile,
+               settings: Settings, reporter: Reporter, classLoaderBuilder: () 
=> ClassLoader,
                writtenClasses: mutable.ListBuffer[AbstractFile])
        extends  BundleContextScalaCompiler(bundleContext : BundleContext,
                settings: Settings, reporter: Reporter) {
@@ -56,8 +57,8 @@ class TrackingCompiler private (bundleCo
                if (reporter.hasErrors) {
                        reporter.reset
                        throw new CompileErrorsException;
-               } 
-               val classLoader = new AbstractFileClassLoader(outputDirectory, 
this.getClass.getClassLoader())
+               }
+               val classLoader = classLoaderBuilder()
                val result: List[Class[_]] = for (classFile <- 
writtenClasses.toList;
                                                                                
  if (!classFile.name.contains('$'))) yield {
                        val path = classFile.path
@@ -71,7 +72,27 @@ class TrackingCompiler private (bundleCo
 }
 
 object TrackingCompiler {
-       def apply(bundleContext : BundleContext, out: PrintWriter, 
outputDirectory: AbstractFile) = {
+
+       private class TrackingCompilerSplittingDirectory extends 
SplittingDirectory
+
+       private def createClassLoader(dir: AbstractFile) = new 
AbstractFileClassLoader(dir, this.getClass.getClassLoader())
+
+       def apply(bundleContext : BundleContext, out: PrintWriter, 
outputDirectoryOption: Option[AbstractFile]) = {
+               val (outputDirectory, classLoaderBuilder): (AbstractFile, () => 
ClassLoader) = outputDirectoryOption match {
+                       case Some(d) => (d, () => createClassLoader(d))
+                       case None => {
+                                       val d = new 
TrackingCompilerSplittingDirectory
+                                       d.currentTarget = new 
VirtualDirectory("(memory)", None)
+                                       def createClassLoaderAndReset() = {
+                                               val r = 
createClassLoader(d.currentTarget)
+                                               //println("created class loader 
with "+(for (c <- d.currentTarget) yield c).mkString("-"))
+                                               d.currentTarget = new 
VirtualDirectory("(memory)", None)
+                                               r
+                                       }
+                                       (d, createClassLoaderAndReset _)
+                               }
+               }
+
                val writtenClasses: mutable.ListBuffer[AbstractFile] = 
mutable.ListBuffer[AbstractFile]()
                val settings = {
                                trait VirtualDirectoryFlavour extends 
VirtualDirectoryWrapper {
@@ -108,7 +129,7 @@ object TrackingCompiler {
                                        out write msg
                                        out.flush()
                                }
-                       }, outputDirectory, writtenClasses)
+                       }, classLoaderBuilder, writtenClasses)
        }
 }
 

Added: 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/SplittingDirectory.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/SplittingDirectory.scala?rev=1037287&view=auto
==============================================================================
--- 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/SplittingDirectory.scala
 (added)
+++ 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/SplittingDirectory.scala
 Sat Nov 20 18:17:23 2010
@@ -0,0 +1,60 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.apache.clerezza.scala.scripting.util
+
+import scala.tools.nsc.io.AbstractFile
+import scala.tools.nsc.io.VirtualDirectory
+
+class SplittingDirectory()
+               extends VirtualDirectory(null, None) with 
GenericFileWrapperTrait {
+
+       var currentTarget: VirtualDirectory = null
+
+       protected def wrapped: VirtualDirectory = {
+               if (currentTarget == null) {
+                       throw new RuntimeException("No current Target set, 
SplittingDirectory not usable")
+               }
+               currentTarget
+       }
+
+       private def wrap(f: AbstractFile): AbstractFile =  {
+               f match {
+                       case d: VirtualDirectory => new 
VirtualDirectoryWrapper(d, wrap) {
+                                       override def output = d.output
+                               }
+                       case o => new FileWrapper(o, wrap)
+               }
+       }
+       val childWrapper: (AbstractFile) => AbstractFile = wrap
+
+       //lastModified = wrapped.lastModified
+
+       override def output = {
+               wrapped.asInstanceOf[VirtualDirectory].output
+       }
+       override def input = {
+               wrapped.asInstanceOf[VirtualDirectory].input
+       }
+       override def file = {
+               wrapped.asInstanceOf[VirtualDirectory].file
+       }
+       override def container = {
+               wrapped.asInstanceOf[VirtualDirectory].container
+       }
+       override def absolute = {
+               wrapped.asInstanceOf[VirtualDirectory].absolute
+       }
+       override val name = "(splitting)"
+       
+       override def lookupPath(path: String, directory: Boolean): AbstractFile 
= {
+               childWrapper(wrapped.lookupPath(path, directory))
+       }
+       override def lookupPathUnchecked(path: String, directory: Boolean): 
AbstractFile = {
+               childWrapper(wrapped.lookupPathUnchecked(path, directory))
+       }
+
+}
+

Modified: 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/Wrapper.scala
URL: 
http://svn.apache.org/viewvc/incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/Wrapper.scala?rev=1037287&r1=1037286&r2=1037287&view=diff
==============================================================================
--- 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/Wrapper.scala
 (original)
+++ 
incubator/clerezza/trunk/scala-scripting/script-engine/src/main/scala/org/apache/clerezza/scala/scripting/util/Wrapper.scala
 Sat Nov 20 18:17:23 2010
@@ -7,5 +7,5 @@ package org.apache.clerezza.scala.script
 
 trait Wrapper[T] {
        protected def wrapped: T
-       protected val childWrapper: (T) => T
+       protected def childWrapper: (T) => T
 }


Reply via email to