stevedlawrence commented on a change in pull request #394:
URL: https://github.com/apache/incubator-daffodil/pull/394#discussion_r455010022



##########
File path: 
daffodil-core/src/main/scala/org/apache/daffodil/dsom/walker/RecordWalker.scala
##########
@@ -0,0 +1,309 @@
+/*
+ * 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.dsom.walker
+
+import java.io.File
+import java.util
+
+import org.apache.daffodil.dsom.{Choice, ComplexTypeBase, ElementBase, 
GroupRef, Root, Sequence, SimpleTypeBase, Term}
+import org.apache.nifi.serialization.SimpleRecordSchema
+import org.apache.nifi.serialization.record.{DataType, RecordField, 
RecordFieldType, RecordSchema, SchemaIdentifier}
+import org.apache.nifi.serialization.record.`type`.RecordDataType
+import scala.collection.mutable.ListBuffer
+
+/**
+ * Direct subclass of the NIFI RecordField.  NIFI doesn't have "Optional" 
fields, so
+ * eventually this will either be removed from the Schema if an Infoset 
doesn't have the field,
+ * or it will become a regular RecordField if it does.
+ * @param fieldName the name for the RecordField
+ * @param dataType the NIFI DataType of this RecordField
+ */
+class OptionalRecordField(fieldName: String, dataType: DataType)
+  extends RecordField(fieldName, dataType) {
+  // this is the easiest way to construct it; essentially a "copy constructor" 
except to denote
+  // that we want to treat it as this special optional subclass.
+  def this(recordField: RecordField) = this(recordField.getFieldName, 
recordField.getDataType)
+  override def equals(obj: Any): Boolean =
+    obj match {
+      case _: OptionalRecordField => super.equals(obj)
+      case _ => false
+    }
+  override def hashCode(): Int = 31 * super.hashCode() + 1
+  override def toString: String = "Optional" + super.toString
+}
+
+/**
+ * Concrete implementation of the AbstractDSOMWalker abstract class.
+ * This class produces a NIFI RecordSchema that is intended to match the 
original DFDL file.
+ *
+ * The RecordSchema is built in 3 primary stages:
+ * 1) A tree of SchemaNodes is created as the DFDL file is walked; this walk 
is performed
+ * through the various event handlers defined in the parent abstract class.
+ * 2) The tree of SchemaNodes undergoes some post-processing, mainly to remove 
redundant Record wrappers.
+ * 3) The tree of SchemaNodes is converted into a RecordSchema; it is walked 
recursively within this class.
+ * @param schemaFile an input DFDL Schema file to parse
+ */
+class RecordWalker(schemaFile: File) extends 
AbstractDSOMWalker[RecordSchema](schemaFile) {

Review comment:
       Re: the nifi-daffodil repo, if you're able to modify the nifi-daffodil 
repo to support scala, it should work fine in theory. I suspect the new 
controllers are mostly separate from the existing processors?
   
   Re: walkDSOM on ProcessorFactory, I think after discussions the consensus is 
that while a recursive walk is useful, there may be cases where it isn't 
sufficient. So I would suggust that we move all the ``walkDSOM`` functions off 
of the Views and onto the AbstractDSOMWalker (just like you had originally), so 
the AbstractDSOM walker has all the logic for how to recursively walk a DSOM. 
Then the only new function need on the the ProcessorFactory is an ability to 
get the RootView. If one wants to traverse this RootView manually, they can do 
so. But if they just want to traverse it recrusively and get events, they can 
create a concrete implementation of the AbstractDSOMWalker and implement those 
events (and potential override the walkDSOM function if they want. So for 
example:
   ```scala
   val rootView = processorFactory.rootView
   val walker = new DSOMWalkerImpl()
   walker.walkDSOM(rootView)
   ```
   So the View's don't contain any logic about how they should be traversed, 
since they don't really know that. Recurisve makes sense, but presumable there 
are reasonable traversals. And technically the AbstractDSOMWalker isn't even 
neccessary--the views have all the information needed to traverse them. But to 
be helpful, it makes sense to also provide a AbstractDSOMWalker interface that 
contains all the logic for traversing recursively so users don't have to think 
about that and can just think of it as a series of events.
   
   So this is very similar to what you originally started with, but just with 
Views to hide internal details of our dsom objects.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to