Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added SAXInfosetInputter base class

...

ContentHandlergetContentHandler()
Return the current content handler.
DTDHandlergetDTDHandler()
Return the current DTD handler.
EnyoutityResolvergetEntityResolver()
Return the current entity resolver.
ErrorHandlergetErrorHandler()
Return the current error handler.
booleangetFeature(String name)
Look up the value of a feature flag. The only two features that are implemented are http://xml.org/sax/features/namespaces and http://xml.org/sax/features/namespace-prefixes as required by the XMLReader interface. All other features shall throw a SAXNotRecognizedException.
Object

getProperty(String name)
Look up the value of a property URN. We support the following:

voidparse(InputSource input)
Parse data from an InputSource. The InputSource must be backed by an InputStream. The getByteStream() method must return non-null or an IOException shall be thrown. This shall call the custom parse(InputStream)  method described below.
voidparse(String systemId)
This function is not supported. If called, this shall throw an IOException.
voidsetContentHandler(ContentHandler handler)
Store the parameter in local state. This handler will receive the SAX events created by Daffodil.
voidsetDTDHandler(DTDHandler handler)
Store the parameter in local state. Note that Daffodil will never use the DTDHandler except for when getDTDHandler()  is called.
voidsetEntityResolver(EntityResolver resolver)
Store the parameter in local state. Note that Daffodil will never use the EntityResolver except for when getEntityResolver()  is called.
voidsetErrorHandler(ErrorHandler handler)
Store the parameter in local state. The handler.fatalError()  callback is used for Schema Definition Errors. The handler.warning()  callback is used for Schema Definition Warnings.
voidsetFeature(String name, boolean value)
Set the value of a feature flag. The only two features that are implemented are http://xml.org/sax/features/namespaces and http://xml.org/sax/features/namespace-prefixes as required by the XMLReader interface. All other features shall throw a SAXNotRecognizedException.
void

setProperty(String name, Object value)
Set the value of a property. We only support the setting of the propeties below. All other propeties shall throw a SAXNotRecognizedException. Property values must be of the type defined below, otherwise it will throw a SAXNotSupportedException.

PropertyVAlue Type
BlobDirectoryjava.nio.file.Paths
BlobPrefixString
BlobSuffixString


Info

ParseResult cannot be set externally


...

Code Block
scala
scala
class DaffodilUnparseContentHandler(dp: DataProcessor, output: OutputStream) extends ContentHandler with coroutine[SAXInfosetEvent] {
  
  private val infoseEvent = new SAXInfosetEvent()
  private val inputter = new SAXInfosetInputter(this, dp, output)


  private def sendtoInputter(....) {
    // queueing the infosetEvent for SAXInfosetInputter
	val infosetEventWithResponse = this.resume(inputter, Try(infosetEvent))
    infosetEvent.clear()
    // if event is wrapped in a Try failure, we will not have an unparseResult, so we only set
    // unparseResults for events wrapped in Try Success, including those events that have expected
    // errors
    if (infosetEventWithResponse.isSuccess && infosetEventWithResponse.get.unparseResult.isDefined) {
      unparseResult = infosetEventWithResponse.get.unparseResult.get
    }
    // the exception from events wrapped in Try failures and events wrapped in Try Successes
    // (with an unparse error state i.e unparseResult.isError) are collected and thrown to stop
    // the execution of the xmlReader
    if (infosetEventWithResponse.isFailure || infosetEventWithResponse.get.isError) {
      val causeError = if(infosetEventWithResponse.isFailure) {
        infosetEventWithResponse.failed.get
      } else {
        infosetEventWithResponse.get.causeError.get
      }
      causeError match {
        case unparseError: DaffodilUnparseErrorSAXException =>
          // although this is an expected error, we need to throw it so we can stop the xmlReader
          // parse and this thread
          throw unparseError
        case unhandled: DaffodilUnhandledSAXException => throw unhandled
        case unknown => throw new DaffodilUnhandledSAXException("Unknown exception: ", new Exception(unknown))
      }
    }
  }

  def startDocument() {
    // Start the coroutine
    infosetEvent.eventType = One(StartDocument)
    sendToInputter()
  }

  def endDocument() {
    infosetEvent.eventType = One(EndDocument)
    sendToInputter()
  }
  
  ...
}

class SAXInfosetInputter(unparseContentHandler: DaffodilUnparseContentHandler, dp: DataProcessor, output: OutputStream) extends InfosetInputter with coroutine[SAXInfosetEvent] {

  val currentEvent: SAXInfosetEvent = new SAXInfosetEvent
  val nextEvent: SAXInfosetEvent = new SAXInfosetEvent  

  def getEventType: InfosetInputterEventType = currentEvent.eventType.orNull
  def getLocalName: String = currentEvent.localName.orNull
  def getNamespaceURI: String = currentEvent.namespaceURI.orNull
  ...

  def hasNext: Boolean = {
    if (endDocumentReceived) false
    else if (!nextEvent.isEmpty) true
    else {
      val event = this.resume(unparseContentHandler, Try(currentEvent))
      copyEvent(source = event, dest = nextEvent)
      true
    }
  }

  def next(): Unit = {
    if (hasNext()) {
      copyEvent(source = Try(nextEvent), dest = currentEvent)
      nextEvent.clear()
      if (currentEvent.eventType.contains(EndDocument)) endDocumentReceived = true
    } else {
      // we should never call next() if hasNext() is false
      Assert.abort()
    }
  }
  ...
}

class SAXInfosetEvent() {

  var localName: Maybe[String] = Nope
  var simpleText: Maybe[String] = Nope
  var namespaceURI: Maybe[String] = Nope
  var eventType: Maybe[InfosetInputterEventType] = Nope
  var nilValue: Maybe[String] = Nope
  var causeError: Maybe[SAXException] = Nope
  var unparseResult: Maybe[UnparseResult] = Nope

  def isError: Boolean
  def clear: Unit
  def isEmpty: Boolean
}

...