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

Reply via email to