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

olabusayo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git


The following commit(s) were added to refs/heads/main by this push:
     new 667390d08 Add support for xerces validation on a saved parser
667390d08 is described below

commit 667390d0893352380a3c9f6b8de3e1893595aa96
Author: olabusayoT <[email protected]>
AuthorDate: Fri Aug 1 13:44:39 2025 -0400

    Add support for xerces validation on a saved parser
    
    - remove SerializableDataProcessor class as that is no longer needed
    - remove useSerializedProcessor since it's mostly true everywhere in the 
codebase
    - remove writeReplace so it serializes everything as expected, leaving it 
up to the users to remove non-serializable things
    - update save to remove non-serializable debugger
    - save diagnostics before save and reload in DaffodilTDMLDFDLProcessor. 
Always use serializedProcessor in TDMLRunner
    - add test to check order of scallop arguments
    - remove errors on using with saved parser
    - add tests for reloadable parsers using schematron and xerces validation
    - update cli documentation
    
    DAFFODIL-3007
---
 .../main/scala/org/apache/daffodil/cli/Main.scala  | 40 ++++-------
 .../daffodil/cli/cliTest/TestCLISaveParser.scala   | 27 +++++---
 .../cli/cliTest/schematron/TestValidating.scala    | 54 +++++++++++++++
 .../org/apache/daffodil/api/DataProcessor.java     |  3 +-
 .../org/apache/daffodil/core/util/TestUtils.scala  | 29 ++++----
 .../runtime1/processors/DataProcessor.scala        | 62 ++---------------
 .../java/org/apache/daffodil/jexample/TestAPI.java | 13 ++--
 .../org/apache/daffodil/sexample/TestAPI.scala     | 79 ++++++++++------------
 .../org/apache/daffodil/tdml/TDMLRunner.scala      | 11 ---
 .../tdml/processor/TDMLDFDLProcessor.scala         |  1 -
 .../tdml/DaffodilCTDMLDFDLProcessor.scala          |  1 -
 .../processor/tdml/DaffodilTDMLDFDLProcessor.scala | 41 ++++-------
 .../daffodil/processor/tdml/TestDaffodilC.scala    |  2 -
 project/Dependencies.scala                         |  2 +-
 14 files changed, 159 insertions(+), 206 deletions(-)

diff --git a/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala 
b/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala
index 7fe4d24ac..d29d8a97d 100644
--- a/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala
+++ b/daffodil-cli/src/main/scala/org/apache/daffodil/cli/Main.scala
@@ -169,24 +169,12 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
     singleArgConverter[(String, Option[URI])]((s: String) => {
       import ValidatorPatterns._
 
-      def doesNotSupportReloadableParsers(name: String): Boolean =
-        // TODO: DAFFODIL-1749, this will change once ticket is implemented
-        schema.isEmpty && parser.isDefined && !Seq("limited", 
"off").exists(_.contains(name))
-
       s match {
         case DefaultArgPattern(name, arg) =>
-          if (doesNotSupportReloadableParsers(name)) {
-            null // validateOpt will cause null to output an appropriate error 
message
-          } else {
-            val uri = fileResourceToURI(arg).uri
-            (name, Some(uri))
-          }
+          val uri = fileResourceToURI(arg).uri
+          (name, Some(uri))
         case NoArgsPattern(name) =>
-          if (doesNotSupportReloadableParsers(name)) {
-            null // validateOpt will cause null to output an appropriate error 
message
-          } else {
-            (name, schema.map(_.uri).toOption)
-          }
+          (name, schema.map(_.uri).toOption)
         case _ =>
           throw new Exception(
             "Unrecognized Validator name %s.  Must be 'xerces', 'limited', 
'off', or name of spi validator."
@@ -427,8 +415,9 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
       argName = "validator_name",
       descr =
         "Validator name. Use 'off', 'limited', 'xerces[=value]', 
'schematron[=value]', or a " +
-          "custom validator_name[=value]. The optional value paramter provides 
a file to the " +
-          "validator (e.g. .xsd, .sch, .conf, .properties) used for validator 
configuration."
+          "custom validator_name[=value]. The optional value parameter 
provides a file to the " +
+          "validator (e.g. .xsd, .sch, .conf, .properties) used for validator 
configuration. " +
+          "If using --parser, some validators may require a config file 
specified."
     )(validateConverter(schema, parser))
     val debug = opt[Option[String]](
       argName = "file",
@@ -463,12 +452,6 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
       case _ => Right(())
     }
 
-    validateOpt(parser, validate) {
-      case (Some(_), Some(null)) =>
-        Left("The validation name must be 'limited' or 'off' when using a 
saved parser.")
-      case _ => Right(())
-    }
-
     validateOpt(infosetType, stream, schema) {
       case (Some(InfosetType.EXI), Some(true), _) =>
         Left("Streaming mode is not currently supported with EXI infosets.")
@@ -557,8 +540,10 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
       argName = "validator_name",
       descr =
         "Validator name. Use 'off', 'limited', 'xerces[=value]', 
'schematron[=value]', or a " +
-          "custom validator_name[=value]. The optional value paramter provides 
a file to the " +
-          "validator (e.g. .xsd, .sch, .conf, .properties) used for validator 
configuration."
+          "custom validator_name[=value]. The optional value parameter 
provides a file to the " +
+          "validator (e.g. .xsd, .sch, .conf, .properties) used for validator 
configuration. " +
+          "If using --parser, some validators may require a config file 
specified. Note that " +
+          "using this flag doesn't use the created validator as unparse 
validation is currently unsupported."
     )(validateConverter(schema, parser))
     val debug = opt[Option[String]](
       argName = "file",
@@ -792,8 +777,9 @@ class CLIConf(arguments: Array[String], stdout: 
PrintStream, stderr: PrintStream
       argName = "validator_name",
       descr =
         "Validator name. Use 'off', 'limited', 'xerces[=value]', 
'schematron[=value]', or a " +
-          "custom validator_name[=value]. The optional value paramter provides 
a file to the " +
-          "validator (e.g. .xsd, .sch, .conf, .properties) used for validator 
configuration."
+          "custom validator_name[=value]. The optional value parameter 
provides a file to the " +
+          "validator (e.g. .xsd, .sch, .conf, .properties) used for validator 
configuration. " +
+          "If using --parser, some validators may require a config file 
specified."
     )(validateConverter(schema, parser))
 
     val infile = trailArg[String](
diff --git 
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
 
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
index 7e38f6e0e..8266d420e 100644
--- 
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
+++ 
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLISaveParser.scala
@@ -164,7 +164,7 @@ class TestCLISaveParser {
     }
   }
 
-  @Test def test_CLI_DFDL_1205_FullValidation_SavedParser_Incompatible(): Unit 
= {
+  @Test def test_CLI_DFDL_1205_FullValidation_SavedParser(): Unit = {
     val schema = path(
       
"daffodil-cli/src/test/resources/org/apache/daffodil/cli/charClassEntities.dfdl.xsd"
     )
@@ -176,11 +176,16 @@ class TestCLISaveParser {
       )
 
       runCLI(args"parse --parser $parser --validate xerces $input") { cli =>
-        cli.expectErr("[error]")
-        cli.expectErr(
-          "The validation name must be 'limited' or 'off' when using a saved 
parser."
-        )
-      }(ExitCode.Usage)
+        cli.expectErr("xerces property is empty or not defined")
+      }(
+        ExitCode.UnableToCreateValidatorError
+      )
+
+      runCLI(args"parse --validate xerces $input --parser $parser") { cli =>
+        cli.expectErr("xerces property is empty or not defined")
+      }(
+        ExitCode.UnableToCreateValidatorError
+      )
     }
   }
 
@@ -231,8 +236,14 @@ class TestCLISaveParser {
 
       runCLI(args"parse --validate xerces -P $parser") { cli =>
         cli.send("test", inputDone = true)
-        cli.expectErr("validation name must be 'limited' or 'off' when using a 
saved parser.")
-      }(ExitCode.Usage)
+        cli.expectErr("xerces property is empty or not defined")
+      }(ExitCode.UnableToCreateValidatorError)
+
+      runCLI(args"parse --validate xerces=$schema -P $parser") { cli =>
+        cli.send("test", inputDone = true)
+        cli.expectErr("[error] Validation Error")
+        cli.expectErr("not valid")
+      }(ExitCode.ParseError)
     }
   }
 
diff --git 
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/schematron/TestValidating.scala
 
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/schematron/TestValidating.scala
index 5a62cda13..e0aa06dea 100644
--- 
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/schematron/TestValidating.scala
+++ 
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/schematron/TestValidating.scala
@@ -46,6 +46,34 @@ class TestValidating {
     }(ExitCode.ParseError)
   }
 
+  // always fails sch, with validate flag should fail
+  @Test def failShouldFail_reloadable_parser(): Unit = {
+    val schema = 
path("daffodil-schematron/src/test/resources/xsd/string.dfdl.xsd")
+    val schematron = 
path("daffodil-schematron/src/test/resources/sch/always-fails.sch")
+    val input = 
path("daffodil-cli/src/test/resources/org/apache/daffodil/cli/input/uuid.txt")
+
+    runCLI(args"""parse --validate schematron=$schematron -s $schema 
$input""") { cli =>
+      
cli.expect("<never-fails>2f6481e6-542c-11eb-ae93-0242ac130002</never-fails>")
+      cli.expectErr("[error] Validation Error: never fails")
+    }(ExitCode.ParseError)
+
+    // test reloadable parser
+    withTempFile { parser =>
+      runCLI(args"save-parser -s $schema $parser") { _ => }(
+        ExitCode.Success
+      )
+
+      runCLI(args"""parse --validate schematron -P $parser $input""") { cli =>
+        cli.expectErr("schematron property is empty or not defined")
+      }(ExitCode.UnableToCreateValidatorError)
+
+      runCLI(args"""parse --validate schematron=$schematron -P $parser 
$input""") { cli =>
+        
cli.expect("<never-fails>2f6481e6-542c-11eb-ae93-0242ac130002</never-fails>")
+        cli.expectErr("[error] Validation Error: never fails")
+      }(ExitCode.ParseError)
+    }
+  }
+
   // never fails sch, with validate flag should pass
   @Test def passShouldPass(): Unit = {
     val schema = 
path("daffodil-schematron/src/test/resources/xsd/string.dfdl.xsd")
@@ -57,6 +85,32 @@ class TestValidating {
     }(ExitCode.Success)
   }
 
+  // never fails sch, with validate flag should pass
+  @Test def passShouldPass_reloadable_parser(): Unit = {
+    val schema = 
path("daffodil-schematron/src/test/resources/xsd/string.dfdl.xsd")
+    val schematron = 
path("daffodil-schematron/src/test/resources/sch/never-fails.sch")
+    val input = 
path("daffodil-cli/src/test/resources/org/apache/daffodil/cli/input/uuid.txt")
+
+    runCLI(args"""parse --validate schematron=$schematron -s $schema 
$input""") { cli =>
+      
cli.expect("<never-fails>2f6481e6-542c-11eb-ae93-0242ac130002</never-fails>")
+    }(ExitCode.Success)
+
+    // test reloadable parser
+    withTempFile { parser =>
+      runCLI(args"save-parser -s $schema $parser") { _ => }(
+        ExitCode.Success
+      )
+
+      runCLI(args"""parse --validate schematron -P $parser $input""") { cli =>
+        cli.expectErr("schematron property is empty or not defined")
+      }(ExitCode.UnableToCreateValidatorError)
+
+      runCLI(args"""parse --validate schematron=$schematron -P $parser 
$input""") { cli =>
+        
cli.expect("<never-fails>2f6481e6-542c-11eb-ae93-0242ac130002</never-fails>")
+      }(ExitCode.Success)
+    }
+  }
+
   // fails to resolve included schema
   @Test def failToResolve(): Unit = {
     val schema = 
path("daffodil-schematron/src/test/resources/xsd/string.dfdl.xsd")
diff --git 
a/daffodil-core/src/main/java/org/apache/daffodil/api/DataProcessor.java 
b/daffodil-core/src/main/java/org/apache/daffodil/api/DataProcessor.java
index 8f5c55bde..d78b578ce 100644
--- a/daffodil-core/src/main/java/org/apache/daffodil/api/DataProcessor.java
+++ b/daffodil-core/src/main/java/org/apache/daffodil/api/DataProcessor.java
@@ -143,7 +143,8 @@ public interface DataProcessor extends WithDiagnostics, 
Serializable {
    * Save the DataProcessor
    * <p>
    * The resulting output can be reloaded by {@code 
Compiler.reload(savedParser:java\.nio\.channels\.ReadableByteChannel)* 
Compiler.reload}.
-   *
+   * Note that any changes due to withValidator, withDebugger, and any compile 
diagnostics are not saved
+   * 
    * @param output the byte channel to write the {@link DataProcessor} to. 
Note that external variable settings are not saved.
    */
   void save(WritableByteChannel output);
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/util/TestUtils.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/util/TestUtils.scala
index 6e575b047..774341acf 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/core/util/TestUtils.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/util/TestUtils.scala
@@ -115,8 +115,6 @@ object TestUtils {
     runSchemaOnRBC(testSchema, rbc, areTracing)
   }
 
-  private val useSerializedProcessor = true
-
   def testUnparsing(
     testSchema: scala.xml.Elem,
     infosetXML: Node,
@@ -182,21 +180,18 @@ object TestUtils {
     )
 
   private def saveAndReload(p: DataProcessor): DataProcessor = {
-    if (this.useSerializedProcessor) {
-      //
-      // We want to serialize/deserialize here, to avoid strange debug 
artifacts
-      // like where schema compilation is still happening at runtime (and
-      // therefore generating lots of Debug messages to the log)
-      //
-      val os = new java.io.ByteArrayOutputStream()
-      val output = Channels.newChannel(os)
-      p.save(output)
-
-      val is = new java.io.ByteArrayInputStream(os.toByteArray)
-      val input = Channels.newChannel(is)
-      val compiler_ = Compiler()
-      compiler_.reload(input).asInstanceOf[DataProcessor]
-    } else p
+    // We want to serialize/deserialize here, to avoid strange debug artifacts
+    // like where schema compilation is still happening at runtime (and
+    // therefore generating lots of Debug messages to the log)
+    //
+    val os = new java.io.ByteArrayOutputStream()
+    val output = Channels.newChannel(os)
+    p.save(output)
+
+    val is = new java.io.ByteArrayInputStream(os.toByteArray)
+    val input = Channels.newChannel(is)
+    val compiler_ = Compiler()
+    compiler_.reload(input).asInstanceOf[DataProcessor]
   }
 
   def compileSchema(testSchema: Node) = {
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/DataProcessor.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/DataProcessor.scala
index 8956dc091..352b0d0f9 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/DataProcessor.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/processors/DataProcessor.scala
@@ -83,42 +83,6 @@ trait WithDiagnosticsImpl extends WithDiagnostics {
 class InvalidUsageException(msg: String, cause: Throwable = null)
   extends api.exceptions.InvalidUsageException(msg, cause)
 
-object DataProcessor {
-
-  /**
-   * This is the SerializableDataProcessor constructed from a saved processor.
-   *
-   * It enables us to implement restrictions on what you can/cannot do with a 
reloaded
-   * processor versus an original one.
-   *
-   * When we reload a processor, we want it to have default values for 
everything settable
-   * like debug mode and debugger.
-   *
-   * Note that this class does preserve variableMap. That is because
-   * serializations other than our own save/reload may need such settings 
(e.g., Apache Spark
-   * which serializes to move objects for remote execution).
-   *
-   * Hence, we're depending on the save method to explicitly reset them to 
default values.
-   */
-  private class SerializableDataProcessor(
-    ssrd: SchemaSetRuntimeData,
-    tunables: DaffodilTunables,
-    variableMap: VariableMap // must be explicitly reset by save method
-  ) extends DataProcessor(ssrd, tunables, variableMap) {
-
-    override def withValidation(kind: String, config: URI): api.DataProcessor 
= {
-      if (kind == DaffodilLimitedValidator.name || kind == NoValidator.name) {
-        super.withValidation(kind, config)
-      } else {
-        throw new InvalidUsageException(
-          "Only Limited/No validation allowed when using a restored parser."
-        )
-      }
-    }
-  }
-
-}
-
 /**
  * The very last aspects of compilation, and the start of the
  * back-end runtime.
@@ -137,27 +101,6 @@ class DataProcessor(
   with Serializable
   with MultipleEventHandler {
 
-  import DataProcessor.SerializableDataProcessor
-
-  /**
-   * In order to make this serializable, without serializing the unwanted 
current state of
-   * debugging mode, debugger, etc. we replace, at serialization time, this
-   * object with a [[SerializableDataProcessor]] which is a private derived 
class that
-   * sets all these troublesome slots back to the default values.
-   *
-   * But note: there is serialization for us to save/reload, and there is 
serialization
-   * in other contexts like Apache Spark, which may serialize objects without 
notifying us.
-   *
-   * So we preserve everything that something like Spark might need preserved
-   * and reinitialize things that are *always* reinitialized e.g., debugger, 
areDebugging.
-   *
-   * @throws java.io.ObjectStreamException Must be part of writeReplace's API
-   * @return the serializable object
-   */
-  @throws(classOf[java.io.ObjectStreamException])
-  private def writeReplace(): Object =
-    new SerializableDataProcessor(ssrd, tunables, variableMap.copy())
-
   def copy(
     ssrd: SchemaSetRuntimeData = ssrd,
     tunables: DaffodilTunables = tunables,
@@ -286,7 +229,10 @@ class DataProcessor(
       variableMap = ssrd.originalVariables,
       validator = NoValidator,
       // don't save any warnings that were generated
-      diagnostics = Seq.empty
+      diagnostics = Seq.empty,
+      // disable debugger if provided
+      areDebugging = false,
+      optDebugger = None
     )
 
     try {
diff --git 
a/daffodil-core/src/test/java/org/apache/daffodil/jexample/TestAPI.java 
b/daffodil-core/src/test/java/org/apache/daffodil/jexample/TestAPI.java
index 022e951cc..7f24dffd5 100644
--- a/daffodil-core/src/test/java/org/apache/daffodil/jexample/TestAPI.java
+++ b/daffodil-core/src/test/java/org/apache/daffodil/jexample/TestAPI.java
@@ -20,6 +20,7 @@ package org.apache.daffodil.jexample;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -222,7 +223,7 @@ public class TestAPI {
   // This is a duplicate of test testAPI1 that serializes the parser
   // before executing the test.
   @Test
-  public void testAPI1_A_FullFails() throws Exception {
+  public void testAPI1_A_Full_SavedParser() throws Exception {
     DebuggerRunnerForAPITest debugger = new DebuggerRunnerForAPITest();
 
     org.apache.daffodil.api.Compiler c = Daffodil.compiler();
@@ -241,13 +242,9 @@ public class TestAPI {
     ReadableByteChannel input = Channels.newChannel(is);
     org.apache.daffodil.api.Compiler compiler = Daffodil.compiler();
     DataProcessor parser = compiler.reload(input);
-
-    try {
-      parser = parser.withValidation("xerces", schemaFile.toURI());
-      fail();
-    } catch (InvalidUsageException e) {
-      assertEquals("Only Limited/No validation allowed when using a restored 
parser.", e.getMessage());
-    }
+    assertNotNull(schemaFile);
+    parser = parser.withValidation("xerces", schemaFile.toURI());
+    assertNotNull(parser);
   }
 
   @Test
diff --git 
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/TestAPI.scala 
b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/TestAPI.scala
index 219ae84a3..e195a54bb 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/TestAPI.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/TestAPI.scala
@@ -41,7 +41,6 @@ import org.apache.daffodil.api.ParseResult
 import org.apache.daffodil.api.exceptions.DaffodilUnhandledSAXException
 import org.apache.daffodil.api.exceptions.DaffodilUnparseErrorSAXException
 import org.apache.daffodil.api.exceptions.ExternalVariableException
-import org.apache.daffodil.api.exceptions.InvalidUsageException
 import org.apache.daffodil.api.infoset.Infoset
 import org.apache.daffodil.api.infoset.XMLTextEscapeStyle
 import org.apache.daffodil.lib.exceptions.UsageException
@@ -51,8 +50,8 @@ import org.apache.commons.io.FileUtils
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
 import org.junit.Test
 import org.xml.sax.XMLReader
 
@@ -132,7 +131,7 @@ class TestAPI {
         try {
           Class.forName(desc.getName, false, getClass.getClassLoader)
         } catch {
-          case e: ClassNotFoundException => super.resolveClass(desc);
+          case e: ClassNotFoundException => super.resolveClass(desc)
         }
       }
     }
@@ -172,9 +171,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("42", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("42", bos.toString())
     }
   }
   // This is a duplicate of test testAPI1 that serializes the parser
@@ -225,9 +224,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("42", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("42", bos.toString())
     }
   }
   @Test
@@ -297,9 +296,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("9", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("9", bos.toString())
     }
   }
   // This is a duplicate of test testAPI3 that serializes the parser
@@ -338,9 +337,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("9", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("9", bos.toString())
     }
   }
   @Test
@@ -366,9 +365,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("data", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("data", bos.toString())
     }
   }
   @Test
@@ -400,9 +399,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("data", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("data", bos.toString())
     }
   }
 
@@ -492,8 +491,8 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
+      val err2 = res2.isError()
+      assertFalse(err2)
       assertTrue(bos.toString().contains("Return-Path: <[email protected]>"))
     }
   }
@@ -525,8 +524,8 @@ class TestAPI {
       val wbc1 = java.nio.channels.Channels.newChannel(bos1)
       val inputter1 = Infoset.getScalaXMLInfosetInputter(node1)
       val res2 = dp.unparse(inputter1, wbc1)
-      val err2 = res2.isError();
-      assertFalse(err2);
+      val err2 = res2.isError()
+      assertFalse(err2)
       assertTrue(bos1.toString().contains("Return-Path: <[email protected]>"))
 
       val node2 = outputter.getResult()
@@ -535,8 +534,8 @@ class TestAPI {
       val wbc2 = java.nio.channels.Channels.newChannel(bos2)
       val inputter2 = Infoset.getScalaXMLInfosetInputter(node2)
       val res3 = dp.unparse(inputter2, wbc2)
-      val err3 = res3.isError();
-      assertFalse(err3);
+      val err3 = res3.isError()
+      assertFalse(err3)
       assertTrue(bos2.toString().contains("Return-Path: <[email protected]>"))
     }
   }
@@ -701,10 +700,11 @@ class TestAPI {
   }
   // This is a duplicate of test testAPI1 that serializes the parser
   // before executing the test.
-  // Demonstrates that setting validation to Full for a saved parser fails.
+  // Demonstrates that setting validation to xerces for a saved parser
+  // does not fail.
   //
   @Test
-  def testAPI1_A_FullFails(): Unit = {
+  def testAPI1_A_Full_SavedParser(): Unit = {
     val debugger = new DebuggerRunnerForAPITest()
 
     val c = Daffodil.compiler()
@@ -724,17 +724,8 @@ class TestAPI {
     val input = Channels.newChannel(is)
     val compiler = Daffodil.compiler()
     val parser = compiler.reload(input)
-
-    try {
-      parser.withValidation("xerces", schemaFile.toURI)
-      fail()
-    } catch {
-      case e: InvalidUsageException =>
-        assertEquals(
-          "Only Limited/No validation allowed when using a restored parser.",
-          e.getMessage
-        )
-    }
+    val p = parser.withValidation("xerces", schemaFile.toURI)
+    assertNotNull(p)
   }
 
   @Test
@@ -762,7 +753,7 @@ class TestAPI {
 
     val diags = res.getDiagnostics
     assertEquals(1, diags.size)
-    val d = diags.get(0);
+    val d = diags.get(0)
     assertTrue(d.getMessage.contains("wrong"))
     assertTrue(d.getMessage.contains("e2"))
   }
@@ -1368,9 +1359,9 @@ class TestAPI {
       val wbc = java.nio.channels.Channels.newChannel(bos)
       val inputter = Infoset.getScalaXMLInfosetInputter(outputter.getResult())
       val res2 = dp.unparse(inputter, wbc)
-      val err2 = res2.isError();
-      assertFalse(err2);
-      assertEquals("9100", bos.toString());
+      val err2 = res2.isError()
+      assertFalse(err2)
+      assertEquals("9100", bos.toString())
     }
   }
 
diff --git 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
index f1bdd391b..91d72a08c 100644
--- a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
+++ b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
@@ -553,7 +553,6 @@ class DFDLTestSuite private[tdml] (
   def getCompileResult(
     impl: AbstractTDMLDFDLProcessorFactory,
     suppliedSchema: DaffodilSchemaSource,
-    useSerializedProcessor: Boolean,
     optRootName: Option[String],
     optRootNamespace: Option[String],
     tunables: Map[String, String]
@@ -562,7 +561,6 @@ class DFDLTestSuite private[tdml] (
     val key = TDMLCompileResultCacheKey(
       impl.implementationName,
       suppliedSchema,
-      useSerializedProcessor,
       optRootName,
       optRootNamespace,
       tunables
@@ -934,18 +932,11 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: 
DFDLTestSuite) {
         _.nBits
       }
 
-      val useSerializedProcessor =
-        if (validation == "on") false
-        else if (defaultValidation == "on") false
-        else if (optExpectedWarnings.isDefined) false
-        else true
-
       val rootNamespaceString = getRootNamespaceString()
 
       val compileResult: TDML.CompileResult = parent.getCompileResult(
         impl,
         suppliedSchema,
-        useSerializedProcessor,
         Option(rootName),
         Option(rootNamespaceString),
         tunables
@@ -3014,7 +3005,6 @@ object UTF8Encoder {
 case class TDMLCompileResultCacheKey(
   impl: String,
   suppliedSchema: DaffodilSchemaSource,
-  useSerializedProcessor: Boolean,
   optRootName: Option[String],
   optRootNamespace: Option[String],
   tunables: Map[String, String]
@@ -3102,7 +3092,6 @@ case class 
TDMLCompileResultCache(entryExpireDurationSeconds: Option[Long]) {
     } else {
       val compileResult = impl.getProcessor(
         key.suppliedSchema,
-        key.useSerializedProcessor,
         key.optRootName,
         key.optRootNamespace,
         key.tunables
diff --git 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/processor/TDMLDFDLProcessor.scala
 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/processor/TDMLDFDLProcessor.scala
index d64e35779..072093204 100644
--- 
a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/processor/TDMLDFDLProcessor.scala
+++ 
b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/processor/TDMLDFDLProcessor.scala
@@ -57,7 +57,6 @@ trait AbstractTDMLDFDLProcessorFactory {
 
   def getProcessor(
     schemaSource: DaffodilSchemaSource,
-    useSerializedProcessor: Boolean,
     optRootName: Option[String] = None,
     optRootNamespace: Option[String] = None,
     tunables: Map[String, String]
diff --git 
a/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilCTDMLDFDLProcessor.scala
 
b/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilCTDMLDFDLProcessor.scala
index e707583ba..ff07cdbdd 100644
--- 
a/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilCTDMLDFDLProcessor.scala
+++ 
b/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilCTDMLDFDLProcessor.scala
@@ -72,7 +72,6 @@ final class DaffodilCTDMLDFDLProcessorFactory(compiler: 
Compiler)
   // schema (only diagnostics on left, or processor too on right)
   override def getProcessor(
     schemaSource: DaffodilSchemaSource,
-    useSerializedProcessor: Boolean,
     optRootName: Option[String] = None,
     optRootNamespace: Option[String] = None,
     tunables: Map[String, String]
diff --git 
a/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilTDMLDFDLProcessor.scala
 
b/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilTDMLDFDLProcessor.scala
index 4b46739e2..5089a803e 100644
--- 
a/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilTDMLDFDLProcessor.scala
+++ 
b/daffodil-tdml-processor/src/main/scala/org/apache/daffodil/processor/tdml/DaffodilTDMLDFDLProcessor.scala
@@ -105,35 +105,27 @@ final class TDMLDFDLProcessorFactory private (
    */
   private def generateProcessor(
     pf: DFDL.ProcessorFactory,
-    useSerializedProcessor: Boolean,
     schemaSource: DaffodilSchemaSource
   ): TDML.CompileResult = {
     val p = pf.onPath("/")
+    val diags = p.getDiagnostics
     if (p.isError) {
-      val diags = p.getDiagnostics
       Left(diags)
     } else {
       val dp = {
-        if (useSerializedProcessor) {
-          val os = new java.io.ByteArrayOutputStream()
-          val output = Channels.newChannel(os)
-          p.save(output)
-          val is = new java.io.ByteArrayInputStream(os.toByteArray)
-          compiler.reload(is)
-        } else p
+        val os = new java.io.ByteArrayOutputStream()
+        val output = Channels.newChannel(os)
+        p.save(output)
+        val is = new java.io.ByteArrayInputStream(os.toByteArray)
+        compiler.reload(is)
       }
-      val diags = p.getDiagnostics
-      val processor = new DaffodilTDMLDFDLProcessor(
-        dp.asInstanceOf[DFDL.DataProcessor],
-        schemaSource.uriForLoading
-      )
+      val processor = new DaffodilTDMLDFDLProcessor(dp, 
schemaSource.uriForLoading)
       Right(diags, processor)
     }
   }
 
   private def compileProcessor(
     schemaSource: DaffodilSchemaSource,
-    useSerializedProcessor: Boolean,
     optRootName: Option[String],
     optRootNamespace: Option[String]
   ): TDML.CompileResult = {
@@ -142,44 +134,39 @@ final class TDMLDFDLProcessorFactory private (
       val diags = pf.getDiagnostics
       Left(diags)
     } else {
-      val res = this.generateProcessor(pf, useSerializedProcessor, 
schemaSource)
+      val res = this.generateProcessor(pf, schemaSource)
       res
     }
   }
 
   override def getProcessor(
     schemaSource: DaffodilSchemaSource,
-    useSerializedProcessor: Boolean,
     optRootName: Option[String],
     optRootNamespace: Option[String],
     tunables: Map[String, String]
   ): TDML.CompileResult = {
     if (schemaSource.isXSD) {
       val res =
-        compileProcessor(schemaSource, useSerializedProcessor, optRootName, 
optRootNamespace)
+        compileProcessor(schemaSource, optRootName, optRootNamespace)
       res
     } else {
       val dp = compiler.reload(schemaSource)
       val diags = dp.getDiagnostics
       Assert.invariant(diags.asScala.forall { !_.isError })
-      val processor = new DaffodilTDMLDFDLProcessor(
-        dp.asInstanceOf[DFDL.DataProcessor],
-        schemaSource.uriForLoading
-      )
+      val processor = new DaffodilTDMLDFDLProcessor(dp, 
schemaSource.uriForLoading)
       Right(diags, processor)
     }
   }
 
 }
 
-class DaffodilTDMLDFDLProcessor private (private var dp: api.DataProcessor, 
schemaURI: URI)
-  extends TDMLDFDLProcessor {
+class DaffodilTDMLDFDLProcessor private[tdml] (
+  private var dp: api.DataProcessor,
+  schemaURI: URI
+) extends TDMLDFDLProcessor {
 
   override type R = DaffodilTDMLDFDLProcessor
 
-  def this(ddp: DFDL.DataProcessor, schemaURI: URI) =
-    this(ddp.asInstanceOf[api.DataProcessor], schemaURI)
-
   private def copy(dp: api.DataProcessor = dp) = new 
DaffodilTDMLDFDLProcessor(dp, schemaURI)
 
   private lazy val builtInTracer =
diff --git 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestDaffodilC.scala
 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestDaffodilC.scala
index 7c025383a..33aeed2dd 100644
--- 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestDaffodilC.scala
+++ 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestDaffodilC.scala
@@ -214,13 +214,11 @@ class TestDaffodilC {
     val processorFactory = new DaffodilCTDMLDFDLProcessorFactory()
     val schemaSource =
       UnitTestSchemaSource(testSchema, nameHint = "getProcessor", 
Some(tempDir.toIO))
-    val useSerializedProcessor = false
     val optRootName = None
     val optRootNamespace = None
     val tunables = Map.empty[String, String]
     val cr = processorFactory.getProcessor(
       schemaSource,
-      useSerializedProcessor,
       optRootName,
       optRootNamespace,
       tunables
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index 07bb89923..002729aec 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import sbt.*
+import sbt._
 
 object Dependencies {
 


Reply via email to