stevedlawrence commented on a change in pull request #129: Cross Testing 
Capability with IBM DFDL
URL: https://github.com/apache/incubator-daffodil/pull/129#discussion_r229682037
 
 

 ##########
 File path: 
daffodil-tdml/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
 ##########
 @@ -437,69 +454,116 @@ abstract class TestCase(testCaseXML: NodeSeq, val 
parent: DFDLTestSuite)
   lazy val defaultRoundTrip: RoundTrip = parent.defaultRoundTrip
   lazy val defaultValidation: String = parent.defaultValidation
 
-  /**
-   * This doesn't fetch a serialized processor, it runs whatever the processor 
is
-   * through a serialize then unserialize path to get a processor as if
-   * it were being fetched from a file.
-   */
-  private def generateProcessor(pf: DFDL.ProcessorFactory, 
useSerializedProcessor: Boolean): DFDLTestSuite.CompileResult = {
-    val p = pf.onPath("/")
-    val diags = p.getDiagnostics
-    if (p.isError) Left(diags)
-    else {
-      val dp =
-        if (useSerializedProcessor) {
-          val os = new java.io.ByteArrayOutputStream()
-          val output = Channels.newChannel(os)
-          p.save(output)
-
-          val is = new java.io.ByteArrayInputStream(os.toByteArray)
-          val input = Channels.newChannel(is)
-          val compiler_ = Compiler()
-          compiler_.reload(input)
-        } else p
+  private lazy val defaultImplementations: Seq[String] = 
parent.defaultImplementations
+  private lazy val tcImplementations = (testCaseXML \ "@implementations").text
+  private lazy val implementationStrings =
+    if (tcImplementations == "") defaultImplementations
+    else tcImplementations.split("""\s+""").toSeq
 
-      Right((diags, dp))
-    }
-  }
-
-  private def compileProcessor(schemaSource: DaffodilSchemaSource, 
useSerializedProcessor: Boolean): DFDLTestSuite.CompileResult = {
-    val pf = compiler.compileSource(schemaSource)
-    val diags = pf.getDiagnostics
-    if (pf.isError) {
-      Left(diags) // throw new TDMLException(diags)
-    } else {
-      val res = this.generateProcessor(pf, useSerializedProcessor)
-      res
-    }
-  }
-
-  final protected def getProcessor(schemaSource: DaffodilSchemaSource, 
useSerializedProcessor: Boolean): DFDLTestSuite.CompileResult = {
-    val res: DFDLTestSuite.CompileResult = schemaSource match {
-      case uss: URISchemaSource =>
-        SchemaDataProcessorCache.compileAndCache(uss, useSerializedProcessor,
-          parent.checkAllTopLevel,
-          root,
-          null) {
-            compileProcessor(uss, useSerializedProcessor)
+  lazy val implementations: Seq[TDMLDFDLProcessorFactory] = {
+    //
+    // just by way of eating our own dogfood, we're always going to dynaload 
the
+    // processor, even for the built-in Daffodil one.
+    //
+    lazy val dafpfs = 
dynamicLoadTDMLProcessorFactory(Runner.daffodilTDMLDFDLProcessorFactoryName)
+    val allImpls = {
+      if (parent.optDebugger.isDefined)
+        dafpfs // when debugging or tracing, we only run daffodil, ignore 
other implementations
+      else {
+        implementationStrings.flatMap { s =>
+          s.toLowerCase match {
+              //
+              // When adding another processor implementation to a test case
+              // you can also use daffodil by just specifying 
implementations="daffodil otherOne.full.class.name"
+              // That is, you don't have to use a class name for daffodil.
+            case "daffodil" => dafpfs
+            case _ => dynamicLoadTDMLProcessorFactory(s)
           }
-      case _ => {
-        compileProcessor(schemaSource, useSerializedProcessor)
+        }
       }
     }
+    allImpls.foreach {
+      _.setValidateDFDLSchemas(parent.validateDFDLSchemas)
+    }
+    if (allImpls.isEmpty) throw new TDMLException("No TDML DFDL 
implementations found for '%s'".format(implementationStrings.mkString(", ")))
+    allImpls
+  }
+
+  private lazy val tdmlDFDLProcessorFactoryTraitName = {
+    import scala.language.reflectiveCalls
+    // Doing this so that if we decide to rename the verbose class name here
+    // it will handle this code too.
+    // Also we can rename the packages, etc.
+    val clazzTag = scala.reflect.classTag[TDMLDFDLProcessorFactory]
+    val cname = clazzTag.toString()
+    cname
+  }
+
+  def dynamicLoadTDMLProcessorFactory(className: String): 
Seq[TDMLDFDLProcessorFactory] = {
+    import scala.language.reflectiveCalls
+    import scala.language.existentials
+
+    val clazz = Try(Class.forName(className))
+    val constructor = clazz.map{ _.getDeclaredConstructor() }
+    val tryInstance = constructor.map{ 
_.newInstance().asInstanceOf[TDMLDFDLProcessorFactory] }
+    val res = tryInstance match {
+      case Success(instance) => Seq(instance)
+      case Failure(e) => {
+        // issue warnings
+        val warnMsgGuts =
+        e match {
+          case e: ClassNotFoundException =>  ": ClassNotFoundException - did 
not find implementation '%s'.".format(className)
+          case e: NoClassDefFoundError =>  ": NoClassDefFoundError - did not 
find implementation '%s'.".format(className)
+          case e: NoSuchMethodException => "found implementation %s, but it 
has no default constructor.".format(className)
+          case e: InstantiationException => "found implementation %s, but 
unable to create an instance due to:%s.".format(className, e.getMessage())
+          case e: ClassCastException => "found implementation '%s'. But it was 
not an instance of %s. No tests will be run against it.".format(
+            className, tdmlDFDLProcessorFactoryTraitName)
+          case e => "for implementation %s - cannot use due to unexpected 
exception %s.".format(className, e.getMessage())
+      }
+        this.parent.log(LogLevel.Warning, "TDML Runner %s No tests will be run 
against it.", warnMsgGuts)
+        Seq()
+    }
 
 Review comment:
   I think the braces are indented wrong here?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to