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

arosien pushed a commit to branch tdml-gen-app
in repository https://gitbox.apache.org/repos/asf/daffodil.git

commit 2563ef562291008a6bcb9cae632bd044ccdb11aa
Author: Adam Rosien <[email protected]>
AuthorDate: Thu Feb 8 12:58:42 2024 -0800

    Provide scalaxb bindings for TDML schema.
    
    As part of 
[DAFFODIL-2830](https://issues.apache.org/jira/browse/DAFFODIL-2830).
---
 build.sbt                                          |  12 +
 .../daffodil/xsd/{tdml.xsd => tdml-core.xsd}       |  74 +----
 .../resources/org/apache/daffodil/xsd/tdml.xsd     | 304 +--------------------
 .../resources/test-suite/IPv4-with-comments.tdml   |  71 +++++
 .../src/test/resources/test-suite/IPv4.tdml        | 232 ++++++++++++++++
 .../daffodil/tdml/scalaxb/ScalaxbTests.scala       | 142 ++++++++++
 project/plugins.sbt                                |   2 +
 7 files changed, 469 insertions(+), 368 deletions(-)

diff --git a/build.sbt b/build.sbt
index b900e274e..f1f522a85 100644
--- a/build.sbt
+++ b/build.sbt
@@ -143,7 +143,9 @@ lazy val sapi = Project("daffodil-sapi", 
file("daffodil-sapi"))
 
 lazy val tdmlLib = Project("daffodil-tdml-lib", file("daffodil-tdml-lib"))
   .dependsOn(macroLib % "compile-internal", lib, io, io % "test->test", 
slf4jLogger % "test")
+  .enablePlugins(ScalaxbPlugin)
   .settings(commonSettings)
+  .settings(scalaxbSettings)
 
 lazy val tdmlProc = Project("daffodil-tdml-processor", 
file("daffodil-tdml-processor"))
   .dependsOn(tdmlLib, codeGenC, core, slf4jLogger)
@@ -211,6 +213,16 @@ lazy val testStdLayout = 
Project("daffodil-test-stdLayout", file("test-stdLayout
   .dependsOn(tdmlProc % "test")
   .settings(commonSettings, nopublish)
 
+lazy val scalaxbSettings = Seq(
+  Compile / scalaxb / scalaxbGenerateMutable := true,
+  // Even though we don't generate any http clients, we need this to avoid an 
unused import error in the generated code.
+  Compile / scalaxb / scalaxbHttpClientStyle := HttpClientStyle.Sync,
+  Compile / scalaxb / scalaxbPackageName := "org.apache.daffodil.tdml.scalaxb",
+  Compile / scalaxb / sources := Seq(
+    (lib / Compile / resourceDirectory).value / 
"org/apache/daffodil/xsd/tdml-core.xsd",
+  ),
+)
+
 // Choices here are Java LTS versions, 8, 11, 17, 21,...
 // However 8 is deprecated as of Java 21, so will be phased out.
 val minSupportedJavaVersion: String =
diff --git a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd 
b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml-core.xsd
similarity index 79%
copy from daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
copy to daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml-core.xsd
index d46450f5d..82e748e11 100644
--- a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
+++ b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml-core.xsd
@@ -26,11 +26,6 @@
   xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
 
-  <xsd:import namespace="http://www.w3.org/2001/XMLSchema"; />
-  <xsd:import namespace="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext" />
-  <xsd:import namespace="http://www.ogf.org/dfdl/dfdl-1.0/"/>
-  <xsd:import namespace="http://www.ogf.org/dfdl/dfdl-1.0/extensions"/>
-
   <xs:attribute name="tutorialInclude" type="xs:string" fixed="no"/>
   
 <!-- 
@@ -41,7 +36,7 @@
   Users of TDML creating tutorials should paste in known-correct xhtml5 as the 
contents of the 
   tutorial elements.
 -->
-  <xs:element name="tutorial">
+  <xs:element name="tutorial" substitutionGroup="tns:testSuiteChoices">
       <xs:complexType mixed="true">
       <xs:sequence>
         <xs:any namespace="##any" processContents="skip" minOccurs="0" 
maxOccurs="unbounded"/>
@@ -51,22 +46,12 @@
   </xs:element>
   
   <!-- IBM uses this namespace http://www.ibm.com/xmlns/dfdl/testData -->
+  <element name="testSuiteChoices" abstract="true"/>
 
   <element name="testSuite">
     <complexType>
       <sequence>
-        <choice maxOccurs="unbounded" minOccurs="0">
-          <element ref="tns:tutorial"/>
-          <element ref="tns:parserTestCase"/>
-          <!-- This is an extension to the IBM TDML language. We allow schemas 
-            to be directly embedded inside the TDML file. A TDML file that 
contains all 
-            the schemas it needs is a "self contained" TDML file. -->
-          <element ref="tns:defineSchema" minOccurs="0"/>
-
-          <element ref="tns:defineConfig" minOccurs="0"/>
-
-          <element ref="tns:unparserTestCase"/>
-        </choice>
+        <xsd:element minOccurs="0" maxOccurs="unbounded" 
ref="tns:testSuiteChoices"></xsd:element>
       </sequence>
       <attribute name="suiteName" type="xs:token" use="optional"/>
       <attribute name="ID" type="xs:token" use="optional"/>
@@ -84,6 +69,8 @@
       <selector xpath="unparserTestCase"/>
       <field xpath="@name"/>
     </unique>
+    <!-- These two constraints only apply to tdml.xsd, but because the element 
is defined here,
+      these also need to be defined here, despite not having any affect when 
used by this file. -->
     <unique name="unique-embeddedSchema-name">
       <selector xpath="defineSchema"/>
       <field xpath="@name"/>
@@ -110,55 +97,8 @@
   the TDML thereby allowing a fully-self-contained single file test case as 
   an exchange medium for tests. -->
 
-  <element name="defineSchema" type="tns:defineSchemaType"/>
-  <complexType name="defineSchemaType">
-    <choice maxOccurs='unbounded'>
-      <element ref='dfdl:format'/>
-      <element ref='dfdl:defineVariable'/>
-      <element ref='dfdl:defineEscapeScheme'/>
-      <element ref='dfdl:defineFormat'/>
-      <element ref='xs:element'/>
-      <element ref='xs:complexType'/>
-      <element ref='xs:group'/>
-      <element ref='xs:simpleType'/>
-      <element ref='xs:include'/>
-      <element ref='xs:import'/>
-                        <!-- <any namespace="##other" processContents="lax"/> 
-->
-    </choice>
-    <attribute name="name" type="xs:NCName" use="required"/>
-                <!-- We want the default to be 'unqualified' in the longer 
term but 
-                     we leave it 'qualified here to prevent lots of tests from 
breaking. -->
-    <attribute name="elementFormDefault" type="tns:elementFormDefaultType" 
default="qualified"/>
-        <!-- we want the default for useDefaultNamespace to be false longer 
term but
-             we leave it as true here to prevent lots of tests from breaking.
-             81 tests to be exact. -->
-    <attribute name="useDefaultNamespace" type="xs:boolean" default="true">
-      <annotation><documentation>
-        Controls whether a xmlns="http://example.com"; default namespace prefix
-        definition will be provided for the embedded schema.
-
-        This matters when the defined schema is used to validate the infoset 
xml
-        before unparsing, or after parsing, as it affects the interpretation of
-        path expressions in the DFDL schema based on the 
unqualifiedPathStepPolicy
-        tunable.
-
-        False is recommended since default namespaces can be confusing.
-      </documentation></annotation>
-    </attribute>
-    <attribute ref="tns:tutorialInclude"/>
-  </complexType>
-
-  <element name="defineConfig" type="tns:defineConfigType"/>
-  <complexType name="defineConfigType">
-    <sequence>
-      <element ref="daf:externalVariableBindings" minOccurs="0" maxOccurs="1"/>
-      <element ref="daf:tunables" minOccurs="0" maxOccurs="1"/>
-    </sequence>
-    <attribute name="name" type="xs:NCName" use="required"/>
-  </complexType>
-
 
-  <element name="parserTestCase" type="tns:parserTestCaseType"/>
+  <element name="parserTestCase" type="tns:parserTestCaseType" 
substitutionGroup="tns:testSuiteChoices"/>
   <complexType name="parserTestCaseType">
     <choice minOccurs="2" maxOccurs="11">
       <!-- we can't enforce the cardinality in XSD 1.0 -->
@@ -369,7 +309,7 @@
     </xs:attribute>
   </xs:attributeGroup>
 
-  <element name="unparserTestCase" type="tns:unparserTestCaseType"/>
+  <element name="unparserTestCase" type="tns:unparserTestCaseType" 
substitutionGroup="tns:testSuiteChoices"/>
   <complexType name="unparserTestCaseType">
     <choice minOccurs="2" maxOccurs="9">
       <!-- we just can't enforce cardinality of any of these things using XSD 
1.0 -->
diff --git a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd 
b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
index d46450f5d..02d23737a 100644
--- a/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
+++ b/daffodil-lib/src/main/resources/org/apache/daffodil/xsd/tdml.xsd
@@ -31,86 +31,13 @@
   <xsd:import namespace="http://www.ogf.org/dfdl/dfdl-1.0/"/>
   <xsd:import namespace="http://www.ogf.org/dfdl/dfdl-1.0/extensions"/>
 
-  <xs:attribute name="tutorialInclude" type="xs:string" fixed="no"/>
-  
-<!-- 
-  This element's type is a stub that satisfies the need for xhtml5 validation 
as part of TDML files.
-
-  It is just a wildcard with skip validation in it. So it's not really 
validating anything.
-
-  Users of TDML creating tutorials should paste in known-correct xhtml5 as the 
contents of the 
-  tutorial elements.
--->
-  <xs:element name="tutorial">
-      <xs:complexType mixed="true">
-      <xs:sequence>
-        <xs:any namespace="##any" processContents="skip" minOccurs="0" 
maxOccurs="unbounded"/>
-      </xs:sequence>
-      <xs:anyAttribute namespace="##any" processContents="skip"/>
-    </xs:complexType>
-  </xs:element>
-  
-  <!-- IBM uses this namespace http://www.ibm.com/xmlns/dfdl/testData -->
-
-  <element name="testSuite">
-    <complexType>
-      <sequence>
-        <choice maxOccurs="unbounded" minOccurs="0">
-          <element ref="tns:tutorial"/>
-          <element ref="tns:parserTestCase"/>
-          <!-- This is an extension to the IBM TDML language. We allow schemas 
-            to be directly embedded inside the TDML file. A TDML file that 
contains all 
-            the schemas it needs is a "self contained" TDML file. -->
-          <element ref="tns:defineSchema" minOccurs="0"/>
-
-          <element ref="tns:defineConfig" minOccurs="0"/>
-
-          <element ref="tns:unparserTestCase"/>
-        </choice>
-      </sequence>
-      <attribute name="suiteName" type="xs:token" use="optional"/>
-      <attribute name="ID" type="xs:token" use="optional"/>
-      <attribute name="description" type="xs:string" use="optional"/>
-      <attribute name="defaultRoundTrip" type="tns:roundTripType" 
use="optional"/>
-      <attribute name="defaultValidation" type="tns:validationType" 
use="optional"/>
-      <attribute name="defaultConfig" type="xs:string" use="optional"/>
-      <attribute name="defaultImplementations" type="tns:implementationsType" 
use="optional"/>
-    </complexType>
-    <unique name="unique-parserTestCase-name">
-      <selector xpath="parserTestCase"/>
-      <field xpath="@name"/>
-    </unique>
-    <unique name="unique-unparserTestCase-name">
-      <selector xpath="unparserTestCase"/>
-      <field xpath="@name"/>
-    </unique>
-    <unique name="unique-embeddedSchema-name">
-      <selector xpath="defineSchema"/>
-      <field xpath="@name"/>
-    </unique>
-    <unique name="unique-embeddedConfig-name">
-      <selector xpath="defineConfig"/>
-      <field xpath="@name"/>
-    </unique>
-  </element>
-  
-  <simpleType name="implementationsType">
-    <list itemType="tns:implementationItem"/>
-  </simpleType>
-  
-  <simpleType name="implementationItem">
-    <restriction base="xs:token">
-      <enumeration value="daffodil"/>
-      <enumeration value="daffodilC"/>
-      <enumeration value="ibm"/>
-    </restriction>
-  </simpleType>
+  <xsd:include schemaLocation="tdml-core.xsd"/>
   
 <!-- We want to allow an xsd:schema to be named and directly embedded in 
   the TDML thereby allowing a fully-self-contained single file test case as 
   an exchange medium for tests. -->
 
-  <element name="defineSchema" type="tns:defineSchemaType"/>
+  <element name="defineSchema" type="tns:defineSchemaType" 
substitutionGroup="tns:testSuiteChoices"/>
   <complexType name="defineSchemaType">
     <choice maxOccurs='unbounded'>
       <element ref='dfdl:format'/>
@@ -148,7 +75,7 @@
     <attribute ref="tns:tutorialInclude"/>
   </complexType>
 
-  <element name="defineConfig" type="tns:defineConfigType"/>
+  <element name="defineConfig" type="tns:defineConfigType" 
substitutionGroup="tns:testSuiteChoices"/>
   <complexType name="defineConfigType">
     <sequence>
       <element ref="daf:externalVariableBindings" minOccurs="0" maxOccurs="1"/>
@@ -157,229 +84,4 @@
     <attribute name="name" type="xs:NCName" use="required"/>
   </complexType>
 
-
-  <element name="parserTestCase" type="tns:parserTestCaseType"/>
-  <complexType name="parserTestCaseType">
-    <choice minOccurs="2" maxOccurs="11">
-      <!-- we can't enforce the cardinality in XSD 1.0 -->
-      <element ref="tns:tutorial"/>
-      <element ref="tns:document"/>
-      <element ref="tns:infoset"/>
-      <element ref="tns:errors"/>
-      <element ref="tns:warnings" minOccurs='0'/>
-      <element ref="tns:validationErrors" minOccurs="0"/>
-    </choice>
-    <attributeGroup ref="tns:testCaseAttribs"/>
-  </complexType>
-
-  <attributeGroup name="testCaseAttribs">
-    <attribute name="name" type="xs:NCName" use="required"/>
-    <attribute name="ID" type="xs:token" use="optional"/>
-    <attribute name="root" type="xs:NCName" use="optional"/> <!-- only needed 
when there is no infoset. -->
-    <attribute name="rootNS" type="xs:string" use="optional"/> <!-- only 
needed when there is no infoset. -->
-    <attribute name="model" type="xs:string" use="optional"/> <!-- is there a 
type for a path/uri? -->
-    <attribute name="config" type="xs:string" use="optional"/> <!-- is there a 
type for a path/uri? -->
-    <attribute name="roundTrip" type="tns:roundTripType" use="optional"/>
-    <attribute name="description" type="xs:string" use="optional"/>
-    <attribute name="unsupported" type="xs:boolean" use="optional" 
default="false"/>
-    <attribute name="validation" type="tns:validationType" use="optional"/>
-    <attribute name="implementations" type="tns:implementationsType" 
use="optional"/>
-    <attribute name="diagnosticsStripLocationInfo" type="xs:boolean" 
use="optional" default="true">
-      <annotation>
-        <documentation>We strip the file info from the diagnostics to prevent 
false
-          positive matches against the test case's error and warning strings
-          coming from file/dir names.
-
-          As there are tests that look for correct file/dir names, those
-          tests will need to NOT strip them and can do so by setting the
-          test flag to false.
-
-          This is only for purposes of comparing error/warning strings
-          to the diagnostic messages. Users would always see, displayed,
-          the full diagnostic messages.</documentation>
-      </annotation>
-    </attribute>
-
-  </attributeGroup>
-
-  <simpleType name="roundTripType">
-    <restriction base="xs:token">
-      <enumeration value="false"/> <!-- means same as none -->
-      <enumeration value="true"/> <!-- means same as onePass -->
-      <!-- 
-        parse only - compare infoset. 
-        -->
-      <enumeration value="none"/>
-      <!--  
-        parse, compare infoset, unparse - compare data 
-        -->
-      <enumeration value="onePass"/> 
-      <!-- 
-        parse, unparse, reparse - compare infoset.
-        Note that this can mask certain errors. So must be used with caution.
-        -->
-      <enumeration value="twoPass"/> 
-      <!-- 
-        parse, unparse, reparse, reunparse, compare data.
-        Note that this can mask many kinds of errors very easily, so must be 
used
-        rarely and with caution. 
-        -->
-      <enumeration value="threePass"/>
-    </restriction>
-  </simpleType>
-  
-  <simpleType name="elementFormDefaultType">
-    <restriction base="xs:token">
-      <enumeration value="qualified"/>
-      <enumeration value="unqualified"/>
-    </restriction>
-  </simpleType>
-
-  <simpleType name="validationType">
-    <restriction base="xs:token">
-      <enumeration value="on"/>
-      <enumeration value="limited"/>
-      <enumeration value="off"/>
-    </restriction>
-  </simpleType>
-
-  <element name="document" type="tns:documentType"/>
-  <element name="infoset" type="tns:infosetType"/>
-  <element name="errors" type="tns:errorsType"/>
-  <element name="warnings" type="tns:warningsType"/>
-  <element name="validationErrors" type="tns:validationErrorsType"/>
-
-  <complexType name="documentType" mixed="true">
-    <sequence>
-      <element ref="tns:documentPart" minOccurs="0" maxOccurs="unbounded"/>
-    </sequence>
-    <attribute name="bitOrder" type="tns:bitOrderEnum" use="optional"/>
-    <attribute ref="tns:tutorialInclude"/>
-  </complexType>
-
-  <element name="documentPart" type="tns:documentPartType"/>
-  <complexType name="documentPartType">
-    <simpleContent>
-      <extension base="xs:string">
-        <attribute name="type" type="tns:documentPartTypeEnum" use="required"/>
-        <attribute name="replaceDFDLEntities" type="xs:boolean"/>
-        <attributeGroup ref="tns:bitOrderAG"/>
-        <attribute name="encoding" type="xs:token" use="optional"/>
-      </extension>
-    </simpleContent>
-  </complexType>
-
-  <simpleType name="documentPartTypeEnum">
-    <restriction base="xs:string">
-      <enumeration value="byte"/>
-      <enumeration value="text"/>
-      <enumeration value="bits"/>
-      <enumeration value="file"/>
-    </restriction>
-  </simpleType>
-
-  <attributeGroup name="bitOrderAG">
-    <attribute name="bitOrder" type="tns:bitOrderEnum" use="optional"/>
-    <attribute name="byteOrder" type="tns:byteOrderEnum" use="optional"/>
-  </attributeGroup>
-
-  <simpleType name="byteOrderEnum">
-    <annotation>
-      <documentation>
-        Not to be confused with dfdl:byteOrder, this attribute describes the
-        order of bits or bytes in the TDML document part, that is, whether
-        they
-        should be given their positions starting from the beginning (LTR) or 
the
-        end (RTL). LTR is the normal default where data location number
-        increase
-        from left to right. RTL is used for bit-order LSBFirst, and the bytes
-        are ordered starting on the right increasing to the left.
-      </documentation>
-    </annotation>
-    <restriction base="xs:string">
-      <enumeration value="RTL"/>
-      <enumeration value="LTR"/>
-    </restriction>
-  </simpleType>
-
-  <simpleType name="bitOrderEnum">
-    <restriction base="xs:string">
-      <enumeration value="LSBFirst"/>
-      <enumeration value="MSBFirst"/>
-    </restriction>
-  </simpleType>
-
-  <complexType name="infosetType">
-    <sequence>
-      <element ref="tns:dfdlInfoset"/>
-    </sequence>
-    <attribute ref="tns:tutorialInclude"/>
-  </complexType>
-
-  <element name="dfdlInfoset" type="tns:dfdlInfosetType"/>
-
-  <complexType name="dfdlInfosetType" mixed="true">
-    <sequence>
-      <any namespace="##any" processContents="lax" minOccurs="0" 
maxOccurs="unbounded"/>
-    </sequence>
-    <attribute name="type" use="optional" default="infoset">
-      <simpleType>
-        <restriction base="xs:string">
-          <enumeration value="infoset"/>
-          <enumeration value="file"/>
-        </restriction>
-      </simpleType>
-    </attribute>
-  </complexType>
-
-  <complexType name="errorsType">
-    <sequence>
-      <element ref="tns:error" maxOccurs="unbounded" minOccurs="1"/>
-    </sequence>
-    <attributeGroup ref="tns:errorWarnAttribs"/>
-  </complexType>
-
-  <complexType name="warningsType">
-    <sequence>
-      <element ref="tns:warning" maxOccurs="unbounded" minOccurs="0"/>
-                        <!-- use <warnings/> to indicate no warnings should 
occur. -->
-    </sequence>
-    <attributeGroup ref="tns:errorWarnAttribs"/>
-  </complexType>
-
-  <complexType name="validationErrorsType">
-    <sequence>
-      <element ref="tns:error" maxOccurs="unbounded" minOccurs="0"/>
-                        <!-- use <validationErrors/> to indicate no validation 
should occur. -->
-    </sequence>
-    <attributeGroup ref="tns:errorWarnAttribs"/>
-  </complexType>
-
-  <element name="error" type="xs:string"/>
-  <element name="warning" type="xs:string"/>
-
-  <xs:attributeGroup name="errorWarnAttribs">
-    <xs:attribute name="match" use="optional" default="all">
-      <xs:simpleType>
-        <xs:restriction base="xs:string">
-          <xs:enumeration value="all"/>
-          <xs:enumeration value="any"/>
-        </xs:restriction>
-      </xs:simpleType>
-    </xs:attribute>
-  </xs:attributeGroup>
-
-  <element name="unparserTestCase" type="tns:unparserTestCaseType"/>
-  <complexType name="unparserTestCaseType">
-    <choice minOccurs="2" maxOccurs="9">
-      <!-- we just can't enforce cardinality of any of these things using XSD 
1.0 -->
-      <element ref="tns:tutorial"/> <!-- these before, between, or after any 
of the others -->
-      <element ref="tns:infoset"/> <!-- required -->
-      <element ref="tns:document"/> <!-- must have either document, or errors, 
or both -->
-      <element ref="tns:errors"/>
-      <element ref="tns:warnings"/>
-    </choice>
-    <attributeGroup ref="tns:testCaseAttribs"/>
-  </complexType>
-
 </xsd:schema>
diff --git 
a/daffodil-tdml-lib/src/test/resources/test-suite/IPv4-with-comments.tdml 
b/daffodil-tdml-lib/src/test/resources/test-suite/IPv4-with-comments.tdml
new file mode 100644
index 000000000..1f056bfd3
--- /dev/null
+++ b/daffodil-tdml-lib/src/test/resources/test-suite/IPv4-with-comments.tdml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<tdml:testSuite
+  xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData";
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
+  xmlns:xs="http://www.w3.org/2001/XMLSchema";
+  xmlns:fn="http://www.w3.org/2005/xpath-functions";
+  xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions";
+  xmlns:ipv4="urn:org.apache.daffodil.layers.IPv4"
+  xmlns:chksum="urn:org.apache.daffodil.layers.IPv4Checksum"
+  xmlns:ex="http://example.com";
+  xmlns:tns="http://example.com";
+  defaultRoundTrip="none">
+
+
+  <tdml:parserTestCase name="IPv4_1" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+    roundTrip="none">
+    <tdml:document>
+      <!--
+      see https://en.wikipedia.org/wiki/IPv4_header_checksum
+      for working through the details of this IPv4 Header
+
+      The first line of 5 words is the part 1 of the header
+      The second line is the checksum
+      The third line of 4 words is the part 2 of the header (src, dest 
addresses)
+      -->
+      <tdml:documentPart type="byte"><![CDATA[
+4500 0073 0000 4000 4011
+b861
+c0a8 0001 c0a8 00c7
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ipv4:IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>0</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>47201</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>47201</ComputedChecksum>
+        </ipv4:IPv4Header>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+</tdml:testSuite>
\ No newline at end of file
diff --git a/daffodil-tdml-lib/src/test/resources/test-suite/IPv4.tdml 
b/daffodil-tdml-lib/src/test/resources/test-suite/IPv4.tdml
new file mode 100644
index 000000000..8925a0e51
--- /dev/null
+++ b/daffodil-tdml-lib/src/test/resources/test-suite/IPv4.tdml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<tdml:testSuite
+  xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData";
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
+  xmlns:xs="http://www.w3.org/2001/XMLSchema";
+  xmlns:fn="http://www.w3.org/2005/xpath-functions";
+  xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions";
+  xmlns:ipv4="urn:org.apache.daffodil.layers.IPv4"
+  xmlns:chksum="urn:org.apache.daffodil.layers.IPv4Checksum"
+  xmlns:ex="http://example.com";
+  xmlns:tns="http://example.com";
+  defaultRoundTrip="none">
+
+
+  <tdml:parserTestCase name="IPv4_1" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+    roundTrip="none">
+    <tdml:document>
+      <tdml:documentPart type="byte"><![CDATA[
+4500 0073 0000 4000 4011
+b861
+c0a8 0001 c0a8 00c7
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ipv4:IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>0</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>47201</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>47201</ComputedChecksum>
+        </ipv4:IPv4Header>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+
+  <tdml:unparserTestCase name="IPv4_array" root="testArray" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+                       roundTrip="none">
+    <tdml:document>
+      <tdml:documentPart type="byte"><![CDATA[
+4500 0073 0000 4000 4011
+b861
+c0a8 0001 c0a8 00c7
+4500 0073 0000 4000 4011
+b861
+c0a8 0001 c0a8 00c7
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ipv4:testArray>
+        <IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>0</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>47201</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>47201</ComputedChecksum>
+        </IPv4Header>
+        <IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>0</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>47201</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>47201</ComputedChecksum>
+        </IPv4Header>
+        </ipv4:testArray>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:parserTestCase name="IPv4_1e" root="IPv4Header"  
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+                       roundTrip="none">
+    <tdml:document>
+      <tdml:documentPart type="byte"><![CDATA[
+4500
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Insufficient bits</tdml:error>
+      <tdml:error>160</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="IPv4_2" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+                       roundTrip="none">
+    <tdml:document>
+      <tdml:documentPart type="byte"><![CDATA[
+4500 0073 0001 4000 4011
+b861
+c0a8 0001 c0a8 00c7
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ipv4:IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>1</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>47201</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>47200</ComputedChecksum>
+        </ipv4:IPv4Header>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:validationErrors>
+      <tdml:error>Incorrect checksum</tdml:error>
+    </tdml:validationErrors>
+  </tdml:parserTestCase>
+
+
+  <tdml:unparserTestCase name="IPv4_1u" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+                       roundTrip="none">
+    <tdml:document>
+      <tdml:documentPart type="byte"><![CDATA[
+4500 0073 0000 4000 4011
+b861
+c0a8 0001 c0a8 00c7
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ipv4:IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>0</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>47201</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>0</ComputedChecksum>
+        </ipv4:IPv4Header>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="IPv4_2u" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+                         roundTrip="none">
+    <tdml:document>
+      <tdml:documentPart type="byte"><![CDATA[
+4500 0073 0001 4000 4011
+b860
+c0a8 0001 c0a8 00c7
+       ]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ipv4:IPv4Header>
+          <Version>4</Version>
+          <IHL>5</IHL>
+          <DSCP>0</DSCP>
+          <ECN>0</ECN>
+          <Length>115</Length>
+          <Identification>1</Identification>
+          <Flags>2</Flags>
+          <FragmentOffset>0</FragmentOffset>
+          <TTL>64</TTL>
+          <Protocol>17</Protocol>
+          <Checksum>0</Checksum>
+          <IPSrc>C0A80001</IPSrc>
+          <IPDest>C0A800C7</IPDest>
+          <FakeData>115</FakeData>
+          <ComputedChecksum>0</ComputedChecksum>
+        </ipv4:IPv4Header>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:unparserTestCase>
+</tdml:testSuite>
diff --git 
a/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/scalaxb/ScalaxbTests.scala
 
b/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/scalaxb/ScalaxbTests.scala
new file mode 100644
index 000000000..bf7c2c85b
--- /dev/null
+++ 
b/daffodil-tdml-lib/src/test/scala/org/apache/daffodil/tdml/scalaxb/ScalaxbTests.scala
@@ -0,0 +1,142 @@
+/*
+ * 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.tdml.scalaxb
+
+import org.junit.Assert._
+import org.junit.Test
+
+class ScalaxbTests {
+
+  @Test def testReadingNoTests(): Unit = {
+    val testSuite =
+      scalaxb.fromXML[TestSuite](
+        scala.xml.XML.load(
+          getClass
+            .getClassLoader()
+            .getResourceAsStream("test-suite/ibm-contributed/dpaext1-2.tdml"),
+        ),
+      )
+
+    assertNotNull(testSuite)
+    assertEquals(Some("dpaext"), testSuite.suiteName)
+  }
+
+  // currently failing, not sure why scalaxb isn't handling comments. is the 
xsd too strict and somehow excludes allowing comments?
+  @Test def testReadingComments(): Unit =
+    scalaxb.fromXML[TestSuite](
+      scala.xml.XML.load(
+        getClass
+          .getClassLoader()
+          .getResourceAsStream("test-suite/IPv4-with-comments.tdml"),
+      )
+    )
+
+  @Test def testReading(): Unit = {
+    val testSuite =
+      scalaxb.fromXML[TestSuite](
+        scala.xml.XML.load(
+          getClass
+            .getClassLoader()
+            .getResourceAsStream("test-suite/IPv4.tdml"),
+        )
+      )
+
+    assertNotNull(testSuite)
+    assertEquals(None, testSuite.suiteName)
+
+    val testcase =
+      scalaxb.fromXML[ParserTestCaseType](
+        <tdml:parserTestCase name="IPv4_1" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd" roundTrip="none"/>
+      )
+    val doc =
+      scalaxb.fromXML[DocumentType](
+        <tdml:document xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData";>
+          <tdml:documentPart type="byte">{scala.xml.PCData("4500 0073 0000 
4000 4011 b861 c0a8 0001 c0a8 00c7")}</tdml:documentPart>
+        </tdml:document>
+      )
+    val infoset =
+      scalaxb.fromXML[InfosetType](
+        <tdml:infoset xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData";>
+          <tdml:dfdlInfoset>
+            <ipv4:IPv4Header>
+              <Version>4</Version>
+              <IHL>5</IHL>
+              <DSCP>0</DSCP>
+              <ECN>0</ECN>
+              <Length>115</Length>
+              <Identification>0</Identification>
+              <Flags>2</Flags>
+              <FragmentOffset>0</FragmentOffset>
+              <TTL>64</TTL>
+              <Protocol>17</Protocol>
+              <Checksum>47201</Checksum>
+              <IPSrc>C0A80001</IPSrc>
+              <IPDest>C0A800C7</IPDest>
+              <FakeData>115</FakeData>
+              <ComputedChecksum>47201</ComputedChecksum>
+            </ipv4:IPv4Header>
+          </tdml:dfdlInfoset>
+        </tdml:infoset>
+      )
+    val expectedParserTestCase = 
+      scalaxb.fromXML[ParserTestCaseType](
+        <tdml:parserTestCase name="IPv4_1" root="IPv4Header" 
model="org/apache/daffodil/layers/IPv4.dfdl.xsd"
+    roundTrip="none" xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/";
+  xmlns:xs="http://www.w3.org/2001/XMLSchema";
+  xmlns:fn="http://www.w3.org/2005/xpath-functions";
+  xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions";
+  xmlns:ipv4="urn:org.apache.daffodil.layers.IPv4"
+  xmlns:chksum="urn:org.apache.daffodil.layers.IPv4Checksum"
+  xmlns:ex="http://example.com";
+  xmlns:tns="http://example.com";>
+          <tdml:document>
+            <tdml:documentPart type="byte">{scala.xml.PCData("4500 0073 0000 
4000 4011 b861 c0a8 0001 c0a8 00c7")}</tdml:documentPart>
+          </tdml:document>
+          <tdml:infoset>
+            <tdml:dfdlInfoset>
+              <ipv4:IPv4Header>
+                <Version>4</Version>
+                <IHL>5</IHL>
+                <DSCP>0</DSCP>
+                <ECN>0</ECN>
+                <Length>115</Length>
+                <Identification>0</Identification>
+                <Flags>2</Flags>
+                <FragmentOffset>0</FragmentOffset>
+                <TTL>64</TTL>
+                <Protocol>17</Protocol>
+                <Checksum>47201</Checksum>
+                <IPSrc>C0A80001</IPSrc>
+                <IPDest>C0A800C7</IPDest>
+                <FakeData>115</FakeData>
+                <ComputedChecksum>47201</ComputedChecksum>
+              </ipv4:IPv4Header>
+            </tdml:dfdlInfoset>
+          </tdml:infoset>
+        </tdml:parserTestCase>
+      )
+    val actualParserTestCase: ParserTestCaseType =
+      testSuite
+        .testSuiteChoices
+        .headOption
+        .map(_.as[ParserTestCaseType])
+        .getOrElse(throw new AssertionError("first test case is missing")) // 
fail() returns Unit so mimic JUnit
+    assertEquals(expectedParserTestCase, actualParserTestCase)
+  }
+}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 58544267c..b54c8b0cc 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -26,3 +26,5 @@ addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9")
 addSbtPlugin("com.github.sbt" % "sbt-unidoc" % "0.5.0")
 
 addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
+
+addSbtPlugin("org.scalaxb" % "sbt-scalaxb" % "1.12.0")


Reply via email to