This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-sbt.git
The following commit(s) were added to refs/heads/main by this push:
new 7758e7a Use the new compileResource API when using Daffodil 3.9.0+
7758e7a is described below
commit 7758e7aa57938fd7507440dae5245ee135ab7c5b
Author: Steve Lawrence <[email protected]>
AuthorDate: Mon Sep 30 13:40:55 2024 -0400
Use the new compileResource API when using Daffodil 3.9.0+
The compileResource API is useful to create depersonalized diagnostics
and saved-parsers.
This modifies the DaffodilPlugin to use compileResource instead of
compileSource when creating a saved parser for newer versions of
Daffodil. DaffodilSaver must still support older versions of Daffodil
that do not have this new API, so the plugin passes in a number to the
saver to signify which version of the API to use.
Closes #47
---
.../scala/org/apache/daffodil/DaffodilPlugin.scala | 16 +++++++++
.../scala/org/apache/daffodil/DaffodilSaver.scala | 38 +++++++++++++++-------
2 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
index c694cdd..5b90547 100644
--- a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
+++ b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
@@ -361,10 +361,26 @@ object DaffodilPlugin extends AutoPlugin {
)
}
+ // the DaffodilSaver needs to know which version of Daffodil we
are using to create
+ // a saved processor, since some versions of Daffodil have
different APIs and it
+ // must use the correct one using reflection. The DaffodilSaver is
forked without
+ // SBT libraries on the classpath, so it can't easily use the
SemanticVersion to
+ // compare versions. So we map each Daffodil version to an
"internal API" version,
+ // which is just a simple number that is easier to use in the
Saver and signify
+ // where API functions to use. This is the mapping for which
Daffodil API should be
+ // used for a particular "internal API"
+ val daffodilInternalApiVersionMapping = Map(
+ ">3.8.0" -> "2",
+ "<=3.8.0" -> "1",
+ )
+ val internalApiVersion =
+ filterVersions(daffodilVersion,
daffodilInternalApiVersionMapping).head
+
val args = jvmArgs ++ Seq(
"-classpath",
classpathFiles.mkString(File.pathSeparator),
mainClass,
+ internalApiVersion,
dbi.schema,
targetFile.toString,
dbi.root.getOrElse(""),
diff --git a/src/main/scala/org/apache/daffodil/DaffodilSaver.scala
b/src/main/scala/org/apache/daffodil/DaffodilSaver.scala
index 8d6af29..7540a48 100644
--- a/src/main/scala/org/apache/daffodil/DaffodilSaver.scala
+++ b/src/main/scala/org/apache/daffodil/DaffodilSaver.scala
@@ -34,29 +34,35 @@ import scala.collection.JavaConverters._
object DaffodilSaver {
/**
- * Usage: daffodilReflectionSave <schemaResource> <outputFile> <root>
<config>
+ * Usage: daffodilReflectionSave <apiVersion> <schemaResource> <outputFile>
<root> <config>
*
* If <root> or <config> is unknown/not-provided, they must be the empty
string
*/
def main(args: Array[String]): Unit = {
assert(
- args.length == 4,
+ args.length == 5,
"DaffodilPlugin did not provide the correct number of arguments when
forking DaffodilSaver",
)
- val schemaUrl = this.getClass.getResource(args(0))
+ // the "version" of the Daffodil API to use. Note that this is not the
same as the Daffodil
+ // version, but is related. See the "daffodilInternalAPIVersionMapping" in
the plugin code
+ // for an explanation of why we have this and what version of Daffodil it
represents.
+ val apiVersion = args(0).toInt
+
+ val schemaResource = args(1)
+ val schemaUrl = this.getClass.getResource(schemaResource)
if (schemaUrl == null) {
- System.err.println(s"failed to find schema resource: ${args(0)}")
+ System.err.println(s"failed to find schema resource: $schemaResource")
System.exit(1)
}
val output = FileChannel.open(
- Paths.get(args(1)),
+ Paths.get(args(2)),
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
)
- val root = if (args(2) != "") args(2) else null
- val config = if (args(3) != "") args(3) else null
+ val root = if (args(3) != "") args(3) else null
+ val config = if (args(4) != "") args(4) else null
// parameter types
val cURI = classOf[URI]
@@ -71,7 +77,13 @@ object DaffodilSaver {
val compilerClass = Class.forName("org.apache.daffodil.japi.Compiler")
val compilerWithTunable = compilerClass.getMethod("withTunable", cString,
cString)
- val compilerCompileSource = compilerClass.getMethod("compileSource", cURI,
cString, cString)
+ // the compileResource method added in Daffodil 3.9.0 allows for
depersonalized diagnostics
+ // and better reproducibility of saved parsers--use it instead of
compileSource for newer
+ // versions of Daffodil
+ val compilerCompile = apiVersion match {
+ case 1 => compilerClass.getMethod("compileSource", cURI, cString,
cString)
+ case 2 => compilerClass.getMethod("compileResource", cString, cString,
cString)
+ }
val processorFactoryClass =
Class.forName("org.apache.daffodil.japi.ProcessorFactory")
val processorFactoryIsError = processorFactoryClass.getMethod("isError")
@@ -111,9 +123,13 @@ object DaffodilSaver {
}
}
- // val processorFactory = compiler.compileSource(schemaUrl.toURI, root,
None)
- val processorFactory = compilerCompileSource
- .invoke(compiler, schemaUrl.toURI, root, null)
+ // val processorFactory = compiler.compileSource(schemaUrl.toURI, root,
None) // < 3.9.0
+ // val processorFactory = compiler.compileResource(name, root, None)
// >= 3.9.0
+ val schemaArg = apiVersion match {
+ case 1 => schemaUrl.toURI
+ case 2 => schemaResource
+ }
+ val processorFactory = compilerCompile.invoke(compiler, schemaArg, root,
null)
// val processorFactoryDiags = processorFactory.getDiagnostics()
val processorFactoryDiags = processorFactoryGetDiagnostics