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 <[email protected]> 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 + ("", "") + } +}
