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
}