Skip to content
Snippets Groups Projects
Verified Commit dc595e58 authored by Rico Bergmann's avatar Rico Bergmann
Browse files

[WIP] Create JAR with compiled scala classes

parent 42906dd5
No related branches found
No related tags found
2 merge requests!2Publish v0.1,!1Move away from experimental changes
This commit is part of merge request !1. Comments created here will be created in the context of that merge request.
package org.rosi_project.model_sync.generator.io package org.rosi_project.model_sync.generator.io
import java.io.{FileOutputStream, PrintWriter} import java.io.{BufferedInputStream, FileInputStream, FileOutputStream, PrintWriter}
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Files import java.nio.file.Files
import java.util.jar.{Attributes, JarOutputStream, Manifest} import java.util.jar.{Attributes, JarEntry, JarOutputStream, Manifest}
import org.rosi_project.model_sync.generator.acr.{SAttribute, SClass, SMethod, SType} import org.rosi_project.model_sync.generator.acr.{SAttribute, SClass, SMethod, SType}
import org.rosi_project.model_sync.generator.sync_model.{SModel, SModelVisitor} import org.rosi_project.model_sync.generator.sync_model.{SModel, SModelVisitor}
...@@ -11,6 +11,7 @@ import org.rosi_project.model_sync.generator.sync_model.{SModel, SModelVisitor} ...@@ -11,6 +11,7 @@ import org.rosi_project.model_sync.generator.sync_model.{SModel, SModelVisitor}
import scala.reflect.io.{File, Path} import scala.reflect.io.{File, Path}
import scala.tools.nsc.reporters.ConsoleReporter import scala.tools.nsc.reporters.ConsoleReporter
import scala.tools.nsc.{GenericRunnerSettings, Global, Settings} import scala.tools.nsc.{GenericRunnerSettings, Global, Settings}
import scala.util.control.Breaks._
/** /**
* @author Rico Bergmann * @author Rico Bergmann
...@@ -26,6 +27,7 @@ class SModelFSWriter extends SModelVisitor { ...@@ -26,6 +27,7 @@ class SModelFSWriter extends SModelVisitor {
println(s"... Wrote files (sources) $sFilesToCompile") println(s"... Wrote files (sources) $sFilesToCompile")
println("... Starting compilation") println("... Starting compilation")
// see: https://stackoverflow.com/a/20323371/5161760
val out = new PrintWriter(System.out) val out = new PrintWriter(System.out)
val compilationSettings: Settings = new GenericRunnerSettings(out.println) val compilationSettings: Settings = new GenericRunnerSettings(out.println)
// TODO do we want to reuse the whole classpath? Or just the parts we _actually_ need // TODO do we want to reuse the whole classpath? Or just the parts we _actually_ need
...@@ -39,13 +41,53 @@ class SModelFSWriter extends SModelVisitor { ...@@ -39,13 +41,53 @@ class SModelFSWriter extends SModelVisitor {
println("... Compilation done") println("... Compilation done")
println("... Cleaning up") println("... Cleaning up")
sFilesToCompile.foreach{_.delete} sFilesToCompile.foreach {
_.delete
}
println("... Generating JAR") println("... Generating JAR")
// see: https://stackoverflow.com/questions/1281229/how-to-use-jaroutputstream-to-create-a-jar-file // see: https://stackoverflow.com/a/1281295/5161760
val mf = new Manifest val mf = new Manifest
mf.getMainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0") mf.getMainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0")
val targetJar = new JarOutputStream(new FileOutputStream("model.jar"), mf) val targetJar = new JarOutputStream(new FileOutputStream("model.jar"), mf)
var filesToAdd: List[java.io.File] = baseOutputDir.jfile.listFiles.toList
while (filesToAdd.nonEmpty) {
val file = filesToAdd.head
var fname = file.getAbsolutePath.replace(baseOutputDir.jfile.getAbsolutePath + File.separator, "").replaceAll("\\\\", "/")
println(s"Adding to JAR: $fname")
if (file.isDirectory) {
if (!fname.endsWith("/")) {
fname += "/"
}
filesToAdd ++= file.listFiles.toList
val entry = new JarEntry(fname)
entry.setTime(file.lastModified)
targetJar.putNextEntry(entry)
targetJar.closeEntry()
} else {
val entry = new JarEntry(fname)
entry.setTime(file.lastModified)
targetJar.putNextEntry(entry)
val in = new BufferedInputStream(new FileInputStream(file))
var buffer = new Array[Byte](1024)
breakable {
while (true) {
val bytesRead = in.read(buffer)
if (bytesRead == -1) {
break
}
targetJar.write(buffer, 0, bytesRead)
}
}
targetJar.closeEntry()
in.close()
}
filesToAdd = filesToAdd.tail
}
// TODO fill the JAR // TODO fill the JAR
...@@ -55,8 +97,11 @@ class SModelFSWriter extends SModelVisitor { ...@@ -55,8 +97,11 @@ class SModelFSWriter extends SModelVisitor {
override def visit(sClass: SClass): Unit = { override def visit(sClass: SClass): Unit = {
println(s"Writing class $sClass") println(s"Writing class $sClass")
val classNameWithPath = baseOutputDir.toAbsolute.toString() + pckg2Path(sClass.getPackage) + File.separator + s"${sClass.name}.scala" val classNameWithPath = baseOutputDir.toAbsolute.toString() + File.separator + pckg2Path(sClass.getPackage) + File.separator + s"${sClass.name}.scala"
val writer = new SClassWriter(sClass) val writer = new SClassWriter(sClass)
// TODO create missing directories for packages (if necessary)
val classFile = File(classNameWithPath) val classFile = File(classNameWithPath)
classFile.writeAll(writer.stringify) classFile.writeAll(writer.stringify)
...@@ -81,11 +126,15 @@ class SModelFSWriter extends SModelVisitor { ...@@ -81,11 +126,15 @@ class SModelFSWriter extends SModelVisitor {
val ctxLoader = Thread.currentThread().getContextClassLoader val ctxLoader = Thread.currentThread().getContextClassLoader
ctxLoader match { ctxLoader match {
case urlCL: URLClassLoader => case urlCL: URLClassLoader =>
urlCL.getURLs.toList.map{_.toString} urlCL.getURLs.toList.map {
_.toString
}
case wrappedCL => case wrappedCL =>
wrappedCL.getParent match { wrappedCL.getParent match {
case urlCL: URLClassLoader => case urlCL: URLClassLoader =>
urlCL.getURLs.toList.map{_.toString} urlCL.getURLs.toList.map {
_.toString
}
case something => sys.error(s"Could not unwrap class loader: $something") case something => sys.error(s"Could not unwrap class loader: $something")
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment