This is an automated email from the ASF dual-hosted git repository.

jadams 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 58a0728  Handle upcoming changes to the DFDL API
58a0728 is described below

commit 58a0728478bad850451b3ae2576428f5d00f7747
Author: Josh Adams <[email protected]>
AuthorDate: Thu Jul 31 10:00:42 2025 -0400

    Handle upcoming changes to the DFDL API
    
    Daffodil 4.0.0 will make significant changes to the API and will no
    longer contain a separate Java API. Changes to the SBT plugin were
    needed to be able to use the new API while maintaining compatibility
    with older versions of DFDL.
---
 .../java/org/apache/daffodil/DaffodilSaver.java    | 37 ++++++++++++++++------
 .../scala/org/apache/daffodil/DaffodilPlugin.scala | 22 ++++++-------
 2 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/src/main/java/org/apache/daffodil/DaffodilSaver.java 
b/src/main/java/org/apache/daffodil/DaffodilSaver.java
index ccb9d51..03e9a06 100644
--- a/src/main/java/org/apache/daffodil/DaffodilSaver.java
+++ b/src/main/java/org/apache/daffodil/DaffodilSaver.java
@@ -84,13 +84,24 @@ public class DaffodilSaver {
     Class<?> cString = String.class;
     Class<?> cWritableByteChannel = WritableByteChannel.class;
 
+    String baseApiPackage = null;
+    switch (apiVersion) {
+      case 1:
+      case 2:
+        baseApiPackage = "org.apache.daffodil.japi";
+        break;
+      case 3:
+        baseApiPackage = "org.apache.daffodil.api";
+        break;
+    }
+
     // get the Compiler, ProcessorFactory, and DataProcessor classes and the 
functions we need
     // to invoke on those classes. Note that we use JAPI because its easier to 
use via
     // reflection than the Scala API and it is much smaller and easier to use 
than the lib API
-    Class<?> daffodilClass = 
Class.forName("org.apache.daffodil.japi.Daffodil");
+    Class<?> daffodilClass = Class.forName(baseApiPackage + ".Daffodil");
     Method daffodilCompiler = daffodilClass.getMethod("compiler");
 
-    Class<?> compilerClass = 
Class.forName("org.apache.daffodil.japi.Compiler");
+    Class<?> compilerClass = Class.forName(baseApiPackage + ".Compiler");
     Method compilerWithTunable = compilerClass.getMethod("withTunable", 
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
@@ -101,20 +112,25 @@ public class DaffodilSaver {
         compilerCompile = compilerClass.getMethod("compileSource", cURI, 
cString, cString);
         break;
       case 2:
+      case 3:
         compilerCompile = compilerClass.getMethod("compileResource", cString, 
cString, cString);
         break;
     }
 
-    Class<?> processorFactoryClass = 
Class.forName("org.apache.daffodil.japi.ProcessorFactory");
+    Class<?> processorFactoryClass = Class.forName(baseApiPackage + 
".ProcessorFactory");
     Method processorFactoryIsError = 
processorFactoryClass.getMethod("isError");
     Method processorFactoryOnPath = processorFactoryClass.getMethod("onPath", 
cString);
     Method processorFactoryGetDiagnostics = 
processorFactoryClass.getMethod("getDiagnostics");
 
-    Class<?> dataProcessorClass = 
Class.forName("org.apache.daffodil.japi.DataProcessor");
+    Class<?> dataProcessorClass = Class.forName(baseApiPackage + 
".DataProcessor");
     Method dataProcessorIsError = dataProcessorClass.getMethod("isError");
     Method dataProcessorSave = dataProcessorClass.getMethod("save", 
cWritableByteChannel);
     Method dataProcessorGetDiagnostics = 
processorFactoryClass.getMethod("getDiagnostics");
 
+    Class<?> diagnosticClass = Class.forName(baseApiPackage + ".Diagnostic");
+    Method diagnosticIsError = diagnosticClass.getMethod("isError");
+    Method diagnosticToString = diagnosticClass.getMethod("toString");
+
     // val compiler = Daffodil.compiler()
     Object compiler = daffodilCompiler.invoke(null);
 
@@ -147,6 +163,7 @@ public class DaffodilSaver {
         schemaArg = schemaUrl.toURI();
         break;
       case 2:
+      case 3:
         schemaArg = schemaResource;
         break;
     }
@@ -154,7 +171,7 @@ public class DaffodilSaver {
 
     // val processorFactoryDiags = processorFactory.getDiagnostics()
     List<?> processorFactoryDiags = (List<?>) 
processorFactoryGetDiagnostics.invoke(processorFactory);
-    printDiagnostics(processorFactoryDiags);
+    printDiagnostics(processorFactoryDiags, diagnosticClass, 
diagnosticIsError, diagnosticToString);
 
     // if (processorFactory.isError) System.exit(1)
     if ((boolean) processorFactoryIsError.invoke(processorFactory)) 
System.exit(1);
@@ -164,7 +181,7 @@ public class DaffodilSaver {
 
     // val dataProcessorDiags = dataProcessor.getDiagnostics()
     List<?> dataProcessorDiags = (List<?>) 
dataProcessorGetDiagnostics.invoke(dataProcessor);
-    printDiagnostics(dataProcessorDiags);
+    printDiagnostics(dataProcessorDiags, diagnosticClass, diagnosticIsError, 
diagnosticToString);
 
     // if (dataProcessor.isError) System.exit(1)
     if ((boolean) dataProcessorIsError.invoke(dataProcessor)) System.exit(1);
@@ -176,10 +193,10 @@ public class DaffodilSaver {
   }
 
 
-  static private void printDiagnostics(List<?> diags) throws Exception {
-    Class<?> diagnosticClass = 
Class.forName("org.apache.daffodil.japi.Diagnostic");
-    Method diagnosticIsError = diagnosticClass.getMethod("isError");
-    Method diagnosticToString = diagnosticClass.getMethod("toString");
+  static private void printDiagnostics(List<?> diags,
+      Class<?> diagnosticClass,
+      Method diagnosticIsError,
+      Method diagnosticToString) throws Exception {
 
     for (Object d : diags) {
       String msg = (String) diagnosticToString.invoke(d);
diff --git a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala 
b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
index 35e4ccb..30d691d 100644
--- a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
+++ b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
@@ -187,7 +187,7 @@ object DaffodilPlugin extends AutoPlugin {
 
       // versions of scala each version of Daffodil was released with
       val daffodilToScalaVersion = Map(
-        ">=4.0.0" -> "3.3.5",
+        ">=4.0.0" -> "3.3.6",
         "=3.11.0" -> "2.13.16",
         "=3.10.0" -> "2.12.20",
         "=3.9.0 " -> "2.12.20",
@@ -346,17 +346,14 @@ object DaffodilPlugin extends AutoPlugin {
     libraryDependencies ++= {
       daffodilPackageBinVersions.value.flatMap { binDaffodilVersion =>
         val cfg = ivyConfigName(binDaffodilVersion)
-        // the daffodil-japi dependency must ignore the scalaVersion setting 
and instead use
-        // the specific version of scala used for the binDaffodilVersion. We 
can do this by
-        // defining the dependency with a "constant" cross version
-        val daffodilToCrossVersion = Map(
-          ">=4.0.0 " -> "3",
-          "=3.11.0 " -> "2.13",
-          "<=3.10.0" -> "2.12"
+        // the Daffodil dependency must ignore the scalaVersion setting and 
instead use
+        // the specific version of scala used for the binDaffodilVersion.
+        val daffodilToPackageBinDep = Map(
+          ">=4.0.0 " -> "org.apache.daffodil" % "daffodil-core_3" % 
binDaffodilVersion % cfg,
+          "=3.11.0 " -> "org.apache.daffodil" % "daffodil-japi_2.13" % 
binDaffodilVersion % cfg,
+          "<=3.10.0 " -> "org.apache.daffodil" % "daffodil-japi_2.12" % 
binDaffodilVersion % cfg
         )
-        val crossVersion = filterVersions(binDaffodilVersion, 
daffodilToCrossVersion).head
-        val dafDep = ("org.apache.daffodil" % "daffodil-japi" % 
binDaffodilVersion % cfg)
-          .withCrossVersion(CrossVersion.constant(crossVersion))
+        val dafDep = filterVersions(binDaffodilVersion, 
daffodilToPackageBinDep).head
         // Add logging backends used when packageDaffodilBin outputs log 
messages
         val daffodilToLogDependency = Map(
           ">=3.5.0" -> "org.slf4j" % "slf4j-simple" % "2.0.9" % cfg,
@@ -458,7 +455,8 @@ object DaffodilPlugin extends AutoPlugin {
             // 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",
+              ">=4.0.0" -> "3",
+              ">=3.9.0 <=3.11.0" -> "2",
               "<=3.8.0" -> "1"
             )
             val internalApiVersion =

Reply via email to