You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by sl...@apache.org on 2019/06/04 11:38:38 UTC
[incubator-daffodil] branch master updated: Generate
DaffodilTunables and WarnID from dafext.xsd
This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git
The following commit(s) were added to refs/heads/master by this push:
new db7b1ea Generate DaffodilTunables and WarnID from dafext.xsd
db7b1ea is described below
commit db7b1eac516c3de16fe58d87804ec799fac382a5
Author: Steve Lawrence <sl...@apache.org>
AuthorDate: Wed May 15 08:09:29 2019 -0400
Generate DaffodilTunables and WarnID from dafext.xsd
- Add Tuanble and WarnID generators to generate code based on
dafext.xsd. This makes adding new warnings or tunables much easier,
and the schema acts as documentation.
- Modifies the parseUnparsePolicy tunable to add a "fromRoot" value,
which is the new default. The old default of empty string is no longer
supported.
- Generates ParseUnparsePolicy and UnqualifyPathStepPolicy tunable
enums, which are also now props.Enums to gets improved enum
functionality and allows for consistent logic in the generator
- Cleaned up the dafext.xsd schema, added tunable documentation and
default values
DAFFODIL-2117
---
.../org/apache/daffodil/compiler/Compiler.scala | 46 +-
.../org/apache/daffodil/general/TestTunables.scala | 4 +-
.../org/apache/daffodil/api/DaffodilTunables.scala | 310 ------------
.../daffodil/api/UnqualifiedPathStepPolicy.scala | 44 --
.../scala/org/apache/daffodil/api/WarnID.scala | 98 ----
.../resources/org/apache/daffodil/xsd/dafext.xsd | 548 +++++++++++++++------
.../daffodil/propGen/PropertyGenerator.scala | 34 +-
.../apache/daffodil/propGen/TunableGenerator.scala | 292 +++++++++++
.../apache/daffodil/propGen/WarnIDGenerator.scala | 85 ++++
9 files changed, 849 insertions(+), 612 deletions(-)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala b/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
index 18f236f..521e7a7 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
@@ -17,24 +17,44 @@
package org.apache.daffodil.compiler
-import java.io.{ File, FileInputStream, ObjectInputStream, StreamCorruptedException }
+import java.io.File
+import java.io.FileInputStream
+import java.io.ObjectInputStream
+import java.io.StreamCorruptedException
import java.nio.channels.Channels
-import java.util.zip.{ GZIPInputStream, ZipException }
+import java.util.zip.GZIPInputStream
+import java.util.zip.ZipException
import scala.collection.mutable.Queue
import scala.xml.Node
import org.apache.daffodil.ExecutionMode
-import org.apache.daffodil.api.{ DFDL, DaffodilSchemaSource, DaffodilTunables, URISchemaSource, UnitTestSchemaSource, ValidationMode }
-import org.apache.daffodil.dsom.{ ElementBase, SchemaComponent, SchemaComponentImpl, SchemaSet }
+import org.apache.daffodil.api.DFDL
+import org.apache.daffodil.api.DaffodilSchemaSource
+import org.apache.daffodil.api.DaffodilTunables
+import org.apache.daffodil.api.URISchemaSource
+import org.apache.daffodil.api.UnitTestSchemaSource
+import org.apache.daffodil.api.ValidationMode
+import org.apache.daffodil.api.ParseUnparsePolicyTunable
+import org.apache.daffodil.dsom.ElementBase
+import org.apache.daffodil.dsom.SchemaComponent
+import org.apache.daffodil.dsom.SchemaComponentImpl
+import org.apache.daffodil.dsom.SchemaSet
import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.externalvars.{ Binding, ExternalVariablesLoader }
+import org.apache.daffodil.externalvars.Binding
+import org.apache.daffodil.externalvars.ExternalVariablesLoader
import org.apache.daffodil.oolag.OOLAG
-import org.apache.daffodil.processors.{ DataProcessor, Processor, SchemaSetRuntimeData, SerializableDataProcessor, VariableMap }
+import org.apache.daffodil.processors.DataProcessor
+import org.apache.daffodil.processors.Processor
+import org.apache.daffodil.processors.SchemaSetRuntimeData
+import org.apache.daffodil.processors.SerializableDataProcessor
+import org.apache.daffodil.processors.VariableMap
import org.apache.daffodil.processors.parsers.NotParsableParser
import org.apache.daffodil.processors.unparsers.NotUnparsableUnparser
import org.apache.daffodil.schema.annotation.props.gen.ParseUnparsePolicy
-import org.apache.daffodil.util.{ LogLevel, Logging, Misc }
+import org.apache.daffodil.util.LogLevel
+import org.apache.daffodil.util.Logging
+import org.apache.daffodil.util.Misc
import org.apache.daffodil.xml._
/**
@@ -61,12 +81,12 @@ final class ProcessorFactory(val sset: SchemaSet)
final override def enclosingComponentDef: Option[SchemaComponent] = None
lazy val (generateParser, generateUnparser) = {
- val (context, policy) =
- if (tunable.parseUnparsePolicy.isDefined) {
- (None, tunable.parseUnparsePolicy.get)
- } else {
- (Some(rootElem), rootElem.rootParseUnparsePolicy)
- }
+ val (context, policy) = tunable.parseUnparsePolicy match {
+ case ParseUnparsePolicyTunable.FromRoot => (Some(rootElem), rootElem.rootParseUnparsePolicy)
+ case ParseUnparsePolicyTunable.ParseOnly => (None, ParseUnparsePolicy.ParseOnly)
+ case ParseUnparsePolicyTunable.UnparseOnly => (None, ParseUnparsePolicy.UnparseOnly)
+ case ParseUnparsePolicyTunable.Both => (None, ParseUnparsePolicy.Both)
+ }
rootElem.checkParseUnparsePolicyCompatibility(context, policy)
policy match {
case ParseUnparsePolicy.Both => (true, true)
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/general/TestTunables.scala b/daffodil-core/src/test/scala/org/apache/daffodil/general/TestTunables.scala
index c434c15..e300987 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/general/TestTunables.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/general/TestTunables.scala
@@ -85,8 +85,8 @@ class TestTunables extends Logging {
}
@Test def testTunableSuppressionListCopying() {
- val t1 = DaffodilTunables("suppressschemadefinitionwarnings", "escapeSchemeRefUndefined")
- val t2 = DaffodilTunables("suppressschemadefinitionwarnings", "all")
+ val t1 = DaffodilTunables("suppressSchemaDefinitionWarnings", "escapeSchemeRefUndefined")
+ val t2 = DaffodilTunables("suppressSchemaDefinitionWarnings", "all")
val w1 = t1.suppressSchemaDefinitionWarnings.mkString(",")
val w2 = t2.suppressSchemaDefinitionWarnings.mkString(",")
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala
index b08a6ff..6a9c064 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/api/DaffodilTunables.scala
@@ -15,313 +15,3 @@
* limitations under the License.
*/
-package org.apache.daffodil.api
-
-import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.schema.annotation.props.gen.ParseUnparsePolicy
-import org.apache.daffodil.util.LogLevel
-import org.apache.daffodil.util.Logging
-import org.apache.daffodil.util.Misc
-import org.apache.daffodil.xml.DaffodilXMLLoader
-import org.apache.daffodil.schema.annotation.props.EmptyElementParsePolicy
-
-object DaffodilTunables {
-
- def apply(tunables: Map[String, String]): DaffodilTunables = {
- apply().setTunables(tunables)
- }
-
- def apply(tunable: String, value: String): DaffodilTunables = {
- apply().setTunable(tunable, value)
- }
-
- def apply(): DaffodilTunables = {
- // override tunables from the global configuration file on the class path, if it exists
- val (configOpt, _) = Misc.getResourceOption("/daffodil-config.xml")
- val configTunables: Map[String, String] =
- if (configOpt.isDefined) {
- val loader = new DaffodilXMLLoader()
- val node = loader.load(URISchemaSource(configOpt.get))
- val trimmed = scala.xml.Utility.trim(node)
- val tunablesNode = (trimmed \ "tunables").headOption
- val tunablesMap: Map[String, String] = tunablesNode match {
- case None => Map.empty
- case Some(tunableNode) => {
- tunableNode.child.map { n => (n.label, n.text) }.toMap
- }
- }
- tunablesMap
- } else {
- Map.empty
- }
-
- new DaffodilTunables().setTunables(configTunables)
- }
-}
-
-case class DaffodilTunables(
- val maxSkipLengthInBytes: Long = 1024, // applicable to leadingSkip and trailingSkip
- val maxBinaryDecimalVirtualPoint: Int = 200, // Can be as large as Int.MaxValue
- val minBinaryDecimalVirtualPoint: Int = -200, // Can be as small as Int.MinValue
- val generatedNamespacePrefixStem: String = "tns",
- val readerByteBufferSize: Long = 8192,
- //
- // If true, require that the bitOrder property is specified. If false, use a
- // default value for bitOrder if not defined in a schema
- //
- // Looks to be compile-time as it gets 'tunable' from Term.
- //
- val requireBitOrderProperty: Boolean = false,
- //
- // If true, require that the choiceDispatchKeyKind property is specified. If false, use a
- // default value for bitOrder if not defined in a schema
- //
- // Looks to be compile-time as it gets 'tunable' from Term.
- //
- val requireChoiceDispatchKeyKindProperty: Boolean = false,
- //
- // If true, require that the choiceBranchKeyKind property is specified. If false, use a
- // default value for bitOrder if not defined in a schema
- //
- // Looks to be compile-time as it gets 'tunable' from Term.
- //
- val requireChoiceBranchKeyKindProperty: Boolean = false,
- //
- // If true, require that the encodingErrorPolicy property is specified. If
- // false, use a default value not defined in a schema and warn about missing property
- //
- // Looks to be compile-time as it gets 'tunable' from Term.
- //
- val requireEncodingErrorPolicyProperty: Boolean = false,
- //
- // If true, require that the encodingErrorPolicy property is specified. If
- // false, warn about missing property
- //
- // Looks to be compile-time as it gets 'tunable' from Term.
- //
- val requireTextBidiProperty: Boolean = false,
- //
- // If true, require that the encodingErrorPolicy property is specified. If
- // false, warn about missing property
- //
- // Looks to be compile-time as it gets 'tunable' from Term.
- //
- val requireFloatingProperty: Boolean = false,
- //
- // If true, require that the emptyElementParsePolicy property is specified. If
- // false, warn about missing property
- //
- val requireEmptyElementParsePolicyProperty: Boolean = false,
- val defaultEmptyElementParsePolicy: EmptyElementParsePolicy = EmptyElementParsePolicy.TreatAsEmpty,
- //
- // Whether to compile a schema to support parsing, unparsing, both, or to use
- // the daf:parseUnparsePolicy from the root node. None means to use the
- // policy from the schema, otherwise use whatever the value is
- //
- // Looks to be compile-time. Set in Compiler.
- ///
- val parseUnparsePolicy: Option[ParseUnparsePolicy] = None,
- val maxFieldContentLengthInBytes: Long = 1024 * 1024, // Can be as large as Int.MaxValue
- val defaultInitRegexMatchLimitInChars: Long = 32,
- val maxDataDumpSizeInBytes: Long = 256,
- val maxOccursBounds: Long = Int.MaxValue, // Can be as large as Int.MaxValue
- //
- // When unexpected text is found where a delimiter is expected, this is the maximum
- // number of bytes (characters) to display when the expected delimiter is a variable
- // length delimiter.
- //
- val maxLengthForVariableLengthDelimiterDisplay: Int = 10, // will display this number of bytes
- //
- // In certain I/O optimized situations (text-only, encodingErrorPolicy='replace', fixed-width encoding)
- // input files larger than this will be mmapped. Input files smaller than this
- // will be simply read using ordinary I/O (because for small files that is just faster).
- // This exists because mmap is more expensive than ordinary I/O for small files.
- //
- val inputFileMemoryMapLowThreshold: Long = 32 * 1024 * 1024, // 32Meg
- //
- // TODO: In the future, when we can stream and handle input larger than the JVM single
- // object limits, input files larger than this will be streamed, i.e., using java.io.InputStream.
- // They will not be memory mapped. A CharBuffer 2x larger may be created, and that
- // cannot exceed the JVM maximum size, so this has to be no bigger (and perhaps quite a bit
- // smaller) than 1/2 the maximum JVM object size.
- //
- // val inputFileMemoryMapHighThreshold: Long = 256 * 1024 * 1024, // 256 Meg
-
- //
- // Initial array buffer size allocated for recurring elements (aka arrays)
- //
- // Applies to InfosetImpl, as such is a run-time thing
- //
- val initialElementOccurrencesHint: Long = 10,
- val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy.Type = UnqualifiedPathStepPolicy.NoNamespace,
- val suppressSchemaDefinitionWarnings: List[WarnID] = Nil,
-
- // By default, path expressions in Daffodil will only work correctly if path
- // steps are used in an expression defined in the schema when compiled. To
- // enable the use of other expressions (e.g. during debugging, where not all
- // expressions are known at schema compile time), set this tunable to true.
- // This may cause a degredation of performance in path expression evaluation,
- // so this should be avoided when in production. This flag is automatically
- // enabled when debugging is enabled.
- val allowExternalPathExpressions: Boolean = false,
-
- // Daffodil supports Java 7+. This is essentially all version of java that
- // are in use, so we no longer have any unsupported java versions. This
- // tunable no longer has any affect and is only kept for backwards
- // compatability.
- val errorOnUnsupportedJavaVersion: Boolean = true,
-
- val maximumSimpleElementSizeInCharacters: Int = 1024 * 1024,
- val initialRegexMatchLimitInCharacters: Int = 64,
- val maximumRegexMatchLengthInCharacters: Int = 1024 * 1024,
-
- /* Due to differences in the DFDL spec and ICU4J SimpleDateFormat, we must have SimpleDateFormat
- * parse in lenient mode, which allows the year value to overflow with very large years
- * into possibly negative years. These tunables simply make sure that value we get back
- * from SimpleDateFormat are reasonable
- */
- val minValidYear: Int = 0,
- val maxValidYear: Int = 9999,
-
- /* Defines how Daffodil coerces expressions where the result type differs
- * from the expected type. As an example, assume the expected type of an
- * expression is an xs:string, but the expression is { 3 }. In this case, the
- * expression result is an xs:int, which should not be automatically coerced
- * to an xs:string. Instead, the expression should be { xs:string(3) } or { "3" }
- * If the value of this tunable is false, these types of expressions will
- * result in a schema definition error. If the value is true, Daffodil will
- * provide a warning and attempt to coerce the result type to the expected
- * type.
- */
- val allowExpressionResultCoercion: Boolean = true)
-
- extends Serializable
- with Logging {
-
- /* Appear to be Compile-Time as the tunable is obtained from:
- * Term, SchemaComponent, Element, etc.
- *
- * maxSkipLengthInBytes
- * maxBinaryDecimalVirtualPoint
- * minBinaryDecimalVirtualPoint
- * requireEncodingErrorPolicyProperty
- * requireBitOrderProperty
- * requireEmptyElementPolicyProperty
- * emptyElementParsePolicy
- * generatedNamespacePrefixStem
- * parseUnparsePolicy
- *
- * Used by StepQNameFactory. Appears to get tunable from:
- * Expressions's DPathCompileInfo
- * CompiledExpression's ElementRuntimeData
- *
- * unqualifiedPathStepPolicy
- *
- * Appear to be Run-Time as the tunable is obtained from:
- * PState/UState
- *
- * initialElementOccurrencesHint
- * maxOccursBounds
- * maxDataDumpSizeInBytes
- *
- * Only used in Main.scala for DataInputStream:
- *
- * maxFieldContentLengthInBytes
- *
- * DataInputStream objects:
- *
- * defaultInitRegexMatchLimitInChars
- *
- * Unused?
- *
- * maxLengthForVariableLengthDelimiterDisplay
- *
- * */
-
- def setTunables(tunables: Map[String, String]): DaffodilTunables = {
- var t = this
- tunables.foreach { case (k, v) => t = t.setTunable(k, v) }
- t
- }
-
- def setTunable(tunable: String, value: String): DaffodilTunables = {
- tunable.toLowerCase match {
- case "maxfieldcontentlengthinbytes" => this.copy(maxFieldContentLengthInBytes = java.lang.Long.valueOf(value))
- case "defaultinitialregexmatchlimitinchars" => this.copy(defaultInitRegexMatchLimitInChars = java.lang.Long.valueOf(value))
- case "maxdatadumpsizeinbytes" => this.copy(maxDataDumpSizeInBytes = java.lang.Long.valueOf(value))
- case "maxoccursbounds" => this.copy(maxOccursBounds = java.lang.Long.valueOf(value))
- case "maxlengthforvariablelengthdelimiterdisplay" => this.copy(maxLengthForVariableLengthDelimiterDisplay = java.lang.Integer.valueOf(value))
- case "inputfilememorymaplowthreshold" => this.copy(inputFileMemoryMapLowThreshold = java.lang.Long.valueOf(value))
- case "initialelementoccurrenceshint" => this.copy(initialElementOccurrencesHint = java.lang.Long.valueOf(value))
- case "unqualifiedpathsteppolicy" => {
- val policy = value.toLowerCase match {
- case "nonamespace" => UnqualifiedPathStepPolicy.NoNamespace
- case "defaultnamespace" => UnqualifiedPathStepPolicy.DefaultNamespace
- case "preferdefaultnamespace" => UnqualifiedPathStepPolicy.PreferDefaultNamespace
- case _ => Assert.usageError("Unknown value for unqualifiedPathStepPolicy tunable. Value must be \"noNamespace\", \"defaultNamespace\", or \"perferDefaultNamespace\".")
- }
- this.copy(unqualifiedPathStepPolicy = policy)
- }
- case "requirebitorderproperty" => this.copy(requireBitOrderProperty = java.lang.Boolean.valueOf(value))
- case "requirechoicedispatchkeykindproperty" => this.copy(requireChoiceDispatchKeyKindProperty = java.lang.Boolean.valueOf(value))
- case "requireencodingerrorpolicyproperty" => this.copy(requireEncodingErrorPolicyProperty = java.lang.Boolean.valueOf(value))
- case "requiretextbidiproperty" => this.copy(requireTextBidiProperty = java.lang.Boolean.valueOf(value))
- case "requirefloatingproperty" => this.copy(requireFloatingProperty = java.lang.Boolean.valueOf(value))
- case "requireemptyelementparsepolicyproperty" => this.copy(requireEmptyElementParsePolicyProperty = java.lang.Boolean.valueOf(value))
- case "defaultemptyelementparsepolicy" => {
- val policy = value.toLowerCase match {
- case "treatasmissing" => EmptyElementParsePolicy.TreatAsMissing
- case "treatasempty" => EmptyElementParsePolicy.TreatAsEmpty
- case _ => Assert.usageError("Unknown value for defaultEmptyElementParsePolicy tunable. Value must be \"treatAsMissing\" or \"treatAsEmpty\".")
- }
- this.copy(defaultEmptyElementParsePolicy = policy)
- }
- case "maxskiplengthinbytes" => this.copy(maxSkipLengthInBytes = java.lang.Long.valueOf(value))
- case "maxbinarydecimalvirtualpoint" => this.copy(maxBinaryDecimalVirtualPoint = java.lang.Integer.valueOf(value))
- case "minbinarydecimalvirtualpoint" => this.copy(minBinaryDecimalVirtualPoint = java.lang.Integer.valueOf(value))
- case "generatednamespaceprefixstem" => this.copy(generatedNamespacePrefixStem = value)
- case "readerbytebuffersize" => this.copy(readerByteBufferSize = java.lang.Long.valueOf(value))
- case "parseunparsepolicy" => {
- val policy = value.toLowerCase match {
- case "parseonly" => Some(ParseUnparsePolicy.ParseOnly)
- case "unparseonly" => Some(ParseUnparsePolicy.UnparseOnly)
- case "both" => Some(ParseUnparsePolicy.Both)
- case "schema" => None
- case _ => Assert.usageError("Unknown value for parseUnparsePolicy tunable. Value must be \"parseOnly\", \"unparseOnly\", \"both\", or \"schema\".")
- }
- this.copy(parseUnparsePolicy = policy)
- }
- case "suppressschemadefinitionwarnings" => {
- val ws = """\s+"""
- // value is whitespace separated list of warning identifier strings
- val warnIDs = value.split(ws).toSeq
-
- var warningsList: List[WarnID] = Nil
- warnIDs.foreach { warnIDString =>
- {
- WarnID.find(warnIDString) match {
- case None => log(LogLevel.Warning, "Ignoring unknown warning identifier: %s", warnIDString)
- case Some(foundID) => warningsList = foundID :: warningsList
- }
- }
- }
- this.copy(suppressSchemaDefinitionWarnings = warningsList)
- }
- case "allowexternalpathexpressions" => this.copy(allowExternalPathExpressions = java.lang.Boolean.valueOf(value))
- case "erroronunsupportedjavaversion" => this.copy(errorOnUnsupportedJavaVersion = java.lang.Boolean.valueOf(value))
- case "maximumsimpleelementsizeincharacters" => this.copy(maximumSimpleElementSizeInCharacters = java.lang.Integer.valueOf(value))
- case "initialregexmatchlimitincharacters" => this.copy(initialRegexMatchLimitInCharacters = java.lang.Integer.valueOf(value))
- case "maximumregexmatchlengthincharacters" => this.copy(maximumRegexMatchLengthInCharacters = java.lang.Integer.valueOf(value))
- case "allowexpressionresultcoercion" => this.copy(allowExpressionResultCoercion = java.lang.Boolean.valueOf(value))
- case _ => {
- log(LogLevel.Warning, "Ignoring unknown tunable: %s", tunable)
- this
- }
- }
- }
-
- def notSuppressedWarning(warnID: WarnID) =
- !suppressSchemaDefinitionWarnings.contains(warnID) &&
- !suppressSchemaDefinitionWarnings.contains(WarnID.All)
-
-}
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/api/UnqualifiedPathStepPolicy.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/api/UnqualifiedPathStepPolicy.scala
deleted file mode 100644
index ccd3776..0000000
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/api/UnqualifiedPathStepPolicy.scala
+++ /dev/null
@@ -1,44 +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.api
-
-import org.apache.daffodil.util.Enum
-
- /**
- * Specified how unqualified path steps are resolved.
- *
- * NoNamespace:
- * Unqualified path steps remain unqualified and will only match elements in
- * NoNamespace. A prefix must be provided to match namespaced elements.
- *
- * DefaultNamespace:
- * Unqualified path steps will always use the default namespace. If a default
- * namespace is defined, it is not possible to match a NoNamespace element
- * with this policy. Because of this, this may not work well with
- * elementFormDefault="unqualified".
- *
- * PreferDefaultNamespace
- * Attempt to use the default namespace to resolve a step. If that fails to
- * match an element, then try to resolve using NoNamespace.
- */
- object UnqualifiedPathStepPolicy extends Enum {
- abstract sealed trait Type extends EnumValueType
- case object NoNamespace extends Type
- case object DefaultNamespace extends Type
- case object PreferDefaultNamespace extends Type
- }
\ No newline at end of file
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/api/WarnID.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/api/WarnID.scala
deleted file mode 100644
index 4a7c99b..0000000
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/api/WarnID.scala
+++ /dev/null
@@ -1,98 +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.api
-
-import org.apache.daffodil.exceptions.ThrowsSDE
-import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.schema.annotation.props.{ Enum => PropsEnum }
-
-sealed trait WarnID extends WarnID.Value
-
-/**
- * Warning Identifiers for use in suppressing warning messages that are
- * unavoidable and not helpful.
- *
- * TODO: This file really should be generated from dafext.xsd's
- * enumerations for the XML syntax that specifies these suppressions in
- * config files. As this list grows, it's more and more unwieldy.
- */
-object WarnID extends PropsEnum[WarnID] {
- /**
- * Suppresses All Warnings
- */
- case object All extends WarnID; forceConstruction(All)
-
- /**
- * For selective suppression of individual warnings.
- *
- * Please add additional, preserving alphabetical order and copying the
- * apparent naming conventions.
- */
- case object AlignmentNotSame extends WarnID; forceConstruction(AlignmentNotSame)
- case object AppinfoDFDLSourceWrong extends WarnID; forceConstruction(AppinfoDFDLSourceWrong)
- case object AppinfoNoSource extends WarnID; forceConstruction(AppinfoNoSource)
- case object ChoiceInsideHiddenGroup extends WarnID; forceConstruction(ChoiceInsideHiddenGroup)
-
- /**
- * For DeprecatedThing warning suppression
- */
- case object DeprecatedBuiltInFormats extends WarnID; forceConstruction(DeprecatedBuiltInFormats)
- case object DeprecatedEncodingNameUSASCII7BitPacked extends WarnID; forceConstruction(DeprecatedEncodingNameUSASCII7BitPacked)
- case object DeprecatedFunctionDAFError extends WarnID; forceConstruction(DeprecatedFunctionDAFError)
-
- /**
- * Deprecated properties should all begin with "DeprecatedProperty..."
- */
- case object DeprecatedPropertySeparatorPolicy extends WarnID; forceConstruction(DeprecatedPropertySeparatorPolicy)
- case object EncodingErrorPolicyError extends WarnID; forceConstruction(EncodingErrorPolicyError)
- case object TextBidiError extends WarnID; forceConstruction(TextBidiError)
- case object FloatingError extends WarnID; forceConstruction(FloatingError)
- case object EscapeSchemeRefUndefined extends WarnID; forceConstruction(EscapeSchemeRefUndefined)
- case object FacetExplicitLengthOutOfRange extends WarnID; forceConstruction(FacetExplicitLengthOutOfRange)
- case object InconsistentLengthKind extends WarnID; forceConstruction(InconsistentLengthKind)
- case object IgnoreImport extends WarnID; forceConstruction(IgnoreImport)
- case object MultipleChoiceBranches extends WarnID; forceConstruction(MultipleChoiceBranches)
- case object NamespaceDifferencesOnly extends WarnID; forceConstruction(NamespaceDifferencesOnly)
- case object NoEmptyDefault extends WarnID; forceConstruction(NoEmptyDefault)
- case object PathNotToArray extends WarnID; forceConstruction(PathNotToArray)
- case object PatternEncodingSlashW extends WarnID; forceConstruction(PatternEncodingSlashW)
- case object QueryStylePathExpression extends WarnID; forceConstruction(QueryStylePathExpression)
- case object RegexPatternZeroLength extends WarnID; forceConstruction(RegexPatternZeroLength)
- case object EmptyElementParsePolicyError extends WarnID; forceConstruction(EmptyElementParsePolicyError)
- /**
- * UnsupportedThing warning suppression.
- */
- case object UnsupportedAttributeBlockDefault extends WarnID; forceConstruction(UnsupportedAttributeBlockDefault)
- case object UnsupportedAttributeFinalDefault extends WarnID; forceConstruction(UnsupportedAttributeFinalDefault)
- case object UnsupportedAttributeSchemaLocation extends WarnID; forceConstruction(UnsupportedAttributeSchemaLocation)
- case object UnsupportedAttributeFormDefault extends WarnID; forceConstruction(UnsupportedAttributeFormDefault)
-
- /**
- * textOutputMinLength checking
- */
- case object TextOutputMinLengthOutOfRange extends WarnID; forceConstruction(TextOutputMinLengthOutOfRange)
-
- /**
- * Automatic expression result type coercion
- */
- case object DeprecatedExpressionResultCoercion extends WarnID; forceConstruction(DeprecatedExpressionResultCoercion)
-
- override def apply(name: String, context: ThrowsSDE) = Assert.usageError("not to be called. Call find(name) method instead.")
-
- def find(name: String): Option[WarnID] = optionStringToEnum("warning identifier", name)
-}
diff --git a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
index 1db4e4f..dac12db 100644
--- a/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
+++ b/daffodil-propgen/src/main/resources/org/apache/daffodil/xsd/dafext.xsd
@@ -15,155 +15,427 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<xsd:schema targetNamespace="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
+<xs:schema
+ targetNamespace="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
xmlns:dafint="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:int"
- attributeFormDefault="unqualified" elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd
urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:int xsd/dafint.xsd">
- <xsd:import namespace="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:int"/>
+ <xs:import namespace="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:int"/>
- <xsd:attribute name="parseUnparsePolicy" type="daf:ParseUnparsePolicyEnum"/>
+ <xs:attribute name="parseUnparsePolicy" type="daf:ParseUnparsePolicyEnum"/>
+ <xs:simpleType name="ParseUnparsePolicyEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="both" />
+ <xs:enumeration value="parseOnly" />
+ <xs:enumeration value="unparseOnly" />
+ </xs:restriction>
+ </xs:simpleType>
- <xsd:simpleType name="ParseUnparsePolicyEnum">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="parseOnly" />
- <xsd:enumeration value="unparseOnly" />
- <xsd:enumeration value="both" />
- </xsd:restriction>
- </xsd:simpleType>
-
- <xsd:attribute name="emptyElementParsePolicy" type="daf:EmptyElementParsePolicyEnum"/>
+ <xs:attribute name="emptyElementParsePolicy" type="daf:EmptyElementParsePolicyEnum"/>
- <xsd:simpleType name="EmptyElementParsePolicyEnum">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="treatAsMissing" />
- <xsd:enumeration value="treatAsEmpty" />
- </xsd:restriction>
- </xsd:simpleType>
-
- <xsd:element name="property" type="daf:PropertyType" />
-
- <xsd:complexType name="PropertyType">
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute name="name" type="daf:PropertyNameType" use='required'/>
- <xsd:attributeGroup ref="dafint:daffodilAG"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
-
- <xsd:simpleType name="PropertyNameType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="parseUnparsePolicy"/>
- <xsd:enumeration value="emptyElementParsePolicy"/>
- </xsd:restriction>
- </xsd:simpleType>
+ <xs:simpleType name="EmptyElementParsePolicyEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="treatAsEmpty" />
+ <xs:enumeration value="treatAsMissing" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="property" type="daf:PropertyType" />
+
+ <xs:complexType name="PropertyType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="daf:PropertyNameType" use='required'/>
+ <xs:attributeGroup ref="dafint:daffodilAG"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:simpleType name="PropertyNameType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="emptyElementParsePolicy"/>
+ <xs:enumeration value="parseUnparsePolicy"/>
+ </xs:restriction>
+ </xs:simpleType>
<!-- properties related to daffodil configuration -->
- <xsd:element name="externalVariableBindings" type="daf:externalVarType" />
- <xsd:complexType name="externalVarType">
- <xsd:sequence>
- <xsd:element ref="daf:bind" minOccurs="0" maxOccurs="unbounded" />
- </xsd:sequence>
- </xsd:complexType>
-
- <xsd:element name="bind" type="daf:bindType" />
-
- <xsd:simpleType name="bindNameType">
- <xsd:restriction base="xsd:string" />
- </xsd:simpleType>
- <xsd:complexType name="bindType">
- <xsd:simpleContent>
- <xsd:extension base="daf:bindNameType">
- <xsd:attribute name="name" use="required">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string" />
- </xsd:simpleType>
- </xsd:attribute>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
-
- <xsd:element name="tunables">
- <xsd:complexType>
- <xsd:all><!-- any order but only 0 or 1 time each -->
- <xsd:element name="requireBitOrderProperty" minOccurs="0" type="xsd:boolean" />
- <xsd:element name="requireEncodingErrorPolicyProperty" minOccurs="0" type="xsd:boolean" />
- <xsd:element name="requireTextBidiProperty" minOccurs="0" type="xsd:boolean" />
- <xsd:element name="requireFloatingProperty" minOccurs="0" type="xsd:boolean" />
- <xsd:element name="maxFieldContentLengthInBytes" minOccurs="0" type="xsd:int" />
- <xsd:element name="maxOccursBounds" minOccurs="0" type="xsd:int" />
- <xsd:element name="maxSkipLengthInBytes" minOccurs="0" type="xsd:int" />
- <xsd:element name="maxBinaryDecimalVirtualPoint" minOccurs="0" type="xsd:int" />
- <xsd:element name="minBinaryDecimalVirtualPoint" minOccurs="0" type="xsd:int" />
- <xsd:element name="generatedNamespacePrefixStem" minOccurs="0" type="xsd:string" />
- <xsd:element name="readerByteBufferSize" minOccurs="0" type="xsd:int" />
- <xsd:element name="maxLengthForVariableLengthDelimiterDisplay" minOccurs="0" type="xsd:int" />
- <xsd:element name="inputFileMemoryMapLowThreshold" minOccurs="0" type="xsd:int" />
- <xsd:element name="maximumSimpleElementSizeInCharacters" minOccurs="0" type="xsd:int" />
- <xsd:element name="initialRegexMatchLimitInCharacters" minOccurs="0" type="xsd:int" />
- <xsd:element name="maximumRegexMatchLengthInCharacters" minOccurs="0" type="xsd:int" />
- <xsd:element name="parseUnparsePolicy" minOccurs="0" type="daf:ParseUnparsePolicyEnum"/>
- <xsd:element name="unqualifiedPathStepPolicy" minOccurs="0">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="noNamespace" />
- <xsd:enumeration value="defaultNamespace" />
- <xsd:enumeration value="preferDefaultNamespace" />
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:element>
- <xsd:element name="suppressSchemaDefinitionWarnings" minOccurs="0">
- <xsd:simpleType>
- <xsd:list>
- <xsd:simpleType>
- <xsd:restriction base="xsd:token">
- <xsd:enumeration value="all"/>
- <!--
- Please keep these in alphabetical order
- -->
- <xsd:enumeration value="alignmentNotSame"/>
- <xsd:enumeration value="appinfoDFDLSourceWrong"/>
- <xsd:enumeration value="appinfoNoSource"/>
- <xsd:enumeration value="choiceInsideHiddenGroup" />
- <xsd:enumeration value="deprecatedBuiltInFormats"/>
- <xsd:enumeration value="deprecatedEncodingNameUSASCII7BitPacked"/>
- <xsd:enumeration value="deprecatedFunctionDAFError"/>
- <xsd:enumeration value="deprecatedPropertySeparatorPolicy" />
- <xsd:enumeration value="deprecatedExpressionResultCoercion" />
- <xsd:enumeration value="emptyElementParsePolicyError" />
- <xsd:enumeration value="encodingErrorPolicyError"/>
- <xsd:enumeration value="escapeSchemeRefUndefined"/>
- <xsd:enumeration value="facetExplicitLengthOutOfRange"/>
- <xsd:enumeration value="inconsistentLengthKind"/>
- <xsd:enumeration value="multipleChoiceBranches"/>
- <xsd:enumeration value="namespaceDifferencesOnly"/>
- <xsd:enumeration value="noEmptyDefault"/>
- <xsd:enumeration value="pathNotToArray" />
- <xsd:enumeration value="patternEncodingSlashW"/>
- <xsd:enumeration value="queryStylePathExpression"/>
- <xsd:enumeration value="regexPatternZeroLength" />
- <xsd:enumeration value="unsupportedAttributeBlockDefault" />
- <xsd:enumeration value="unsupportedAttributeFinalDefault" />
- <xsd:enumeration value="unsupportedAttributeFormDefault" />
- <xsd:enumeration value="unsupportedAttributeSchemaLocation" />
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:list>
- </xsd:simpleType>
- </xsd:element>
- <xsd:element name="allowExpressionResultCoercion" minOccurs="0" type="xsd:boolean" />
- <xsd:element name="defaultEmptyElementParsePolicy" minOccurs="0" type="daf:EmptyElementParsePolicyEnum"/>
- <xsd:element name="requireEmptyElementParsePolicyProperty" minOccurs="0" type="xsd:boolean" />
- </xsd:all>
- </xsd:complexType>
- </xsd:element>
-
-</xsd:schema>
+ <xs:element name="externalVariableBindings" type="daf:externalVarType" />
+
+ <xs:complexType name="externalVarType">
+ <xs:sequence>
+ <xs:element ref="daf:bind" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="bind" type="daf:bindType" />
+
+ <xs:simpleType name="bindNameType">
+ <xs:restriction base="xs:string" />
+ </xs:simpleType>
+
+ <xs:complexType name="bindType">
+ <xs:simpleContent>
+ <xs:extension base="daf:bindNameType">
+ <xs:attribute name="name" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string" />
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="tunables">
+ <xs:complexType>
+ <xs:all>
+ <xs:element name="allowExpressionResultCoercion" type="xs:boolean" default="true" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Defines how Daffodil coerces expressions where the result type differs
+ from the expected type. As an example, assume the expected type of an
+ expression is an xs:string, but the expression is { 3 }. In this case, the
+ expression result is an xs:int, which should not be automatically coerced
+ to an xs:string. Instead, the expression should be { xs:string(3) } or { "3" }
+ If the value of this tunable is false, these types of expressions will
+ result in a schema definition error. If the value is true, Daffodil will
+ provide a warning and attempt to coerce the result type to the expected
+ type.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="allowExternalPathExpressions" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ By default, path expressions in Daffodil will only work correctly if path
+ steps are used in an expression defined in the schema when compiled. To
+ enable the use of other expressions (e.g. during debugging, where not all
+ expressions are known at schema compile time), set this tunable to true.
+ This may cause a degredation of performance in path expression evaluation,
+ so this should be avoided when in production. This flag is automatically
+ enabled when debugging is enabled.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="defaultInitialRegexMatchLimitInChars" type="xs:int" default="32" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated. This tunable no longer has any affect and is only kept for
+ backwards compatability.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="defaultEmptyElementParsePolicy" type="daf:TunableEmptyElementParsePolicy" default="treatAsEmpty" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Defines the default empty element parse policy to use if it is not defined
+ in a schema. This is only used if requireEmptyElementParsePolicyProperty is
+ false.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="errorOnUnsupportedJavaVersion" type="xs:boolean" default="true" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated. This tunable no longer has any affect and is only kept for
+ backwards compatability.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="generatedNamespacePrefixStem" type="xs:string" default="tns" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Stem to use when generating a namespace prefix when one is not defined for
+ the target naespace.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="initialElementOccurrencesHint" type="xs:int" default="10" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Initial array buffer size allocated for recurring elements/arrays.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="initialRegexMatchLimitInCharacters" type="xs:int" default="64" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Initial number of characters to match when performing regular expression
+ matches on input data. When a regex fails to match, more data may be
+ consumed up to the maximumRegexMatchLengthInCharacters tunable.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="inputFileMemoryMapLowThreshold" type="xs:int" default="33554432" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated. This tunable no longer has any affect and is only kept for
+ backwards compatability.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxBinaryDecimalVirtualPoint" type="xs:int" default="200" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ The largest allowed value of the dfdl:binaryDecimalVirtualPoint property.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxDataDumpSizeInBytes" type="xs:int" default="256" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ The maximum size of data to retrive when When getting data to display
+ for debugging.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxFieldContentLengthInBytes" type="xs:int" default="1048576" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated. This tunable no longer has any affect and is only kept for
+ backwards compatability.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxLengthForVariableLengthDelimiterDisplay" type="xs:int" default="10" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ When unexpected text is found where a delimiter is expected, this is the maximum
+ number of bytes (characters) to display when the expected delimiter is a variable
+ length delimiter.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxOccursBounds" type="xs:int" default="2147483647" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Maximum number of occurances of an array element.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxSkipLengthInBytes" type="xs:int" default="1024" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Maximum number of bytes allowed to skip in a skip region.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maxValidYear" type="xs:int" default="9999" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Due to differences in the DFDL spec and ICU4J SimpleDateFormat, we must
+ have SimpleDateFormat parse in lenient mode, which allows the year value
+ to overflow with very large years into possibly negative years. This
+ tunable tunable sets an upper limit for values to prevent overflow.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maximumRegexMatchLengthInCharacters" type="xs:int" default="1048576" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Maximum number of characters to match when performing regular expression
+ matches on input data.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="maximumSimpleElementSizeInCharacters" type="xs:int" default="1048576" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Maximum number of characters to parse when parsing string data.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="minBinaryDecimalVirtualPoint" type="xs:int" default="-200" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ The smallest allowed value of the dfdl:binaryDecimalVirtualPoint property.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="minValidYear" type="xs:int" default="0" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Due to differences in the DFDL spec and ICU4J SimpleDateFormat, we must
+ have SimpleDateFormat parse in lenient mode, which allows the year value
+ to overflow with very large years into possibly negative years. This
+ tunable tunable sets an upper limit for values to prevent underflow.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="parseUnparsePolicy" type="daf:TunableParseUnparsePolicyTunable" default="fromRoot" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Whether to compile a schema to support only parsing, only unparsing, both, or to
+ use the daf:parseUnparsePolicy from the root node. All child elements of the root
+ must have a compatable daf:parseUnaprsePolicy property.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="readerByteBufferSize" type="xs:int" default="8192" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Deprecated. This tunable no longer has any affect and is only kept for
+ backwards compatability.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireBitOrderProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:bitOrder property is specified. If false, use a
+ default value if the property is not defined in the schema.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireChoiceDispatchKeyKindProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:choiceDispatchKeyKind property is specified. If false, use a
+ default value if the property is not defined in the schema.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireChoiceBranchKeyKindProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:choiceBranchKeyKind property is specified. If false, use a
+ default value if the property is not defined in the schema.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireEmptyElementParsePolicyProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:emptyElementParsePolicy property is specified in
+ the schema. If false, and not defined in the schema, uses the
+ defaultEmptyElementParsePolicy as the value of emptyElementParsePolicy.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireEncodingErrorPolicyProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:encodingErrorPolicy property is specified. If
+ false, use a default value if the property is not defined in the schema.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireFloatingProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:floating property is specified. If
+ false, use a default value if the property is not defined in the schema.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="requireTextBidiProperty" type="xs:boolean" default="false" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ If true, require that the dfdl:testBidi property is specified. If
+ false, use a default value if the property is not defined in the schema.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="suppressSchemaDefinitionWarnings" type="daf:TunableSuppressSchemaDefinitionWarnings" default="" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Space-separated list of schema definition warnings that should be ignored,
+ or "all" to ignore all warnings.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:element name="unqualifiedPathStepPolicy" type="daf:TunableUnqualifiedPathStepPolicy" default="noNamespace" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Defines how to lookup DFDL expression path steps that to not include a
+ namespace prefix. Values are:
+ - noNamespace: only match elements that do not have a namespace
+ - defaultNamespace: only match elements defined in the default namespace
+ - preferDefaultNamespace: match elements defined in the default namespace;
+ if non are found, match elemnts that do not have a namespace
+ </xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ </xs:all>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:simpleType name="TunableEmptyElementParsePolicy">
+ <xs:restriction base="daf:EmptyElementParsePolicyEnum" />
+ </xs:simpleType>
+
+ <!--
+ The two 'Tunables' in the name are intentional. The first is the standard for
+ Tunable enums used by the generator. The second is to differentiate between
+ the dfdl property enum and the tunable enum, since they have different allowed
+ values.
+ -->
+ <xs:simpleType name="TunableParseUnparsePolicyTunable">
+ <xs:union>
+ <xs:simpleType>
+ <xs:restriction base="daf:ParseUnparsePolicyEnum" />
+ </xs:simpleType>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="fromRoot" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+
+ <xs:simpleType name="TunableUnqualifiedPathStepPolicy">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="defaultNamespace" />
+ <xs:enumeration value="noNamespace" />
+ <xs:enumeration value="preferDefaultNamespace" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="TunableSuppressSchemaDefinitionWarnings">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="all" />
+ <xs:enumeration value="alignmentNotSame" />
+ <xs:enumeration value="appinfoDFDLSourceWrong" />
+ <xs:enumeration value="appinfoNoSource" />
+ <xs:enumeration value="choiceInsideHiddenGroup" />
+ <xs:enumeration value="deprecatedBuiltInFormats" />
+ <xs:enumeration value="deprecatedEncodingNameUSASCII7BitPacked" />
+ <xs:enumeration value="deprecatedExpressionResultCoercion" />
+ <xs:enumeration value="deprecatedFunctionDAFError" />
+ <xs:enumeration value="deprecatedPropertySeparatorPolicy" />
+ <xs:enumeration value="emptyElementParsePolicyError" />
+ <xs:enumeration value="encodingErrorPolicyError" />
+ <xs:enumeration value="escapeSchemeRefUndefined" />
+ <xs:enumeration value="facetExplicitLengthOutOfRange" />
+ <xs:enumeration value="floatingError" />
+ <xs:enumeration value="ignoreImport" />
+ <xs:enumeration value="inconsistentLengthKind" />
+ <xs:enumeration value="multipleChoiceBranches" />
+ <xs:enumeration value="namespaceDifferencesOnly" />
+ <xs:enumeration value="noEmptyDefault" />
+ <xs:enumeration value="pathNotToArray" />
+ <xs:enumeration value="patternEncodingSlashW" />
+ <xs:enumeration value="queryStylePathExpression" />
+ <xs:enumeration value="regexPatternZeroLength" />
+ <xs:enumeration value="textBidiError" />
+ <xs:enumeration value="textOutputMinLengthOutOfRange" />
+ <xs:enumeration value="unsupportedAttributeBlockDefault" />
+ <xs:enumeration value="unsupportedAttributeFinalDefault" />
+ <xs:enumeration value="unsupportedAttributeFormDefault" />
+ <xs:enumeration value="unsupportedAttributeSchemaLocation" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+</xs:schema>
diff --git a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/PropertyGenerator.scala b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/PropertyGenerator.scala
index 76fb639..ce092c2 100644
--- a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/PropertyGenerator.scala
+++ b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/PropertyGenerator.scala
@@ -39,7 +39,8 @@ class PropertyGenerator(arg: Node) {
val excludedTypes = List("Property", "EmptyElementParsePolicy", "TextNumberBase", "AlignmentType", "FillByteType", "BinaryBooleanTrueRepType", "BinaryBooleanFalseRepType",
"SeparatorSuppressionPolicy", "dafint:daffodilAG", "TextStandardExponentRep", "TextOutputMinLength", // Do these by hand.
"PropertyNameType", "PropertyType", // Not used and causes conflict with daf namespace
- "externalVariableBindings", "externalVarType", "bind", "bindNameType", "bindType", "tunables") // Ignore daffodil configuration types
+ "externalVariableBindings", "externalVarType", "bind", "bindNameType", "bindType", "tunables", // Ignore daffodil configuration types
+ "TunableEmptyElementParsePolicy", "TunableParseUnparsePolicyTunable", "TunableSuppressSchemaDefinitionWarnings", "TunableUnqualifiedPathStepPolicy") // Ignore tunable types
val excludedAttributes = List("EmptyElementParsePolicy", "TextNumberBase",
"SeparatorSuppressionPolicy", "TextStandardExponentRep", "TextOutputMinLength") // Do these by hand.
@@ -641,6 +642,12 @@ object PropertyGenerator {
def generatedCodeFilename = "GeneratedCode.scala"
def generatedCodePackage = "org.apache.daffodil.schema.annotation.props.gen"
+ def tunableCodeFilename = "DaffodilTunablesGen.scala"
+ def tunableCodePackage = "org.apache.daffodil.api"
+
+ def warnIdCodeFilename = "WarnIdGen.scala"
+ def warnIdCodePackage = "org.apache.daffodil.api"
+
def preamble = "package " + generatedCodePackage + """
////////////////////////////////////////////////////////////////////////////////////////////
@@ -677,6 +684,13 @@ import org.apache.daffodil.exceptions.ThrowsSDE
allThunks
}
+ def getGeneratedFilePath(rootDir: String, pkg: String, filename: String): String = {
+ val outDir = new java.io.File(rootDir + "/" + pkg.split('.').reduceLeft(_ + "/" + _))
+ outDir.mkdirs()
+ val outPath = outDir + "/" + filename
+ outPath
+ }
+
/**
* Main - run as a scala application to actually create a new GeneratedCode.scala file in the gen directory.
*/
@@ -687,14 +701,20 @@ import org.apache.daffodil.exceptions.ThrowsSDE
val thunks = generateThunks()
- val outDir = new java.io.File(args(0) + "/" + generatedCodePackage.split('.').reduceLeft(_ + "/" + _))
- outDir.mkdirs()
- val outPath = outDir + "/" + generatedCodeFilename
- val outwriter = new java.io.FileWriter(outPath)
+ val generatedCodePath = getGeneratedFilePath(args(0), generatedCodePackage, generatedCodeFilename)
+ writeGeneratedCode(thunks, new java.io.FileWriter(generatedCodePath))
+ System.out.println(generatedCodePath)
+
+ val tunablePath = getGeneratedFilePath(args(0), tunableCodePackage, tunableCodeFilename)
+ val tunableGenerator = new TunableGenerator(daffodilExtensionsXML)
+ tunableGenerator.writeGeneratedCode(new java.io.FileWriter(tunablePath))
+ System.out.println(tunablePath)
- writeGeneratedCode(thunks, outwriter)
+ val warnIdPath = getGeneratedFilePath(args(0), warnIdCodePackage, warnIdCodeFilename)
+ val warnIdGenerator = new WarnIDGenerator(daffodilExtensionsXML)
+ warnIdGenerator.writeGeneratedCode(new java.io.FileWriter(warnIdPath))
+ System.out.println(warnIdPath)
- System.out.println(outPath)
}
//
diff --git a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
new file mode 100644
index 0000000..c2be36e
--- /dev/null
+++ b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
@@ -0,0 +1,292 @@
+/*
+ * 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.propGen
+
+import scala.xml.XML
+
+class TunableGenerator(schema: scala.xml.Node) {
+
+ val top = """
+ |/*
+ | * 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.api
+ |
+ |////////////////////////////////////////////////////////////////////////////////////////////
+ |//
+ |// Generated Code - Do not hand modify!
+ |//
+ |// This file is entirely generated code created from the
+ |// XML Schema files that describe Daffodil configuration files.
+ |//
+ |// Don't edit this. Go fix the generator to create what you need instead.
+ |//
+ |////////////////////////////////////////////////////////////////////////////////////////////
+ |
+ |import org.apache.daffodil.exceptions.Assert
+ |import org.apache.daffodil.exceptions.ThrowsSDE
+ |import org.apache.daffodil.schema.annotation.props.EmptyElementParsePolicy
+ |import org.apache.daffodil.schema.annotation.props.Enum
+ |import org.apache.daffodil.util.LogLevel
+ |import org.apache.daffodil.util.Logging
+ |import org.apache.daffodil.util.Misc
+ |import org.apache.daffodil.xml.DaffodilXMLLoader
+ |
+ |object DaffodilTunables {
+ |
+ | def apply(tunables: Map[String, String]): DaffodilTunables = {
+ | apply().setTunables(tunables)
+ | }
+ |
+ | def apply(tunable: String, value: String): DaffodilTunables = {
+ | apply().setTunable(tunable, value)
+ | }
+ |
+ | def apply(): DaffodilTunables = {
+ | // override tunables from the global configuration file on the class path, if it exists
+ | val (configOpt, _) = Misc.getResourceOption("/daffodil-config.xml")
+ | val configTunables: Map[String, String] =
+ | if (configOpt.isDefined) {
+ | val loader = new DaffodilXMLLoader()
+ | val node = loader.load(URISchemaSource(configOpt.get))
+ | val trimmed = scala.xml.Utility.trim(node)
+ | val tunablesNode = (trimmed \ "tunables").headOption
+ | val tunablesMap: Map[String, String] = tunablesNode match {
+ | case None => Map.empty
+ | case Some(tunableNode) => {
+ | tunableNode.child.map { n => (n.label, n.text) }.toMap
+ | }
+ | }
+ | tunablesMap
+ | } else {
+ | Map.empty
+ | }
+ |
+ | new DaffodilTunables().setTunables(configTunables)
+ | }
+ |}
+ |
+ |case class DaffodilTunables private (
+ """.trim.stripMargin
+
+ val middle = """
+ | extends Serializable
+ | with Logging {
+ |
+ | def setTunables(tunables: Map[String, String]): DaffodilTunables = {
+ | tunables.foldLeft(this) { case (dafTuns, (tunable, value)) => dafTuns.setTunable(tunable, value) }
+ | }
+ |
+ | def setTunable(tunable: String, value: String): DaffodilTunables = {
+ | tunable match {
+ """.trim.stripMargin
+
+ val bottom = """
+ | case _ => throw new IllegalArgumentException("Unknown tunable: " + tunable)
+ | }
+ | }
+ |
+ | def notSuppressedWarning(warnID: WarnID) =
+ | !suppressSchemaDefinitionWarnings.contains(warnID) &&
+ | !suppressSchemaDefinitionWarnings.contains(WarnID.All)
+ |
+ |}
+ """.trim.stripMargin
+
+ val tunablesRoot = (schema \ "element").find(_ \@ "name" == "tunables").get
+ val tunableNodes = tunablesRoot \\ "all" \ "element"
+
+ val excludedSimpleTypes = Seq(
+ "TunableEmptyElementParsePolicy",
+ "TunableSuppressSchemaDefinitionWarnings"
+ )
+ val tunableSimpleTypeNodes = (schema \ "simpleType")
+ .filter { st => (st \@ "name").startsWith("Tunable") }
+ .filter { st => !excludedSimpleTypes.contains(st \@ "name") }
+
+ def writeGeneratedCode(w: java.io.FileWriter) {
+ val tunables =
+ tunableNodes.map { tunableNode =>
+ val schemaName = tunableNode \@ "name"
+ val schemaType = tunableNode \@ "type"
+ val schemaDefault = tunableNode \@ "default"
+
+ val tunable =
+ if (schemaName == "suppressSchemaDefinitionWarnings") {
+ // special case, list of enums
+ new EnumListTunable(schemaName, schemaType, schemaDefault, "WarnID")
+ } else if (!schemaType.startsWith("xs:")) {
+ // non-primitive type, assume a single enum
+ new EnumTunable(schemaName, schemaType, schemaDefault)
+ } else {
+ // primitive type
+ new PrimitiveTunable(schemaName, schemaType, schemaDefault)
+ }
+ tunable
+ }
+
+ w.write(top)
+ w.write("\n")
+ w.write(tunables.map(_.scalaDefinition).mkString(" ", ",\n ", ")"))
+ w.write("\n")
+ w.write(middle)
+ w.write("\n")
+ w.write(tunables.map(_.scalaConversion.split("\n").mkString(" ", "\n ", "")).mkString("\n"))
+ w.write("\n")
+ w.write(bottom)
+ w.write("\n")
+ w.write("\n")
+
+ val tunableDefinitions =
+ tunableSimpleTypeNodes.map { n =>
+ new TunableEnumDefinition(schema, n)
+ }
+
+ w.write(tunableDefinitions.map(_.scalaEnumeration).mkString("\n"))
+
+ w.flush();
+ }
+}
+
+abstract class TunableBase {
+ def scalaDefinition: String
+ def scalaConversion: String
+}
+
+class PrimitiveTunable(name: String, schemaType: String, schemaDefault: String)
+ extends TunableBase {
+
+ private val scalaType = schemaType match {
+ case "xs:boolean" => "Boolean"
+ case "xs:int" => "Int"
+ case "xs:string" => "String"
+ }
+
+ private val scalaDefault = schemaType match {
+ case "xs:string" => "\"" + schemaDefault + "\""
+ case _ => schemaDefault
+ }
+
+ override val scalaDefinition = s"""val ${name}: ${scalaType} = ${scalaDefault}"""
+ override val scalaConversion = s"""case "${name}" => this.copy(${name} = value.to${scalaType})"""
+}
+
+class EnumTunable(name: String, schemaType: String, schemaDefault: String)
+ extends TunableBase {
+
+ private val scalaType = schemaType.stripPrefix("daf:Tunable")
+ private val scalaDefault = scalaType + "." + schemaDefault.head.toUpper + schemaDefault.tail
+
+ override val scalaDefinition = s"""val ${name}: ${scalaType} = ${scalaDefault}"""
+ override val scalaConversion = s"""
+ |case "${name}" => {
+ | val vOpt = ${scalaType}.optionStringToEnum("${scalaType}", value)
+ | val v = vOpt.getOrElse(throw new IllegalArgumentException("For input string: \\"" + value + "\\""))
+ | this.copy(${name} = v)
+ |}
+ """.trim.stripMargin
+}
+
+class EnumListTunable(name: String, schemaType: String, schemaDefault: String, listType: String)
+ extends TunableBase {
+
+ val scalaDefault = {
+ val trimmedDefault = schemaDefault.trim
+ if (trimmedDefault == "") {
+ "Nil"
+ } else {
+ val defaultSeq = trimmedDefault.split("\\s+").map(d => s"${listType}.${d.head.toUpper + d.tail}")
+ s"""Seq(${defaultSeq.mkString(", ")})"""
+ }
+
+ }
+
+ override val scalaDefinition = s"val ${name}: Seq[${listType}] = ${scalaDefault}"
+ override val scalaConversion = s"""
+ |case "${name}" => {
+ | val values = value.split("\\\\s+").toSeq.map { v =>
+ | val vOpt = ${listType}.optionStringToEnum("${listType}", v)
+ | vOpt.getOrElse(throw new IllegalArgumentException("For input string: \\"" + v + "\\""))
+ | }
+ | this.copy(${name} = values)
+ |}
+ """.trim.stripMargin
+}
+
+class TunableEnumDefinition(schemaRoot: scala.xml.Node, simpleTypeNode: scala.xml.Node) {
+ private val nodeName = (simpleTypeNode \@ "name").stripPrefix("Tunable")
+ private val scalaType = nodeName.head.toUpper + nodeName.tail
+
+ /**
+ * Returns a list of all string values of enumerations. If a simpletype is a
+ * untion of other simple types, it recursively gets their enumeration values
+ * and combines everything.
+ */
+ private def getAllEnumerationValues(node: scala.xml.Node): Seq[String] = {
+ val restrictions = node \\ "restriction"
+ restrictions.flatMap { r =>
+ val base = r \@ "base"
+ val enumerationValues =
+ if (base.startsWith("xs:")) {
+ (r \ "enumeration").map(_ \@ "value")
+ } else {
+ val local = base.split(":")(1)
+ val restrictionSimpleTypeNode =
+ (schemaRoot \ "simpleType").find(_ \@ "name" == base.split(":")(1)).get
+ getAllEnumerationValues(restrictionSimpleTypeNode)
+ }
+ enumerationValues
+ }
+ }
+
+ private val allEnumerationValues = getAllEnumerationValues(simpleTypeNode)
+
+ private val top = s"""
+ |sealed trait ${scalaType} extends ${scalaType}.Value
+ |object ${scalaType} extends Enum[${scalaType}] {
+""".trim.stripMargin
+
+ private val scalaEnums = {
+ val scalaEnumValues = allEnumerationValues.map { e => e.head.toUpper + e.tail }
+ scalaEnumValues.map { e => s""" case object ${e} extends ${scalaType}; forceConstruction(${e})""" }
+ }
+
+ private val bottom = s"""
+ | override def apply(name: String, context: ThrowsSDE) = Assert.usageError("not to be called. Use optionStringToEnum")
+ |}
+""".stripMargin
+
+ val scalaEnumeration = {
+ top + "\n" + scalaEnums.mkString("\n") + "\n" + bottom
+ }
+
+}
diff --git a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/WarnIDGenerator.scala b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/WarnIDGenerator.scala
new file mode 100644
index 0000000..88eee5e
--- /dev/null
+++ b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/WarnIDGenerator.scala
@@ -0,0 +1,85 @@
+/*
+ * 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.propGen
+
+import scala.xml.XML
+
+class WarnIDGenerator(schema: scala.xml.Node) {
+
+ val top = """
+ |/*
+ | * 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.api
+ |
+ |////////////////////////////////////////////////////////////////////////////////////////////
+ |//
+ |// Generated Code - Do not hand modify!
+ |//
+ |// This file is entirely generated code created from the
+ |// XML Schema files that describe Daffodil configuration files.
+ |//
+ |// Don't edit this. Go fix the generator to create what you need instead.
+ |//
+ |////////////////////////////////////////////////////////////////////////////////////////////
+ |
+ |import org.apache.daffodil.exceptions.Assert
+ |import org.apache.daffodil.exceptions.ThrowsSDE
+ |import org.apache.daffodil.schema.annotation.props.Enum
+ |
+ |sealed trait WarnID extends WarnID.Value
+ |object WarnID extends Enum[WarnID] {
+ """.trim.stripMargin
+
+ val bottom = """
+ | override def apply(name: String, context: ThrowsSDE) = Assert.usageError("not to be called. Use optionStringToEnum")
+ |}
+ """.trim.stripMargin
+
+ val ssdwNode = (schema \ "simpleType").find( _ \@ "name" == "TunableSuppressSchemaDefinitionWarnings").get
+ val enumerationNodes = (ssdwNode \\ "enumeration")
+
+ def writeGeneratedCode(w: java.io.FileWriter) {
+ w.write(top)
+ w.write("\n")
+
+ enumerationNodes.foreach { node =>
+ val enumName = node \@ "value"
+ val scalaName = enumName.head.toUpper + enumName.tail
+ w.write(s" case object ${scalaName} extends WarnID; forceConstruction($scalaName)\n")
+ }
+
+ w.write("\n")
+ w.write(bottom)
+ w.flush();
+ }
+}