You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ar...@apache.org on 2022/08/05 17:38:22 UTC

[daffodil-vscode] 18/28: Pull out TDML-specific code into separate object Temporarily replace TDML code with logger statements to figure out why TDML is not being called.

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

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

commit d9935d872e63323d035b13bfb53721b77135b035
Author: Michael Hoke <mi...@nteligen.com>
AuthorDate: Thu Jul 21 11:34:01 2022 -0400

    Pull out TDML-specific code into separate object
    Temporarily replace TDML code with logger statements
      to figure out why TDML is not being called.
---
 .../org.apache.daffodil.debugger.dap/Parse.scala   |  85 +++++-------
 .../main/scala/org.apache.daffodil.tdml/TDML.scala | 143 +++++++++++++++++++++
 2 files changed, 174 insertions(+), 54 deletions(-)

diff --git a/server/core/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala b/server/core/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
index dff5e98..97903e1 100644
--- a/server/core/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
+++ b/server/core/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
@@ -46,10 +46,8 @@ import org.apache.daffodil.util.Misc
 import org.typelevel.log4cats.Logger
 import org.typelevel.log4cats.slf4j.Slf4jLogger
 import scala.util.Try
-import org.apache.commons.io.output.NullOutputStream
-import org.apache.daffodil.tdml._
-import javax.xml.bind.JAXBContext
-import org.apache.commons.io.FilenameUtils
+// import org.apache.commons.io.output.NullOutputStream
+// import org.apache.daffodil.tdml.TDML
 
 trait Parse {
 
@@ -356,61 +354,40 @@ object Parse {
             } ++ Stream.eval(
               dapEvents.offer(None) // ensure dapEvents is terminated when the parse is terminated
             ) ++ Stream.eval(
-              args.infosetOutput match {
+              args.tdmlConfig match {
+                case Debugee.LaunchArgs.TDMLConfig.Config(action, _, _, _) =>
+                  if (action == "generate")
+                    args.infosetOutput match {
+                      case Debugee.LaunchArgs.InfosetOutput.File(_) =>
+                        Logger[IO].debug("Makes it into the generate")
+                        // TDML.generate(path.toString(), args.dataPath.toString(), args.schemaPath.toString(), name, description, tdmlPath)
+                      case _ =>
+                        Logger[IO].debug("Non-file InfosetOutput")
+                        // IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))
+                    }
+                  else
+                    Logger[IO].debug("TDMLConfig is not generate")
+                    // IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))  
+                case _ =>
+                  Logger[IO].debug("Not sure why this is here")
+                  // IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))
+              /* args.infosetOutput match {
                 case Debugee.LaunchArgs.InfosetOutput.File(path) =>
-                 // if (Debugee.LaunchArgs.InfosetOutput.File(path))
-                  /* Resource.make {
-                    IO(new FileOutputStream(path.toFile()))
-                  } { outStream =>
-                    IO(outStream.close()).handleErrorWith(_ => IO.unit)
-                  } */
-                  val factory = new ObjectFactory()
-
-                  val dfdlInfoset = factory.createDfdlInfosetType()
-                  dfdlInfoset.setType("file")
-                  dfdlInfoset.getContent().add(path)
-
-                  val infoset = factory.createInfosetType()
-                  infoset.setDfdlInfoset(dfdlInfoset)
-
-                  val docPart = factory.createDocumentPartType()
-                  docPart.setType(DocumentPartTypeEnum.FILE)
-                  docPart.setValue(args.dataPath.toString())
-
-                  val doc = factory.createDocumentType()
-                  doc.getContent().add(docPart)
-
-                  val testCase = factory.createParserTestCaseType()
-                  testCase.setName(FilenameUtils.getBaseName(args.schemaPath.toString()))
-                  testCase.setRoot("file")
-                  testCase.setModel(args.schemaPath.getFileName().toString())
-                  testCase.setDescription("Generated by DFDL VSCode Extension")
-                  testCase.setRoundTrip(RoundTripType.ONE_PASS)
-                  testCase.getTutorialOrDocumentOrInfoset().add(doc)
-
-                  val testSuite = factory.createTestSuite()
-                  testSuite.setSuiteName(FilenameUtils.getBaseName(args.schemaPath.toString()))
-                  testSuite.setDefaultRoundTrip(RoundTripType.ONE_PASS)
-                  testSuite.getTutorialOrParserTestCaseOrDefineSchema().add(testCase)
-
                   args.tdmlConfig match {
-                    case Debugee.LaunchArgs.TDMLConfig.Config(_, _, _, tdml_path) =>
-                      IO(JAXBContext.newInstance(classOf[TestSuite]).createMarshaller().marshal(testSuite, new FileOutputStream(tdml_path)))
+                    // case Debugee.LaunchArgs.TDMLConfig.Config(action, name, description, tdmlPath) =>
+                      if (action == "generate")
+                        Logger[IO].debug("Makes it into the generate")
+                        // TDML.generate(path.toString(), args.dataPath.toString(), args.schemaPath.toString(), name, description, tdmlPath)
+                      else
+                        Logger[IO].debug("TDMLConfig is None")
+                        // IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))  
                     case _ =>
-                      IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))
+                      Logger[IO].debug("Not sure why this is here")
+                      // IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))
                   }
-                  
-            
-                  
-                  // path.toString()
                 case _ =>
-                  /* Resource.make {
-                    IO(new ByteArrayOutputStream(0))
-                  } { outStream =>
-                    IO(outStream.close()).handleErrorWith(_ => IO.unit)  
-                  } */
-                  IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM))
-                  // ""
+                  Logger[IO].debug("Non-file InfosetOutput")
+                  // IO(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM)) */
               }
             ),
             infosetChanges
diff --git a/server/core/src/main/scala/org.apache.daffodil.tdml/TDML.scala b/server/core/src/main/scala/org.apache.daffodil.tdml/TDML.scala
new file mode 100644
index 0000000..c36ff88
--- /dev/null
+++ b/server/core/src/main/scala/org.apache.daffodil.tdml/TDML.scala
@@ -0,0 +1,143 @@
+package org.apache.daffodil.tdml
+
+import javax.xml.bind.JAXBContext
+import java.io.FileOutputStream
+import cats.effect.IO
+import java.io.File
+
+// TODO: Put TDML path in class definition?
+object TDML {
+  // Create a ParserTestCaseType object that can be put into a TestSuite
+  // These types are generated when JAXB is executed on the TDML schema
+  // 
+  // The format of the new ParserTestCase is as follows:
+  // 
+  // <tdml:parserTestCase name="$tdmlName" root="file" model="$schemaPath" description="$tdmlDescription" roundTrip="onePass">
+  //   <tdml:document>
+  //     <tdml:documentPart type="file">$dataPath</tdml:documentPart>
+  //   <tdml:document>
+  //   <tdml:infoset>
+  //     <tdml:dfdlInfoset type="file">$infosetPath</tdml:dfdlInfoset>
+  //   </tdml:infoset>
+  // </tdml:parserTestCase>
+  // 
+  // infosetPath:     Path to the infoset
+  // dataPath:        Path to the data file
+  // schemaPath:      Path to the DFDL Schema
+  // tdmlName:        Name of the DFDL operation
+  // tdmlDescription: Description for the DFDL operation
+  // 
+  // Returns the ParserTestCase object created with the applied paths
+  def createTestCase(infosetPath: String, dataPath: String, schemaPath: String, tdmlName: String, tdmlDescription: String) = {
+    val factory = new ObjectFactory()
+
+    val dfdlInfoset = factory.createDfdlInfosetType()
+    dfdlInfoset.setType("file")
+    dfdlInfoset.getContent().add(infosetPath)
+
+    val infoset = factory.createInfosetType()
+    infoset.setDfdlInfoset(dfdlInfoset)
+
+    val docPart = factory.createDocumentPartType()
+    docPart.setType(DocumentPartTypeEnum.FILE)
+    docPart.setValue(dataPath.toString())
+
+    val doc = factory.createDocumentType()
+    doc.getContent().add(docPart)
+
+    val testCase = factory.createParserTestCaseType()
+    testCase.setName(tdmlName)
+    testCase.setRoot("file")
+    testCase.setModel(schemaPath)
+    testCase.setDescription(tdmlDescription)
+    testCase.setRoundTrip(RoundTripType.ONE_PASS)
+    testCase.getTutorialOrDocumentOrInfoset().add(doc)
+    testCase.getTutorialOrDocumentOrInfoset().add(infoset)
+  }
+
+  // Generate a new TDML file.
+  // There is a suiteName attribute in the root element (TestSuite) of the document. This is set to $tdmlName
+  // Paths given to this function should be relative as it should be expected for the TDML files to be shared on the mailing list
+  //
+  // infosetPath:     Path to the infoset
+  // dataPath:        Path to the data file
+  // schemaPath:      Path to the DFDL Schema
+  // tdmlName:        Name of the DFDL operation
+  // tdmlDescription: Description for the DFDL operation
+  // tdmlPath:        Path to the TDML file
+  // 
+  // There is a suiteName attribute in the root element of the document. This is set to $tdmlName
+  // TODO: I think the return type here should just be Unit
+  def generate(infosetPath: String, dataPath: String, schemaPath: String, tdmlName: String, tdmlDescription: String, tdmlPath: String): IO[Unit] = {
+    val factory = new ObjectFactory()
+
+    val testSuite = factory.createTestSuite()
+    testSuite.setSuiteName(tdmlName)
+    testSuite.setDefaultRoundTrip(RoundTripType.ONE_PASS)
+    testSuite.getTutorialOrParserTestCaseOrDefineSchema().add(createTestCase(infosetPath, dataPath, schemaPath, tdmlName, tdmlDescription))
+
+    IO(JAXBContext.newInstance(classOf[TestSuite]).createMarshaller().marshal(testSuite, new FileOutputStream(tdmlPath)))
+  }
+
+  // Append a new test case to an existing TDML file.
+  // Paths given to this function should be relative as it should be expected for the TDML files to be shared on the mailing list
+  // 
+  // infosetPath:     Path to the infoset
+  // dataPath:        Path to the data file
+  // schemaPath:      Path to the DFDL Schema
+  // tdmlName:        Name of the DFDL operation
+  // tdmlDescription: Description for the DFDL operation
+  // tdmlPath:        Path to the TDML file
+  // 
+  // TODO: I think the return type here should just be Unit
+  def append(infosetPath: String, dataPath: String, schemaPath: String, tdmlName: String, tdmlDescription: String, tdmlPath: String): IO[Unit] = {
+
+    val testSuite = JAXBContext.newInstance(classOf[TestSuite]).createUnmarshaller().unmarshal(new File(tdmlPath)).asInstanceOf[TestSuite]
+
+    testSuite.getTutorialOrParserTestCaseOrDefineSchema().add(createTestCase(infosetPath, dataPath, schemaPath, tdmlName, tdmlDescription))
+
+    IO(JAXBContext.newInstance(classOf[TestSuite]).createMarshaller().marshal(testSuite, new FileOutputStream(tdmlPath)))
+  }
+
+  // Find the parameters needed to execute a DFDL parse based on the given TDML Parameters
+  // 
+  // tdmlName:        Test case name to run
+  // tdmlDescription: Description of test case to run
+  // tdmlPath:        File path of TDML file to extract test case from
+  // 
+  // Returns a tuple containing the following (Path to DFDL Schema, Path to Data File)
+  // All paths returned could be either relative or absolute - it depends on what exists in the TDML file
+  def execute(tdmlName: String, tdmlDescription: String, tdmlPath: String): (String, String) = {
+    val testCaseList = JAXBContext.newInstance(classOf[TestSuite]).createUnmarshaller().unmarshal(new File(tdmlPath)).asInstanceOf[TestSuite].getTutorialOrParserTestCaseOrDefineSchema()
+
+    testCaseList.forEach { tc =>
+      // var foundDoc = ""
+      // var foundInfoset = ""
+
+      // TODO: Do I really have to cast to instances every time? I've already checked that they are...
+      if (tc.isInstanceOf[ParserTestCaseType]) {
+        // Match name and description of potential test case
+        if (tc.asInstanceOf[ParserTestCaseType].getName() == tdmlName && tc.asInstanceOf[ParserTestCaseType].getDescription() == tdmlDescription) {
+          tc.asInstanceOf[ParserTestCaseType].getTutorialOrDocumentOrInfoset().forEach { dis =>
+            if (dis.isInstanceOf[DocumentType]) {
+              // foundDoc = dis.asInstanceOf[DocumentType].getContent().indexOf(0).asInstanceOf[DocumentPartType].getValue()
+              // if (!foundInfoset.isEmpty()) {
+                // return (tc.asInstanceOf[ParserTestCaseType].getModel(), foundInfoset, foundDoc)
+              // }
+              return (tc.asInstanceOf[ParserTestCaseType].getModel(), dis.asInstanceOf[DocumentType].getContent().indexOf(0).asInstanceOf[DocumentPartType].getValue())
+            }
+            // else if (dis.isInstanceOf[InfosetType]) {
+              // foundInfoset = dis.asInstanceOf[InfosetType].getDfdlInfoset().getContent().indexOf(0).asInstanceOf[String]
+              // if (!foundDoc.isEmpty()) {
+                // return (tc.asInstanceOf[ParserTestCaseType].getModel(), foundInfoset, foundDoc)
+              // }
+            // }
+          }
+        }
+      }
+    }
+
+    // If there is no test case in the TDML file meeting the name/description criteria, return empty
+    ("", "")
+  }
+}