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.git
The following commit(s) were added to refs/heads/main by this push:
new 081151258 Simplify validation API
081151258 is described below
commit 0811512580493aceca4b7b536790d792178f9b90
Author: Steve Lawrence <[email protected]>
AuthorDate: Thu Jul 31 08:57:36 2025 -0400
Simplify validation API
The currently validator API supports all the features needed to support
our existing and custom validators. However, it does add extra
complication, since API users must create a Properties instance, find
the ValidatorFactory, use that and the Properties to create a Validator,
and provide that Validator to the DataProcessor. Although this provides
much flexibility, it is flexibility that API users rarely need.
The new API is now `DataProcessor.withValidation(String, URI)` where the
String is the name of a validator to use (looked up via SPI), and the
URI is either a properties file or a file that the Validator can use for
validation (e.g. XSD for "xerces", .sch or XSD with embedded schematron
rules for "schematron"). This new function uses those parameters and the
existing ValidatorFactory API to create and assign the validator to the
DataProcessor.
Additional changes include:
- The converter in Main.scala no longer creates a validator, instead it
just parses the validation option into a `(String, Option[URI])` that
is passed to the new withValidation function. This means creating the
validator can fail when withValidation is called (e.g. if the
validator does not exist) and so the CLI adds new exit codes to handle
the possible validation failures. If the optional validator value is
not provided, we provide the DFDL schema as the URI.
- The CLI was setting the validator twice, when when creating the
processor and again when setting variables/debug/etc. This removes the
duplicates.
- The daffodil.rootSchema property cannot be needed now, since
withValidation doesn't know if the provided URI is actually the DFDL
schema. Instead, validators now only use properties specific to the
validator.
- makeValidator can never get a null Properties instance now, so the
null check is removed
- We now require that validators are found via SPI. Two tests are
removed that explicitly tested non-SPI behavior.
- Add a missing catch if schematron fails to read the .sch file.
Previously this would throw a generic exception caught by scallop when
creating the validator, but it really should be caught by the
SchematronValidator and returned as an initialization exception.
- The TDMLRunner is modified so it only ever knows about "on", "limited"
and "off" validation modes. It then passes those unmodified strings
directly to the TDMLDFDLProcessor implementation, which must convert
the to whatever the implementation uses for validation. The
DaffodilTDMLDFDLProcessor now keeps track of the schema URI and uses
the new DataProcessor.withValidation, passing in the validation mode
(converting "on" to "xerces") and the schema URI.
- The validation package-info.java file is changed to focus on the
validator names and properties instead of the implementations, since
users don't really need to care about ValidatorFactories's or
Validators as much with the new API
DAFFODIL-3013
---
.../main/scala/org/apache/daffodil/cli/Main.scala | 102 ++++++------
.../daffodil/cli/cliTest/TestCLIParsing.scala | 2 +-
.../cli/cliTest/schematron/TestValidating.scala | 4 +-
.../org/apache/daffodil/api/DataProcessor.java | 36 ++++-
.../apache/daffodil/api/validation/Validator.java | 4 -
.../daffodil/api/validation/ValidatorFactory.java | 12 --
.../daffodil/api/validation/package-info.java | 179 +++++++++++----------
.../org/apache/daffodil/core/util/TestUtils.scala | 14 +-
.../runtime1/processors/DataProcessor.scala | 26 ++-
.../validation/DaffodilLimitedValidator.scala | 4 +-
.../apache/daffodil/validation/NoValidator.scala | 4 +-
.../daffodil/validation/XercesValidator.scala | 13 +-
.../java/org/apache/daffodil/jexample/TestAPI.java | 16 +-
.../daffodil/jexample/ValidatorApiExample.java | 8 +-
.../daffodil/jexample/ValidatorSpiExample.java | 9 +-
.../lib/validation/TestValidatorsSPI.scala | 7 +-
.../lib/validation/TestXercesValidator.scala | 9 +-
.../org/apache/daffodil/sexample/TestAPI.scala | 43 ++---
.../daffodil/sexample/ValidatorApiExample.scala | 42 -----
.../sexample/ValidatorExamplesSupport.scala | 15 --
.../daffodil/sexample/ValidatorSpiExample.scala | 10 +-
.../schematron/SchematronValidatorFactory.scala | 29 ++--
.../validation/schematron/EmbeddedTesting.scala | 8 +-
.../org/apache/daffodil/tdml/TDMLRunner.scala | 55 +++----
.../tdml/processor/TDMLDFDLProcessor.scala | 2 +-
.../tdml/DaffodilCTDMLDFDLProcessor.scala | 2 +-
.../processor/tdml/DaffodilTDMLDFDLProcessor.scala | 36 +++--
.../apache/daffodil/infoset/TestStringAsXml.scala | 12 +-
28 files changed, 301 insertions(+), 402 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 9620497a0..7fe4d24ac 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
@@ -29,7 +29,6 @@ import java.nio.channels.FileChannel
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardOpenOption
-import java.util.Properties
import java.util.Scanner
import java.util.concurrent.Executors
import javax.xml.parsers.SAXParserFactory
@@ -48,8 +47,8 @@ import scala.util.matching.Regex
import org.apache.daffodil.api
import org.apache.daffodil.api.debugger.InteractiveDebuggerRunnerFactory
import org.apache.daffodil.api.exceptions.InvalidParserException
-import org.apache.daffodil.api.validation.ValidatorFactory
-import org.apache.daffodil.api.validation.Validators
+import org.apache.daffodil.api.validation.ValidatorInitializationException
+import org.apache.daffodil.api.validation.ValidatorNotRegisteredException
import org.apache.daffodil.cli.debugger.CLIDebuggerRunner
import org.apache.daffodil.core.compiler.Compiler
import org.apache.daffodil.core.dsom.ExpressionCompilers
@@ -86,7 +85,6 @@ import org.apache.daffodil.slf4j.DaffodilLogger
import org.apache.daffodil.tdml.Runner
import org.apache.daffodil.tdml.TDMLException
import org.apache.daffodil.tdml.TDMLTestNotCompatibleException
-import org.apache.daffodil.validation.NoValidator
import com.siemens.ct.exi.core.EXIFactory
import com.siemens.ct.exi.core.exceptions.EXIException
@@ -167,40 +165,27 @@ class CLIConf(arguments: Array[String], stdout:
PrintStream, stderr: PrintStream
def validateConverter(
schema: ScallopOption[URISchemaSource],
parser: ScallopOption[File]
- ): ValueConverter[api.validation.Validator] =
- singleArgConverter[api.validation.Validator]((s: String) => {
+ ): ValueConverter[(String, Option[URI])] =
+ 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))
- val defaults = {
- schema
- .map(sch => ValidatorFactory.makeConfig(sch.uri.toString))
- .getOrElse(new Properties())
- }
- val props = new Properties(defaults)
-
s match {
- case DefaultArgPattern(name, arg) if Validators.isRegistered(name) =>
+ case DefaultArgPattern(name, arg) =>
if (doesNotSupportReloadableParsers(name)) {
- null
+ null // validateOpt will cause null to output an appropriate error
message
} else {
- if (Seq(".conf", ".properties").exists(arg.endsWith)) {
- val is = new FileInputStream(arg)
- props.load(is)
- } else {
- val uss = fileResourceToURI(arg)
- props.setProperty(name, uss.uri.toString)
- }
- Validators.get(name).make(props)
+ val uri = fileResourceToURI(arg).uri
+ (name, Some(uri))
}
- case NoArgsPattern(name) if Validators.isRegistered(name) =>
+ case NoArgsPattern(name) =>
if (doesNotSupportReloadableParsers(name)) {
- null
+ null // validateOpt will cause null to output an appropriate error
message
} else {
- Validators.get(name).make(props)
+ (name, schema.map(_.uri).toOption)
}
case _ =>
throw new Exception(
@@ -436,14 +421,14 @@ class CLIConf(arguments: Array[String], stdout:
PrintStream, stderr: PrintStream
descr = "Tunable configuration options to change Daffodil's behavior. " +
"Only valid with the --schema option."
)
- val validate: ScallopOption[api.validation.Validator] =
opt[api.validation.Validator](
+ val validate: ScallopOption[(String, Option[URI])] = opt[(String,
Option[URI])](
short = 'V',
- default = Some(NoValidator),
+ default = Some(("off", None)),
argName = "validator_name",
descr =
- "Validator name. Use 'xerces=[value]', 'limited', 'off', or a
validator_plugin_name=value, where value" +
- "is an optional schema to validate against, a key/value
configuration file or a required schematron" +
- " schema in the case of the schematron validator plugin."
+ "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."
)(validateConverter(schema, parser))
val debug = opt[Option[String]](
argName = "file",
@@ -566,14 +551,14 @@ class CLIConf(arguments: Array[String], stdout:
PrintStream, stderr: PrintStream
descr = "Tunable configuration options to change Daffodil's behavior. " +
"Only valid with the --schema option."
)
- val validate: ScallopOption[api.validation.Validator] =
opt[api.validation.Validator](
+ val validate: ScallopOption[(String, Option[URI])] = opt[(String,
Option[URI])](
short = 'V',
- default = Some(NoValidator),
+ default = Some(("off", None)),
argName = "validator_name",
descr =
- "Validator name. Use 'xerces=[value]', 'limited', 'off', or a
validator_plugin_name=value, where value" +
- "is an optional schema to validate against, a key/value
configuration file or a required schematron" +
- " schema in the case of the schematron validator plugin."
+ "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."
)(validateConverter(schema, parser))
val debug = opt[Option[String]](
argName = "file",
@@ -801,14 +786,14 @@ class CLIConf(arguments: Array[String], stdout:
PrintStream, stderr: PrintStream
default = Some(false),
descr = "Perform unparse instead of parse for performance test"
)
- val validate: ScallopOption[api.validation.Validator] =
opt[api.validation.Validator](
+ val validate: ScallopOption[(String, Option[URI])] = opt[(String,
Option[URI])](
short = 'V',
- default = Some(NoValidator),
+ default = Some(("off", None)),
argName = "validator_name",
descr =
- "Validator name. Use 'xerces=[value]', 'limited', 'off', or a
validator_plugin_name=value, where value" +
- "is an optional schema to validate against, a key/value
configuration file or a required schematron" +
- " schema in the case of the schematron validator plugin."
+ "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."
)(validateConverter(schema, parser))
val infile = trailArg[String](
@@ -990,6 +975,7 @@ object Main {
val UserDefinedFunctionError = Value(34)
val UnableToCreateProcessor = Value(35)
val LayerExecutionError = Value(36)
+ val UnableToCreateValidatorError = Value(37)
val Usage = Value(64)
}
@@ -1070,7 +1056,7 @@ class Main(
def createProcessorFromParser(
savedParser: File,
path: Option[String],
- validator: api.validation.Validator
+ validate: (String, Option[URI])
) = {
try {
val compiler = Compiler()
@@ -1084,7 +1070,8 @@ class Main(
Logger.log.debug(s"Parser = ${processorImpl.ssrd.parser.toString}")
Logger.log.debug(s"Unparser =
${processorImpl.ssrd.unparser.toString}")
}
- Some(processor.withValidator(validator))
+ val (validationKind, validationConfig) = validate
+ Some(processor.withValidation(validationKind,
validationConfig.getOrElse(null)))
} else {
None
}
@@ -1136,7 +1123,7 @@ class Main(
rootNS: Option[RefQName],
path: Option[String],
tunablesMap: Map[String, String],
- validator: api.validation.Validator
+ validate: (String, Option[URI])
): Option[api.DataProcessor] = {
val compiler = {
val c = Compiler().withTunables(tunablesMap)
@@ -1157,9 +1144,10 @@ class Main(
"compiling", {
val processorFactory = compiler.compileSource(schemaSource)
if (!processorFactory.isError) {
+ val (validationKind, validationConfig) = validate
val processor = processorFactory
.onPath(path.getOrElse("/"))
- .withValidator(validator)
+ .withValidation(validationKind, validationConfig.getOrElse(null))
// needed to access SchemaSetRuntimeData
.asInstanceOf[DataProcessor]
if (processor.isError) {
@@ -1239,7 +1227,7 @@ class Main(
case Some(conf.parse) => {
val parseOpts = conf.parse
- val validate = parseOpts.validate.toOption.get
+ val validate = parseOpts.validate()
val optDafConfig = parseOpts.config.toOption.map {
DaffodilConfig.fromFile(_) }
@@ -1262,8 +1250,7 @@ class Main(
.withExternalVariables(
combineExternalVariables(parseOpts.vars, optDafConfig)
)
- }.map { _.withValidator(validate) }
- .map { withDebugOrTrace(_, parseOpts.trace, parseOpts.debug) }
+ }.map { withDebugOrTrace(_, parseOpts.trace, parseOpts.debug) }
val rc = processor match {
case None => ExitCode.UnableToCreateProcessor
@@ -1438,7 +1425,7 @@ class Main(
case Some(conf.performance) => {
val performanceOpts = conf.performance
- val validate = performanceOpts.validate.toOption.get
+ val validate = performanceOpts.validate()
val optDafConfig = performanceOpts.config.toOption.map {
DaffodilConfig.fromFile(_) }
@@ -1463,7 +1450,7 @@ class Main(
}.map { p =>
p.asInstanceOf[DFDL.DataProcessor]
.withExternalVariables(combineExternalVariables(performanceOpts.vars,
optDafConfig))
- }.map { _.withValidator(validate) }
+ }
val rc: ExitCode.Value = processor match {
case None => ExitCode.UnableToCreateProcessor
@@ -1592,7 +1579,7 @@ class Main(
case Some(conf.unparse) => {
val unparseOpts = conf.unparse
- val validate = unparseOpts.validate.toOption.get
+ val validate = unparseOpts.validate()
val optDafConfig = unparseOpts.config.toOption.map {
DaffodilConfig.fromFile(_) }
@@ -1613,8 +1600,7 @@ class Main(
}.map { p =>
p.asInstanceOf[DFDL.DataProcessor]
.withExternalVariables(combineExternalVariables(unparseOpts.vars,
optDafConfig))
- }.map { _.withValidator(validate) }
- .map { withDebugOrTrace(_, unparseOpts.trace, unparseOpts.debug) }
+ }.map { withDebugOrTrace(_, unparseOpts.trace, unparseOpts.debug) }
val output = unparseOpts.output.toOption match {
case Some("-") | None => STDOUT
@@ -1696,7 +1682,7 @@ class Main(
case Some(conf.save) => {
val saveOpts = conf.save
- val validate = NoValidator
+ val validate = ("off", None)
val optDafConfig = saveOpts.config.toOption.map {
DaffodilConfig.fromFile(_) }
val tunables =
@@ -2083,6 +2069,14 @@ class Main(
Logger.log.error(Misc.getSomeMessage(e).get)
ExitCode.BadExternalVariable
}
+ case e: ValidatorNotRegisteredException => {
+ Logger.log.error(Misc.getSomeMessage(e).get)
+ ExitCode.UnableToCreateValidatorError
+ }
+ case e: ValidatorInitializationException => {
+ Logger.log.error(Misc.getSomeMessage(e).get)
+ ExitCode.UnableToCreateValidatorError
+ }
case e: NotYetImplementedException => {
nyiFound(e)
ExitCode.NotYetImplemented
diff --git
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLIParsing.scala
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLIParsing.scala
index 15f13afce..e2a0f0eb6 100644
---
a/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLIParsing.scala
+++
b/daffodil-cli/src/test/scala/org/apache/daffodil/cli/cliTest/TestCLIParsing.scala
@@ -552,7 +552,7 @@ class TestCLIParsing {
runCLI(args"parse --validate FooBar -s $schema -r matrix") { cli =>
cli.sendLine("0,1,2", inputDone = true)
cli.expectErr("FooBar")
- }(ExitCode.Usage)
+ }(ExitCode.UnableToCreateValidatorError)
}
@Test def test_CLI_Parsing_invalidElementSDE(): Unit = {
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 3920a24e8..5a62cda13 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
@@ -64,8 +64,8 @@ class TestValidating {
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.expectErr("Bad arguments")
+ cli.expectErr("failed to create schematron validator")
cli.expectErr("does-no-exist/title-rules.sch")
- }(ExitCode.Usage)
+ }(ExitCode.UnableToCreateValidatorError)
}
}
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 53db53e19..8f5c55bde 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
@@ -26,12 +26,14 @@ import
org.apache.daffodil.api.exceptions.ExternalVariableException;
import org.apache.daffodil.api.infoset.InfosetInputter;
import org.apache.daffodil.api.infoset.InfosetOutputter;
import org.apache.daffodil.api.metadata.MetadataHandler;
-import org.apache.daffodil.api.validation.Validator;
+import org.apache.daffodil.api.validation.ValidatorInitializationException;
+import org.apache.daffodil.api.validation.ValidatorNotRegisteredException;
import org.apache.daffodil.core.dsom.ExpressionCompilers$;
import org.apache.daffodil.runtime1.debugger.InteractiveDebugger;
import java.io.File;
import java.io.Serializable;
+import java.net.URI;
import java.nio.channels.WritableByteChannel;
import java.util.Map;
@@ -82,14 +84,36 @@ public interface DataProcessor extends WithDiagnostics,
Serializable {
DataProcessor withDebugger(Debugger dbg);
/**
- * Obtain a new {@link DataProcessor} with a specified validator.
+ * Obtain a new {@link DataProcessor} with validation that does not require
configuration.
*
- * @param validator Validator which could be NoValidator for off, or
DaffodilLimitedValidator
- * for limited, XercesValidator for full,
SchematronValidator for schemratron,
- * or a custom validator that implements {@link Validator}
+ * @param kind Kind of validation to use. Can be a custom validator name
available via the
+ * {@link org.apache.daffodil.api.validation.ValidatorFactory}
SPI or one of the built-in validators
+ * ("xerces", "limited", "off", "schematron")
* @return a new {@link DataProcessor} with a specified validator.
+ * @throws ValidatorNotRegisteredException if the validator cannot be found
+ * @throws ValidatorInitializationException if initializing the validator
fails
*/
- DataProcessor withValidator(Validator validator);
+ default DataProcessor withValidation(String kind) throws
ValidatorNotRegisteredException, ValidatorInitializationException {
+ return withValidation(kind, null);
+ }
+
+ /**
+ * Obtain a new {@link DataProcessor} with validation using a URI for
configuration.
+ *
+ * @param kind Kind of validation to use. Can be a custom validator name
available via the
+ * {@link org.apache.daffodil.api.validation.ValidatorFactory}
SPI or one of the built-in validators
+ * ("xerces", "limited", "off", "schematron")
+ * @param config Absolute URI to use for validation configuration. If the
URI ends with .conf
+ * or .properties it is treated as a java.util.Properties file
that is loaded and
+ * provided to the validator. Otherwise, the URI is provided
as a single property to
+ * the validator. Can be null if a URI is not known or the
validator does not need
+ * additional configuration--this could cause an exception if
a validator requires
+ * properties.
+ * @return a new {@link DataProcessor} with a specified validator.
+ * @throws ValidatorNotRegisteredException if the validator cannot be found
+ * @throws ValidatorInitializationException if initializing the validator
fails
+ */
+ DataProcessor withValidation(String kind, URI config) throws
ValidatorNotRegisteredException, ValidatorInitializationException;
/**
* Obtain a new {@link DataProcessor} with external variables read from a
Daffodil configuration file
diff --git
a/daffodil-core/src/main/java/org/apache/daffodil/api/validation/Validator.java
b/daffodil-core/src/main/java/org/apache/daffodil/api/validation/Validator.java
index bc5a52197..0d4a3fd28 100644
---
a/daffodil-core/src/main/java/org/apache/daffodil/api/validation/Validator.java
+++
b/daffodil-core/src/main/java/org/apache/daffodil/api/validation/Validator.java
@@ -33,10 +33,6 @@ import java.io.Serializable;
* ValidationHandler
*/
public interface Validator extends Serializable {
- /**
- * default schema key for configuration file
- */
- String rootSchemaKey = "daffodil.rootSchema";
/**
* Used to validate XMLs. Any validation diagnostics will be added to the
state
diff --git
a/daffodil-core/src/main/java/org/apache/daffodil/api/validation/ValidatorFactory.java
b/daffodil-core/src/main/java/org/apache/daffodil/api/validation/ValidatorFactory.java
index 704d0ef8f..74510ea2e 100644
---
a/daffodil-core/src/main/java/org/apache/daffodil/api/validation/ValidatorFactory.java
+++
b/daffodil-core/src/main/java/org/apache/daffodil/api/validation/ValidatorFactory.java
@@ -43,16 +43,4 @@ public interface ValidatorFactory extends
SimpleNamedLoadableService {
* @throws
org.apache.daffodil.api.validation.ValidatorInitializationException when
initialization fails
*/
Validator make(Properties config) throws ValidatorInitializationException;
-
- /**
- * Helper utility to create a Properties file with the rootSchemaKey set,
which many validators can use
- *
- * @param defaultSchema String uri to the default validating schema
- * @return Properties object with the default root schema set
- */
- static Properties makeConfig(String defaultSchema) {
- Properties properties = new Properties();
- properties.setProperty(Validator.rootSchemaKey, defaultSchema);
- return properties;
- }
}
diff --git
a/daffodil-core/src/main/java/org/apache/daffodil/api/validation/package-info.java
b/daffodil-core/src/main/java/org/apache/daffodil/api/validation/package-info.java
index 2fd7f8d52..8c244a784 100644
---
a/daffodil-core/src/main/java/org/apache/daffodil/api/validation/package-info.java
+++
b/daffodil-core/src/main/java/org/apache/daffodil/api/validation/package-info.java
@@ -16,97 +16,104 @@
*/
/**
- * We provide 4 different types of built-in validators for use with
- * {@link
org.apache.daffodil.api.DataProcessor#withValidator(org.apache.daffodil.api.validation.Validator)}:
- * <ul>
- * <li>{@link org.apache.daffodil.validation.NoValidator} - for no
validation</li>
- * <li>{@link org.apache.daffodil.validation.DaffodilLimitedValidator} - for
limited/daffodil schema constraints validation</li>
- * <li>{@link org.apache.daffodil.validation.XercesValidator} - for full
validation using Xerces schema validation</li>
- * <li>see org.apache.daffodil.validation.schematron.SchematronValidator -
for schematron validation</li>
- * </ul>
+ * Daffodil Validation API package
+ *
* <p>
- * It is also possible to create a custom validator by doing the following:
+ * Daffodil provides a number of built-in validators for use with {@link
+ * org.apache.daffodil.api.DataProcessor#withValidation(String, URI)}. For each
+ * built-in validator, the following contains the validator name, a
+ * description, and validator specific properties. The {@code String} paramter
+ * should be the name of the validator. If the URI parameter ends in
+ * <i>.conf</i> or <i>.properties</i> then it is treated as a {@link
+ * java.util.Properties} file that provides validator properties. Otherwise,
+ * the URI is set to a property with the same name as the validator. If a
+ * validator does not require properties, the URI parameter can be set to
+ * {@code null} or excluded.
+ * </p>
+ *
+ * <dl>
+ * <dt><span style="font-size: large;"><b>off</b></span></dt>
+ * <dd>
+ * <p><b>Description:</b> disable validation</p>
+ * <p><b>Properties:</b> none</p>
+ * <p><b>Example:</b></p>
+ * <pre>{@code
+ * // explicitly disable validation
+ * dataProcessor.withValidation("off")
+ * }</pre>
+ * </dd>
+ *
+ * <dt><span style="font-size: large;"><b>limited</b></span></dt>
+ * <dd>
+ * <p><b>Description:</b> XML schema validation using Daffodil</p>
+ * <p><b>Properties:</b> none</p>
+ * <p><b>Example:</b></p>
+ * <pre>{@code
+ * // enable XML schema validation using Daffodil
+ * dataProcessor.withValidation("limited")
+ * }</pre>
+ * </dd>
+ *
+ * <dt><span style="font-size: large;"><b>xerces</b></span></dt>
+ * <dd>
+ * <p><b>Description:</b> XML Schema validation using Xerces library</p>
+ * <p><b>Properties:</b></p>
+ * <dl>
+ * <dt>{@code xerces}</dt>
+ * <dd>absolute URI to a XSD file</dd>
+ * </dl>
+ * <p><b>Example:</b></p>
+ * <pre>{@code
+ * // enable XML schema validation, setting the "xerces" property to the
schema.xsd file
+ * dataProcessor.withValidation("xerces",
URI.create("file:///path/to/schema.xsd"))
+ * }</pre>
+ * </dd>
+ *
+ * <dt><span style="font-size: large;"><b>schematron</b></span></dt>
+ * <dd>
+ * <p><b>Description:</b> schematron validation using Saxon-HE library</p>
+ * <p><b>Properties:</b></p>
+ * <dl>
+ * <dt>{@code schematron}</dt>
+ * <dd>
+ * absolute URI to a file containing schematron rules. If the URI
+ * ends with {@code .sch} then the file is treated as a schematron
file.
+ * Otherwise, it is treated as an XSD file containing embedded
+ * schematron rules.
+ * </dd>
+ * <dt>{@code schematron.svrl.file}</dt>
+ * <dd>
+ * absolute URI to a file to write the results of schematron
+ * validation in SVRL format. This property is not thread safe and
+ * will overwrite existing files--it is intended primarily for
+ * debugging with single file validation.
+ * </dd>
+ * </dl>
+ * <p><b>Example:</b></p>
+ * <pre>{@code
+ * // enable schematron validation, setting the "schematron" property to the
schematron.sch file
+ * dataProcessor.withValidation("schematron",
URI.create("file:///path/to/schematron.sch"))
+ *
+ * // use schematron validation, reading the schematron.properties file to set
"schematron" or other schematron properties
+ * dataProcessor.withValidation("schematron",
URI.create("file:///path/to/schematron.properties"))
+ * }</pre>
+ * </dd>
+ * </dl>
+ *
+ * <h2>Custom Validators</h2>
+ * <p>
+ * Daffodil also supports custom validators. To make a custom validator
available to Daffodil, follow these steps:
* <ol>
- * <li>create a custom Validator class that implements the
+ * <li>Create a custom class that implements the
* {@link org.apache.daffodil.api.validation.Validator} interface</li>
- * <li>create a custom ValidatorFactory class that implements the
- * {@link org.apache.daffodil.api.validation.ValidatorFactory} interface,
whose make method
- * returns the custom validator from the previous step</li>
- * <li>Register the created custom Validator Factory by creating a {@link
org.apache.daffodil.api.validation.ValidatorFactory}
+ * <li>Create a custom class that implements the
+ * {@link org.apache.daffodil.api.validation.ValidatorFactory} interface,
whose {@code make} method
+ * returns the custom Validator from the previous step</li>
+ * <li>Register the custom ValidatorFactory by creating a {@link
org.apache.daffodil.api.validation.ValidatorFactory}
* file in {@code META-INF/services/}, its contents being the fully qualified
name of the custom validator factory</li>
+ * <li>Call the {@link
org.apache.daffodil.api.DataProcessor#withValidation(String, URI)} function,
providing the name
+ * of the validator and optional URI.</li>
* </ol>
- * <p>
- * To get an instance of one of the provided validators, one will need:
- * <ul>
- * <li> access to registered {@link
org.apache.daffodil.api.validation.ValidatorFactory}s
- * via the {@link
org.apache.daffodil.api.validation.Validators#get(java.lang.String)}
command</li>
- * <li> a {@link java.util.Properties} object with the appropriate
keys/values (see below for specifics for each kind of validator)</li>
- * <li> the name of the validator (ex: off, limited, xerces or schematron)
</li>
- * </ul>
- * <p>
- * To geta specific Validator factory instance, do the below:
- * <pre>
- * {@code
- * org.apache.daffodil.api.validation.ValidatorFactory vf =
org.apache.daffodil.api.validation.Validators.get("xerces")
- * }
- * </pre>
- * To get the validator, certain properties are required to be passed into the
make function,
- * depending on the validator.
- * <ul>
- * <li>{@link org.apache.daffodil.validation.NoValidator}
- * <ul>
- * <li>none; empty Properties object or null</li>
- * </ul>
- * </li>
- * <li>{@link org.apache.daffodil.validation.DaffodilLimitedValidator}
- * <ul>
- * <li>none; empty Properties object or null</li>
- * </ul>
- * </li>
- * <li>{@link org.apache.daffodil.validation.XercesValidator}
- * <ul>
- * <li>{@code daffodil.rootSchema=schema_file_uri_string}</li>
- * <li>{@code xerces=schema_file_uri_string} - if not found, Daffodil
will attempt to use
- * the above instead. So one or both must be present, but this will
always take precedence over
- * daffodil.rootSchema if both are present.</li>
- * </ul>
- * </li>
- * <li>org.apache.daffodil.validation.schematron.SchematronValidator
- * <ul>
- * <li>{@code schematron=uri_string_to_schematron_file} - if not found,
Daffodil will attempt to use
- * the daffodil.rootSchema instead. So one or both must be present, but
this will always take precedence over
- * daffodil.rootSchema if both are present. </li>
- * <li>{@code schematron.svrl.file=uri_string_to_output_file}</li>
- * <li>{@code daffodil.rootSchema=schema_file_uri_string}</li>
- * </ul>
- * </li>
- * </ul>
- * <p>
- * And finally get the validator using make as below:
- * <pre>
- * {@code
- * Properties props = new Properties();
- * props.setProperty(XercesValidator.name, "/path/to/validating/schema.xsd");
- * org.apache.daffodil.validation.Validator v = vf.make(props);
- * }
- * </pre>
- * <p>
- * or one can load the below properties file as follows:
- * <pre>
- * {@code
- * // schematron.properties
- * schematron=/path/to/schema.xsd
- * schematron.svrl.file=/path/to/validation/output.txt
- * }
- * </pre>
- *
- * <pre>
- * {@code
- * Properties props = new Properties();
- * props.load(new FileInputStream("schematron.properties"));
- * org.apache.daffodil.validation.Validator v = vf.make(props);
- * }
- * </pre>
*/
package org.apache.daffodil.api.validation;
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 94d9cb552..6e575b047 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
@@ -19,12 +19,12 @@ package org.apache.daffodil.core.util
import java.io.ByteArrayInputStream
import java.io.InputStream
+import java.net.URI
import java.nio.channels.Channels
import java.nio.channels.ReadableByteChannel
import java.nio.channels.WritableByteChannel
import java.nio.charset.Charset
import java.nio.file.Files
-import java.util.Properties
import scala.collection.mutable.ArrayBuffer
import scala.jdk.CollectionConverters._
import scala.util.Try
@@ -34,7 +34,6 @@ import org.apache.daffodil.api
import org.apache.daffodil.api.ProcessorFactory
import org.apache.daffodil.api.debugger.InteractiveDebuggerRunnerFactory
import org.apache.daffodil.api.metadata.MetadataHandler
-import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.core.compiler.Compiler
import org.apache.daffodil.core.dsom._
import org.apache.daffodil.io.InputSourceDataInputStream
@@ -236,7 +235,7 @@ object TestUtils {
dp.withDebugger(builtInTracer).withDebugging(true)
} else dp
- val p = p1.withValidator(Validators.get("limited").make(new Properties))
+ val p = p1.withValidation("limited")
val outputter = new ScalaXMLInfosetOutputter()
val input = InputSourceDataInputStream(is)
@@ -370,7 +369,7 @@ class Fakes private () {
override def withExternalVariables(
extVars: java.util.Map[String, String]
): DFDL.DataProcessor = this
- override def withValidator(validator: api.validation.Validator):
DFDL.DataProcessor = this
+ override def withValidation(kind: String, config: URI): DFDL.DataProcessor
= this
override def withDebugger(dbg: api.debugger.Debugger): DFDL.DataProcessor
= this
override def withDebugging(flag: Boolean): DFDL.DataProcessor = this
@@ -445,14 +444,9 @@ class StreamParser private (val schema: Node) {
if (pf.isError) throw new StreamParser.CompileFailure(pf.getDiagnostics)
val dataproc1 = pf
.onPath("/")
- val props = new Properties()
val schemaTempFile = Files.createTempFile("streamparser", ".test")
FileUtils.write(schemaTempFile.toFile, schema.toString(),
Charset.defaultCharset())
- props.setProperty(api.validation.Validator.rootSchemaKey,
schemaTempFile.toUri.toString)
- val dataproc = dataproc1
- .withValidator(
- Validators.get("xerces").make(props)
- )
+ val dataproc = dataproc1.withValidation("xerces", schemaTempFile.toUri)
// .withDebuggerRunner(new TraceDebuggerRunner()) // DAFFODIL-2624 -
cannot trace in streaming SAPI
// .withDebugging(true)
if (dataproc.isError)
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 60e481da1..8956dc091 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
@@ -20,18 +20,22 @@ package org.apache.daffodil.runtime1.processors
import java.io.File
import java.io.IOException
import java.io.ObjectOutputStream
+import java.net.URI
import java.nio.CharBuffer
import java.nio.LongBuffer
import java.nio.channels.Channels
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
+import java.util.Properties
import java.util.zip.GZIPOutputStream
import scala.jdk.CollectionConverters._
import org.apache.daffodil.api
import org.apache.daffodil.api.debugger.Debugger
import org.apache.daffodil.api.metadata.MetadataHandler
+import org.apache.daffodil.api.validation.ValidatorInitializationException
+import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.lib.equality._
import org.apache.daffodil.lib.iapi.DaffodilTunables
import org.apache.daffodil.lib.iapi.WithDiagnostics
@@ -102,9 +106,9 @@ object DataProcessor {
variableMap: VariableMap // must be explicitly reset by save method
) extends DataProcessor(ssrd, tunables, variableMap) {
- override def withValidator(v: api.validation.Validator): api.DataProcessor
= {
- if ((v eq DaffodilLimitedValidator) || (v eq NoValidator)) {
- super.withValidator(v)
+ 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."
@@ -191,7 +195,21 @@ class DataProcessor(
*/
override def clone(): DataProcessor = copy()
- override def withValidator(v: api.validation.Validator): api.DataProcessor =
{
+ override def withValidation(kind: String, config: URI): api.DataProcessor = {
+ val properties = new Properties()
+ if (config != null) {
+ val configStr = config.toString
+ if (configStr.endsWith(".conf") || configStr.endsWith(".properties")) {
+ try {
+ properties.load(config.toURL.openStream())
+ } catch {
+ case e: Exception => throw new
ValidatorInitializationException(e.getMessage)
+ }
+ } else {
+ properties.setProperty(kind, configStr)
+ }
+ }
+ val v = Validators.get(kind).make(properties)
copy(validator = v)
}
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/validation/DaffodilLimitedValidator.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/validation/DaffodilLimitedValidator.scala
index 004f1969f..a84947543 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/validation/DaffodilLimitedValidator.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/validation/DaffodilLimitedValidator.scala
@@ -31,6 +31,8 @@ object DaffodilLimitedValidator extends
api.validation.Validator {
): Unit = {
// do nothing
}
+
+ val name = "limited"
}
class DaffodilLimitedValidator
@@ -42,7 +44,7 @@ class DaffodilLimitedValidator
*/
class DaffodilLimitedValidatorFactory extends api.validation.ValidatorFactory {
- override def name(): String = "limited"
+ override def name(): String = DaffodilLimitedValidator.name
override def make(config: Properties = new Properties()): Validator = {
DaffodilLimitedValidator
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/validation/NoValidator.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/validation/NoValidator.scala
index 0eaa7f5a2..295fe536e 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/validation/NoValidator.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/validation/NoValidator.scala
@@ -31,6 +31,8 @@ object NoValidator extends Validator {
): Unit = {
// do nothing
}
+
+ val name = "off"
}
/**
@@ -40,7 +42,7 @@ object NoValidator extends Validator {
*/
class NoValidatorFactory extends api.validation.ValidatorFactory {
- override def name(): String = "off"
+ override def name(): String = NoValidator.name
override def make(config: Properties = new Properties()): Validator = {
NoValidator
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/validation/XercesValidator.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/validation/XercesValidator.scala
index ed48f93b3..49ee64cd8 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/validation/XercesValidator.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/validation/XercesValidator.scala
@@ -37,10 +37,9 @@ import org.xml.sax.SAXParseException
*
* SPI service name: xerces
*
- * Configuration requirements (only one must be present, but the value of
xerces takes precedence if both are present):
+ * Configuration requirements.
* <ul>
* <li>xerces=schema_file_uri_string</li>
- * <li>daffodil.rootSchema=schema_file_uri_string</li>
* </ul>
*/
class XercesValidatorFactory extends api.validation.ValidatorFactory {
@@ -52,20 +51,12 @@ class XercesValidatorFactory extends
api.validation.ValidatorFactory {
object XercesValidatorFactory {
def makeValidator(config: Properties): api.validation.Validator = {
- if (config == null) {
- throw new api.validation.ValidatorInitializationException(
- "invalid configuration: missing xerces path"
- )
- }
-
val schemaPath = config.getProperty(XercesValidator.name)
- lazy val defaultSchema =
config.getProperty(api.validation.Validator.rootSchemaKey)
val schemaFile = {
if (!Misc.isNullOrBlank(schemaPath)) schemaPath
- else if (!Misc.isNullOrBlank(defaultSchema)) defaultSchema
else
throw new api.validation.ValidatorInitializationException(
- "invalid configuration: xerces validator path was empty"
+ "invalid configuration: xerces property is empty or not defined"
)
}
val uri = new URI(schemaFile)
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 96b1438b6..022e951cc 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
@@ -109,12 +109,6 @@ public class TestAPI {
}
}
- private Properties makeConfig(File schemaFile) throws IOException {
- Properties props = new Properties();
- props.setProperty(Validator.rootSchemaKey, schemaFile.toURI().toString());
- return props;
- }
-
/**
* This is a test-only helper function used to serialize and deserialize a
* DataProcessor to ensure all JAPI classes that need to extend
@@ -249,7 +243,7 @@ public class TestAPI {
DataProcessor parser = compiler.reload(input);
try {
- parser =
parser.withValidator(Validators.get("xerces").make(makeConfig(schemaFile)));
+ parser = parser.withValidation("xerces", schemaFile.toURI());
fail();
} catch (InvalidUsageException e) {
assertEquals("Only Limited/No validation allowed when using a restored
parser.", e.getMessage());
@@ -774,7 +768,7 @@ public class TestAPI {
ProcessorFactory pf = c.compileFile(schemaFile);
DataProcessor dp = pf.onPath("/");
dp = reserializeDataProcessor(dp);
- dp = dp.withValidator(Validators.get("limited").make(new Properties()));
+ dp = dp.withValidation("limited");
java.io.File file = getResource("/test/api/myData.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
@@ -801,7 +795,7 @@ public class TestAPI {
java.io.File schemaFile = getResource("/test/api/mySchema1.dfdl.xsd");
ProcessorFactory pf = c.compileFile(schemaFile);
DataProcessor dp = pf.onPath("/");
- dp =
dp.withValidator(Validators.get("xerces").make(makeConfig(schemaFile)));
+ dp = dp.withValidation("xerces", schemaFile.toURI());
java.io.File file = getResource("/test/api/myData.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
@@ -1365,7 +1359,7 @@ public class TestAPI {
java.io.File schemaFile = getResource("/test/api/blob.dfdl.xsd");
ProcessorFactory pf = c.compileFile(schemaFile);
DataProcessor dp = pf.onPath("/");
- dp =
dp.withValidator(Validators.get("xerces").make(makeConfig(schemaFile)));
+ dp = dp.withValidation("xerces", schemaFile.toURI());
byte[] data = new byte[]{0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04};
ByteArrayInputStream bis = new ByteArrayInputStream(data);
@@ -1478,7 +1472,7 @@ public class TestAPI {
URI uri = new URI("/test/api/mySchema1.dfdl.xsd");
ProcessorFactory pf = c.compileSource(uri);
DataProcessor dp1 = pf.onPath("/");
- DataProcessor dp =
dp1.withValidator(Validators.get("xerces").make(makeConfig(getResource(uri.getPath()))));
+ DataProcessor dp = dp1.withValidation("xerces",
getResource(uri.getPath()).toURI());
java.io.File file = getResource("/test/api/myDataBroken.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
diff --git
a/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorApiExample.java
b/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorApiExample.java
index 8730f85c4..06c68c638 100644
---
a/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorApiExample.java
+++
b/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorApiExample.java
@@ -54,7 +54,7 @@ public class ValidatorApiExample {
org.apache.daffodil.api.Compiler c = Daffodil.compiler();
java.io.File schemaFile = getResource("/test/api/mySchema5.dfdl.xsd");
ProcessorFactory pf = c.compileFile(schemaFile);
- DataProcessor dp =
pf.onPath("/").withValidator(Validators.get(PassingValidator.name).make(new
Properties()));
+ DataProcessor dp = pf.onPath("/").withValidation(PassingValidator.name);
java.io.File file = getResource("/test/api/myData5.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
@@ -70,7 +70,7 @@ public class ValidatorApiExample {
org.apache.daffodil.api.Compiler c = Daffodil.compiler();
java.io.File schemaFile = getResource("/test/api/mySchema1.dfdl.xsd");
ProcessorFactory pf = c.compileFile(schemaFile);
- DataProcessor dp =
pf.onPath("/").withValidator(Validators.get(FailingValidator.name).make(new
Properties()));
+ DataProcessor dp = pf.onPath("/").withValidation(FailingValidator.name);
java.io.File file = getResource("/test/api/myData.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
@@ -91,9 +91,7 @@ public class ValidatorApiExample {
System.err.println(d.toString());
}
DataProcessor dp1 = pf.onPath("/");
- Properties props = new Properties();
- props.setProperty(Validator.rootSchemaKey, schemaFile.toURI().toString());
- DataProcessor dp = dp1.withValidator(Validators.get("xerces").make(props));
+ DataProcessor dp = dp1.withValidation("xerces", schemaFile.toURI());
java.io.InputStream fis = new ByteArrayInputStream("0".getBytes());
try (InputSourceDataInputStream dis =
Infoset.getInputSourceDataInputStream(fis)) {
diff --git
a/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorSpiExample.java
b/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorSpiExample.java
index d6dfc1cdf..9acc5c8ad 100644
---
a/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorSpiExample.java
+++
b/daffodil-core/src/test/java/org/apache/daffodil/jexample/ValidatorSpiExample.java
@@ -18,7 +18,6 @@
package org.apache.daffodil.jexample;
import org.apache.daffodil.api.infoset.Infoset;
-import org.apache.daffodil.api.validation.ValidatorFactory;
import org.apache.daffodil.api.validation.Validators;
import org.apache.daffodil.jexample.validation.FailingValidator;
import org.apache.daffodil.jexample.validation.PassingValidator;
@@ -30,8 +29,6 @@ import org.apache.daffodil.api.infoset.JDOMInfosetOutputter;
import org.apache.daffodil.api.InputSourceDataInputStream;
import org.junit.Test;
-import java.util.Properties;
-
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -51,8 +48,7 @@ public class ValidatorSpiExample {
ProcessorFactory pf = c.compileFile(schemaFile);
assertTrue(Validators.isRegistered(PassingValidator.name));
- ValidatorFactory vf = Validators.get(PassingValidator.name);
- DataProcessor dp = pf.onPath("/").withValidator(vf.make(new Properties()));
+ DataProcessor dp = pf.onPath("/").withValidation(PassingValidator.name);
java.io.File file = getResource("/test/api/myData5.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
@@ -71,8 +67,7 @@ public class ValidatorSpiExample {
ProcessorFactory pf = c.compileFile(schemaFile);
assertTrue(Validators.isRegistered(FailingValidator.name));
- ValidatorFactory vf = Validators.get(FailingValidator.name);
- DataProcessor dp = pf.onPath("/").withValidator(vf.make(new Properties()));
+ DataProcessor dp = pf.onPath("/").withValidation(FailingValidator.name);
java.io.File file = getResource("/test/api/myData.dat");
java.io.FileInputStream fis = new java.io.FileInputStream(file);
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestValidatorsSPI.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestValidatorsSPI.scala
index 0ceb5f41c..b3a72a8cf 100644
---
a/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestValidatorsSPI.scala
+++
b/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestValidatorsSPI.scala
@@ -17,7 +17,8 @@
package org.apache.daffodil.lib.validation
-import org.apache.daffodil.api.validation.ValidatorFactory
+import java.util.Properties
+
import org.apache.daffodil.api.validation.ValidatorNotRegisteredException
import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.validation.XercesValidator
@@ -55,7 +56,7 @@ class TestValidatorsSPI {
@Test def testPassingValidator(): Unit = {
val f = Validators.get(PassingValidator.name)
- val v = f.make(ValidatorFactory.makeConfig(schema))
+ val v = f.make(new Properties())
val validationHandler = new TestingValidationHandler
v.validateXML(infoset, validationHandler)
@@ -65,7 +66,7 @@ class TestValidatorsSPI {
@Test def testFailingValidator(): Unit = {
val f = Validators.get(FailingValidator.name)
- val v = f.make(ValidatorFactory.makeConfig(schema))
+ val v = f.make(new Properties())
val validationHandler = new TestingValidationHandler
v.validateXML(infoset, validationHandler)
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestXercesValidator.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestXercesValidator.scala
index c469f6b7f..f98738086 100644
---
a/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestXercesValidator.scala
+++
b/daffodil-core/src/test/scala/org/apache/daffodil/lib/validation/TestXercesValidator.scala
@@ -17,7 +17,8 @@
package org.apache.daffodil.lib.validation
-import org.apache.daffodil.api.validation.ValidatorFactory
+import java.util.Properties
+
import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.validation.XercesValidator
@@ -29,8 +30,10 @@ class TestXercesValidator {
val infoset =
getClass.getResourceAsStream("/test/validation/testData1Infoset.xml")
@Test def testFromSPI(): Unit = {
- val f = Validators.get(XercesValidator.name)
- val v = f.make(ValidatorFactory.makeConfig(schema))
+ val properties = new Properties()
+ properties.setProperty(XercesValidator.name, schema)
+
+ val v = Validators.get(XercesValidator.name).make(properties)
val validationHandler = new TestingValidationHandler
v.validateXML(infoset, validationHandler)
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 c213e3ffd..219ae84a3 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
@@ -29,7 +29,6 @@ import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths
import java.util.Optional
-import java.util.Properties
import javax.xml.XMLConstants
import scala.collection.immutable.ArraySeq
import scala.jdk.CollectionConverters._
@@ -45,11 +44,8 @@ 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.api.validation.Validator
-import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.lib.exceptions.UsageException
import org.apache.daffodil.sapi.SAXErrorHandlerForSAPITest
-import org.apache.daffodil.validation.NoValidator
import org.apache.commons.io.FileUtils
import org.junit.Assert.assertArrayEquals
@@ -155,7 +151,7 @@ class TestAPI {
val dp = reserializeDataProcessor(dp1)
.withDebuggerRunner(debugger)
.withDebugging(true)
- .withValidator(NoValidator)
+ .withValidation("off")
val file = getResource("/test/api/myData.dat")
val fis = new java.io.FileInputStream(file)
@@ -205,7 +201,7 @@ class TestAPI {
.reload(savedParser)
.withDebuggerRunner(debugger)
.withDebugging(true)
- .withValidator(NoValidator)
+ .withValidation("off")
val file = getResource("/test/api/myData.dat")
// This test uses a byte array here, just so as to be sure to exercise
// the constructor for creating an InputSourceDataInputStream from a byte
array
@@ -616,7 +612,7 @@ class TestAPI {
val dp = reserializeDataProcessor(dp1)
.withDebuggerRunner(debugger)
.withDebugging(true)
- .withValidator(NoValidator)
+ .withValidation("off")
val file = getResource("/test/api/myData.dat")
val fis = new java.io.FileInputStream(file)
@@ -649,7 +645,7 @@ class TestAPI {
.withExternalVariables(extVarsFile)
.withDebuggerRunner(debugger)
.withDebugging(true)
- .withValidator(NoValidator)
+ .withValidation("off")
val file = getResource("/test/api/myData.dat")
val fis = new java.io.FileInputStream(file)
@@ -681,7 +677,7 @@ class TestAPI {
.withExternalVariables(extVarFile)
.withDebuggerRunner(debugger)
.withDebugging(true)
- .withValidator(NoValidator)
+ .withValidation("off")
val file = getResource("/test/api/myData.dat")
val fis = new java.io.FileInputStream(file)
@@ -730,13 +726,7 @@ class TestAPI {
val parser = compiler.reload(input)
try {
- parser.withValidator(
- Validators
- .get("xerces")
- .make({
- makeConfig(schemaFile)
- })
- )
+ parser.withValidation("xerces", schemaFile.toURI)
fail()
} catch {
case e: InvalidUsageException =>
@@ -747,12 +737,6 @@ class TestAPI {
}
}
- private def makeConfig(schemaFile: File) = {
- val props = new Properties()
- props.setProperty(Validator.rootSchemaKey, schemaFile.toURI.toString)
- props
- }
-
@Test
def testAPI15(): Unit = {
val debugger = new DebuggerRunnerForAPITest()
@@ -790,8 +774,7 @@ class TestAPI {
val schemaFile = getResource("/test/api/mySchema1.dfdl.xsd")
val pf = c.compileFile(schemaFile)
val dp1 = pf.onPath("/")
- val dp = reserializeDataProcessor(dp1)
- .withValidator(Validators.get("limited").make(new Properties()))
+ val dp = reserializeDataProcessor(dp1).withValidation("limited")
val file = getResource("/test/api/myData.dat")
val fis = new java.io.FileInputStream(file)
Using.resource(Infoset.getInputSourceDataInputStream(fis)) { input =>
@@ -816,9 +799,7 @@ class TestAPI {
val schemaFile = getResource("/test/api/mySchema1.dfdl.xsd")
val pf = c.compileFile(schemaFile)
val dp1 = pf.onPath("/")
- val dp = dp1.withValidator(
- Validators.get("xerces").make(makeConfig(schemaFile))
- )
+ val dp = dp1.withValidation("xerces", schemaFile.toURI)
val file = getResource("/test/api/myData.dat")
val fis = new java.io.FileInputStream(file)
Using.resource(Infoset.getInputSourceDataInputStream(fis)) { input =>
@@ -1328,10 +1309,7 @@ class TestAPI {
val schemaFile = getResource("/test/api/blob.dfdl.xsd")
val pf = c.compileFile(schemaFile)
val dp1 = pf.onPath("/")
- val dp = dp1
- .withValidator(
- Validators.get("xerces").make(makeConfig(schemaFile))
- )
+ val dp = dp1.withValidation("xerces", schemaFile.toURI)
val data = Array[Byte](0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04)
val bis = new ByteArrayInputStream(data)
@@ -1438,8 +1416,7 @@ class TestAPI {
val uri = new URI("/test/api/mySchema1.dfdl.xsd")
val pf = c.compileSource(uri)
val dp1 = pf.onPath("/")
- val dp =
-
dp1.withValidator(Validators.get("xerces").make(makeConfig(getResource(uri.getPath))))
+ val dp = dp1.withValidation("xerces", getResource(uri.getPath).toURI)
val file = getResource("/test/api/myDataBroken.dat")
val fis = new java.io.FileInputStream(file)
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorApiExample.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorApiExample.scala
deleted file mode 100644
index 3f2dd2b75..000000000
---
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorApiExample.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.daffodil.sexample
-
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-class ValidatorApiExample extends ValidatorExamplesSupport {
- @Test
- def testAlwaysPass(): Unit =
- withSchema("/test/api/mySchema5.dfdl.xsd") { dp =>
- withInput("/test/api/myData5.dat") { input =>
- val res = dp.withValidator(Always.passes).parse(input, `/dev/null`)
- assertFalse(res.isValidationError())
- }
- }
-
- @Test
- def testAlwaysFail(): Unit =
- withSchema("/test/api/mySchema5.dfdl.xsd") { dp =>
- withInput("/test/api/myData5.dat") { input =>
- val res = dp.withValidator(Always.fails).parse(input, `/dev/null`)
- assertTrue(res.isValidationError())
- }
- }
-}
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorExamplesSupport.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorExamplesSupport.scala
index 39ce287a2..041d0f460 100644
---
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorExamplesSupport.scala
+++
b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorExamplesSupport.scala
@@ -62,21 +62,6 @@ class CustomValidatorFactory extends ValidatorFactory {
def make(config: Properties): Validator = new CustomValidator
}
-class AlwaysValidator(s: Seq[String]) extends Validator {
- def validateXML(
- document: InputStream,
- validationHandler: ValidationHandler
- ): Unit =
- s.foreach(validationHandler.validationError(_))
-}
-
-object Always {
- def fails: Validator = (_: InputStream, vh: ValidationHandler) =>
vh.validationError("boom")
- def passes: Validator = (_: InputStream, vh: ValidationHandler) => {
- // do nothing
- }
-}
-
class PassingValidatorFactory extends ValidatorFactory {
def name(): String = PassingValidator.name
def make(config: Properties): Validator = new TestingValidatorSPI(Seq.empty)
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorSpiExample.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorSpiExample.scala
index 93f77ef75..10865543a 100644
---
a/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorSpiExample.scala
+++
b/daffodil-core/src/test/scala/org/apache/daffodil/sexample/ValidatorSpiExample.scala
@@ -17,10 +17,6 @@
package org.apache.daffodil.sexample
-import java.util.Properties
-
-import org.apache.daffodil.api.validation.Validators
-
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
@@ -32,8 +28,7 @@ class ValidatorSpiExample extends ValidatorExamplesSupport {
def testAlwaysPass(): Unit =
withSchema("/test/api/mySchema5.dfdl.xsd") { dp =>
withInput("/test/api/myData5.dat") { input =>
- val v = Validators.get(PassingValidator.name).make(new Properties())
- val res = dp.withValidator(v).parse(input, `/dev/null`)
+ val res = dp.withValidation(PassingValidator.name).parse(input,
`/dev/null`)
assertFalse(res.isValidationError())
}
}
@@ -42,8 +37,7 @@ class ValidatorSpiExample extends ValidatorExamplesSupport {
def testAlwaysFail(): Unit =
withSchema("/test/api/mySchema5.dfdl.xsd") { dp =>
withInput("/test/api/myData5.dat") { input =>
- val v = Validators.get(FailingValidator.name).make(new Properties())
- val res = dp.withValidator(v).parse(input, `/dev/null`)
+ val res = dp.withValidation(FailingValidator.name).parse(input,
`/dev/null`)
assertTrue(res.isValidationError())
}
}
diff --git
a/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidatorFactory.scala
b/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidatorFactory.scala
index 84f916ece..c1b145542 100644
---
a/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidatorFactory.scala
+++
b/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidatorFactory.scala
@@ -29,35 +29,25 @@ import net.sf.saxon.TransformerFactoryImpl
/**
* Daffodil ValidatorFactory implementation for ISO schematron.
- * svrl.file is optional, and if provided a schematron report will be written
there.
- * If schematron is defined it will use that and expect it to be a .sch file.
- * If that's not defined, it will use daffodil.rootSchema and attempt to
extract embedded schematron rules
+ * schematron.svrl.file is optional, and if provided a schematron report will
be written there.
+ * schematron property must be defined, which can either be a .sch file or a
DFDL file with
+ * embedded schematron rules.
*
* Configuration
*
* <ul>
* <li>schematron=uri_string_to_schematron_file</li>
* <li>schematron.svrl.file=uri_string_to_output_file</li>
- * <li>daffodil.rootSchema=schema_file_uri_string</li>
* </ul>
*/
object SchematronValidatorFactory {
def makeValidator(config: Properties): SchematronValidator = {
-
- if (config == null) {
- throw new api.validation.ValidatorInitializationException(
- "invalid configuration: missing schematron path"
- )
- }
-
val schPathValue = config.getProperty(SchematronValidator.name)
- lazy val defaultSchema =
config.getProperty(api.validation.Validator.rootSchemaKey)
val schUri = new URI({
if (!Misc.isNullOrBlank(schPathValue)) schPathValue
- else if (!Misc.isNullOrBlank(defaultSchema)) defaultSchema
else
throw new api.validation.ValidatorInitializationException(
- "invalid configuration: schematron path was not an object or string"
+ "invalid configuration: schematron property is empty or not defined"
)
})
val schStream =
@@ -94,8 +84,15 @@ object SchematronValidatorFactory {
): SchematronValidator = {
val factory = new TransformerFactoryImpl()
factory.setURIResolver(DFDLCatalogResolver.get)
- val rules = Transforms.from(schematron, schematronID, srcfmt, factory)
- new SchematronValidator(Schematron.fromRules(rules), svrlPath)
+ try {
+ val rules = Transforms.from(schematron, schematronID, srcfmt, factory)
+ new SchematronValidator(Schematron.fromRules(rules), svrlPath)
+ } catch {
+ case e: Exception =>
+ throw new api.validation.ValidatorInitializationException(
+ s"failed to create schematron validator: " + e.getMessage
+ )
+ }
}
}
diff --git
a/daffodil-schematron/src/test/scala/org/apache/daffodil/validation/schematron/EmbeddedTesting.scala
b/daffodil-schematron/src/test/scala/org/apache/daffodil/validation/schematron/EmbeddedTesting.scala
index fb7344235..ac9b4416e 100644
---
a/daffodil-schematron/src/test/scala/org/apache/daffodil/validation/schematron/EmbeddedTesting.scala
+++
b/daffodil-schematron/src/test/scala/org/apache/daffodil/validation/schematron/EmbeddedTesting.scala
@@ -27,7 +27,6 @@ import org.apache.daffodil.api.Diagnostic
import org.apache.daffodil.api.ParseResult
import org.apache.daffodil.api.infoset.Infoset
import org.apache.daffodil.lib.util.Misc
-import org.apache.daffodil.validation.schematron.SchSource.Xsd
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -75,12 +74,7 @@ trait EmbeddedTesting {
if (pf.isError()) pf.getDiagnostics.forEach(println)
assertFalse("Schema did not compile", pf.isError())
- val v = SchematronValidatorFactory.makeValidator(
- schema.toURL.openStream(),
- schema.toURL.toString(),
- Xsd
- )
- val dp = pf.onPath("/").withValidator(v)
+ val dp = pf.onPath("/").withValidation("schematron", schema)
f(Validation(dp))
}
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 b4241d766..f1bdd391b 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
@@ -28,7 +28,6 @@ import java.nio.CharBuffer
import java.nio.LongBuffer
import java.nio.charset.CoderResult
import java.nio.charset.StandardCharsets
-import java.util.Properties
import scala.collection.mutable
import scala.jdk.CollectionConverters._
import scala.language.postfixOps
@@ -41,8 +40,6 @@ import scala.xml.NodeSeq.seqToNodeSeq
import scala.xml.SAXParseException
import org.apache.daffodil.api
-import org.apache.daffodil.api.validation.Validator
-import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.io.FormatInfo
import org.apache.daffodil.io.InputSourceDataInputStream
import org.apache.daffodil.io.processors.charset.BitsCharsetDecoder
@@ -412,10 +409,6 @@ class DFDLTestSuite private[tdml] (
val str = (ts \ "@defaultValidation").text
if (str == "") defaultValidationDefault else str
}
- lazy val defaultValidatorName = defaultValidation match {
- case "on" => "xerces"
- case m => m
- }
lazy val defaultConfig = {
val str = (ts \ "@defaultConfig").text
@@ -588,13 +581,10 @@ class DFDLTestSuite private[tdml] (
GlobalTDMLCompileResultCache.cache
}
- val props = new Properties()
- props.setProperty(Validator.rootSchemaKey,
suppliedSchema.uriForLoading.toString)
-
val compileResult = cache.getCompileResult(
impl,
key,
- Validators.get(defaultValidatorName).make(props)
+ defaultValidation
)
compileResult
}
@@ -634,7 +624,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent:
DFDLTestSuite) {
protected final var processor: TDMLDFDLProcessor = null
lazy val defaultRoundTrip: RoundTrip = parent.defaultRoundTrip
- lazy val defaultValidatorName: String = parent.defaultValidatorName
+ lazy val defaultValidation: String = parent.defaultValidation
lazy val defaultIgnoreUnexpectedWarnings: Boolean =
parent.defaultIgnoreUnexpectedWarnings
lazy val defaultIgnoreUnexpectedValidationErrors: Boolean =
parent.defaultIgnoreUnexpectedValidationErrors
@@ -768,19 +758,10 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent:
DFDLTestSuite) {
case "false" => false
case _ => false
}
- lazy val validatorName: String = (testCaseXML \ "@validation").text match {
- case "" => defaultValidatorName
- case "on" => "xerces"
+ lazy val validation: String = (testCaseXML \ "@validation").text match {
+ case "" => defaultValidation
case mode => mode
}
- lazy val validator: api.validation.Validator =
- Validators
- .get(validatorName)
- .make({
- val props = new Properties()
- props.setProperty(Validator.rootSchemaKey,
getSuppliedSchema().uriForLoading.toString)
- props
- })
protected def runProcessor(
compileResult: TDML.CompileResult,
@@ -789,7 +770,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent:
DFDLTestSuite) {
errors: Option[Seq[ExpectedErrors]],
warnings: Option[Seq[ExpectedWarnings]],
validationErrors: Option[Seq[ExpectedValidationErrors]],
- validatorName: String,
+ validation: String,
roundTrip: RoundTrip,
implString: Option[String]
): Unit
@@ -954,8 +935,8 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent:
DFDLTestSuite) {
}
val useSerializedProcessor =
- if (validatorName == "xerces") false
- else if (defaultValidatorName == "xerces") false
+ if (validation == "on") false
+ else if (defaultValidation == "on") false
else if (optExpectedWarnings.isDefined) false
else true
@@ -994,7 +975,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent:
DFDLTestSuite) {
optExpectedErrors,
optExpectedWarnings,
optExpectedValidationErrors,
- validatorName,
+ validation,
roundTrip,
implString
)
@@ -1074,7 +1055,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
optExpectedErrors: Option[Seq[ExpectedErrors]],
optExpectedWarnings: Option[Seq[ExpectedWarnings]],
optExpectedValidationErrors: Option[Seq[ExpectedValidationErrors]],
- validatorName: String,
+ validation: String,
roundTrip: RoundTrip,
implString: Option[String]
) = {
@@ -1105,7 +1086,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
nBits,
optExpectedWarnings,
optExpectedValidationErrors,
- validator,
+ validation,
roundTrip,
implString,
diags.asScala
@@ -1132,7 +1113,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
optExpectedErrors,
optExpectedWarnings,
optExpectedValidationErrors,
- validator,
+ validation,
implString,
diags.asScala
)
@@ -1153,7 +1134,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
optErrors: Option[Seq[ExpectedErrors]],
optWarnings: Option[Seq[ExpectedWarnings]],
optValidationErrors: Option[Seq[ExpectedValidationErrors]],
- validator: api.validation.Validator,
+ validation: String,
implString: Option[String],
compileWarnings: Iterable[api.Diagnostic]
): Unit = {
@@ -1161,7 +1142,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
try {
processor = processor
.withExternalDFDLVariables(externalVarBindings)
- .withValidator(validator)
+ .withValidation(validation)
} catch {
case e: Exception => throw TDMLException(e, implString)
}
@@ -1380,7 +1361,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
lengthLimitInBits: Long,
warnings: Option[Seq[ExpectedWarnings]],
validationErrors: Option[Seq[ExpectedValidationErrors]],
- validator: api.validation.Validator,
+ validation: String,
roundTripArg: RoundTrip,
implString: Option[String],
compileWarnings: Iterable[api.Diagnostic]
@@ -1389,7 +1370,7 @@ case class ParserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
val roundTrip =
roundTripArg // change to OnePassRoundTrip to force all parse tests to
round trip (to see which fail to round trip)
- processor = processor.withValidator(validator)
+ processor = processor.withValidation(validation)
val firstParseTestData = IOUtils.toByteArray(dataToParse)
val testInfoset = optExpectedInfoset.get
@@ -1576,7 +1557,7 @@ case class UnparserTestCase(ptc: NodeSeq, parentArg:
DFDLTestSuite)
optErrors: Option[Seq[ExpectedErrors]],
optWarnings: Option[Seq[ExpectedWarnings]],
optValidationErrors: Option[Seq[ExpectedValidationErrors]],
- validatorName: String,
+ validation: String,
roundTrip: RoundTrip,
implString: Option[String]
) = {
@@ -3100,7 +3081,7 @@ case class
TDMLCompileResultCache(entryExpireDurationSeconds: Option[Long]) {
def getCompileResult(
impl: AbstractTDMLDFDLProcessorFactory,
key: TDMLCompileResultCacheKey,
- defaultValidator: api.validation.Validator
+ defaultValidation: String
): TDML.CompileResult = this.synchronized {
if (entryExpireDurationSeconds.isDefined) {
@@ -3145,7 +3126,7 @@ case class
TDMLCompileResultCache(entryExpireDurationSeconds: Option[Long]) {
// have to rebuild it for every test. This saves memory and should be
significantly
// faster.
val value = compileResult.map { case (diags, proc) =>
- (diags, proc.withValidator(defaultValidator))
+ (diags, proc.withValidation(defaultValidation))
}
cache += (key -> TDMLCompileResultCacheValue(value, None))
value
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 26a65dbb0..d64e35779 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
@@ -77,7 +77,7 @@ trait TDMLDFDLProcessor {
def withDebugger(db: AnyRef): R
- def withValidator(validator: api.validation.Validator): R
+ def withValidation(validation: String): R
def withExternalDFDLVariables(externalVarBindings: Seq[Binding]): R
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 41367b307..e707583ba 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
@@ -126,7 +126,7 @@ final class DaffodilCTDMLDFDLProcessor(executable: os.Path)
extends TDMLDFDLProc
override def withDebugging(onOff: Boolean): R = this
override def withTracing(onOff: Boolean): R = this
override def withDebugger(db: AnyRef): R = this
- override def withValidator(validator: api.validation.Validator): R = this
+ override def withValidation(validation: String): R = this
override def withExternalDFDLVariables(externalVarBindings: Seq[Binding]): R
= this
// Parses the input stream to an infoset and returns a TDMLParseResult
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 84bf07728..4b46739e2 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
@@ -20,6 +20,7 @@ package org.apache.daffodil.processor.tdml
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.OutputStreamWriter
+import java.net.URI
import java.nio.channels.Channels
import java.nio.charset.StandardCharsets
import java.nio.file.Files
@@ -104,7 +105,8 @@ final class TDMLDFDLProcessorFactory private (
*/
private def generateProcessor(
pf: DFDL.ProcessorFactory,
- useSerializedProcessor: Boolean
+ useSerializedProcessor: Boolean,
+ schemaSource: DaffodilSchemaSource
): TDML.CompileResult = {
val p = pf.onPath("/")
if (p.isError) {
@@ -121,7 +123,11 @@ final class TDMLDFDLProcessorFactory private (
} else p
}
val diags = p.getDiagnostics
- Right((diags, new
DaffodilTDMLDFDLProcessor(dp.asInstanceOf[DFDL.DataProcessor])))
+ val processor = new DaffodilTDMLDFDLProcessor(
+ dp.asInstanceOf[DFDL.DataProcessor],
+ schemaSource.uriForLoading
+ )
+ Right(diags, processor)
}
}
@@ -136,7 +142,7 @@ final class TDMLDFDLProcessorFactory private (
val diags = pf.getDiagnostics
Left(diags)
} else {
- val res = this.generateProcessor(pf, useSerializedProcessor)
+ val res = this.generateProcessor(pf, useSerializedProcessor,
schemaSource)
res
}
}
@@ -156,20 +162,25 @@ final class TDMLDFDLProcessorFactory private (
val dp = compiler.reload(schemaSource)
val diags = dp.getDiagnostics
Assert.invariant(diags.asScala.forall { !_.isError })
- Right((diags, new
DaffodilTDMLDFDLProcessor(dp.asInstanceOf[DFDL.DataProcessor])))
+ val processor = new DaffodilTDMLDFDLProcessor(
+ dp.asInstanceOf[DFDL.DataProcessor],
+ schemaSource.uriForLoading
+ )
+ Right(diags, processor)
}
}
}
-class DaffodilTDMLDFDLProcessor private (private var dp: api.DataProcessor)
+class DaffodilTDMLDFDLProcessor private (private var dp: api.DataProcessor,
schemaURI: URI)
extends TDMLDFDLProcessor {
override type R = DaffodilTDMLDFDLProcessor
- def this(ddp: DFDL.DataProcessor) = this(ddp.asInstanceOf[api.DataProcessor])
+ def this(ddp: DFDL.DataProcessor, schemaURI: URI) =
+ this(ddp.asInstanceOf[api.DataProcessor], schemaURI)
- private def copy(dp: api.DataProcessor = dp) = new
DaffodilTDMLDFDLProcessor(dp)
+ private def copy(dp: api.DataProcessor = dp) = new
DaffodilTDMLDFDLProcessor(dp, schemaURI)
private lazy val builtInTracer =
new InteractiveDebugger(
@@ -204,10 +215,13 @@ class DaffodilTDMLDFDLProcessor private (private var dp:
api.DataProcessor)
copy(dp = dp.withDebugger(d))
}
- override def withValidator(
- validator: api.validation.Validator
- ): DaffodilTDMLDFDLProcessor =
- copy(dp = dp.withValidator(validator))
+ override def withValidation(validation: String): DaffodilTDMLDFDLProcessor =
{
+ val validatorName = validation match {
+ case "on" => "xerces"
+ case _ => validation
+ }
+ copy(dp = dp.withValidation(validatorName, schemaURI))
+ }
override def withExternalDFDLVariables(
externalVarBindings: Seq[Binding]
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
index 53c0eac7c..0d27c1151 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/infoset/TestStringAsXml.scala
@@ -21,11 +21,8 @@ import java.io.ByteArrayOutputStream
import java.io.InputStream
import java.net.URI
import java.nio.charset.StandardCharsets
-import java.util.Properties
import scala.jdk.CollectionConverters._
-import org.apache.daffodil.api.validation.Validator
-import org.apache.daffodil.api.validation.Validators
import org.apache.daffodil.core.compiler.Compiler
import org.apache.daffodil.io.InputSourceDataInputStream
import org.apache.daffodil.lib.iapi.URISchemaSource
@@ -45,13 +42,8 @@ class TestStringAsXml {
URISchemaSource(Misc.uriToDiagnosticFile(dfdlSchemaURI), dfdlSchemaURI)
)
val dp = pf.onPath("/")
- val props = new Properties()
- if (validatingSchema != null) {
- props.setProperty(Validator.rootSchemaKey, validatingSchema.toString)
- } else {
- props.setProperty(Validator.rootSchemaKey, dfdlSchemaURI.toString)
- }
- dp.withValidator(Validators.get("xerces").make(props))
+ val schema = if (validatingSchema != null) validatingSchema else
dfdlSchemaURI
+ dp.withValidation("xerces", schema)
}