stevedlawrence opened a new pull request, #1572:
URL: https://github.com/apache/daffodil/pull/1572

   When unparsing using the SAX API, if an XMLReader ends the parse early 
(usually due to invalid XML), then it stops sending events to the 
DaffodilUnparseContentHandler. This can lead to dangling threads since the 
DaffodilUnparseCotentHandler and SAXInfosetInputter are coroutines, which uses 
threads behind the scenes.
   
   To fix this, we add a new finish() method to the
   DaffodilUnparseContentHandler which should be called by SAX unparse API 
users after the XMLReader parse completes, regardless of success. For example,
   
       val contentHandler = dp.newContentHandlerInstance(...)
       xmlReader.setContentHandler(contentHandler)
       try {
         xmlReader.parse(...)
       } catch (...) {
         ...
       } finally {
         contentHandler.finish()
       }
   
   The new finish function cleans up the coroutines setting the next event to 
null, which indicates to the SAXInfosetInputter coroutine that no more events 
are coming, ands leads to ending the unparse and the coroutine. This now also 
means getUnparseResult will always return a result, even if the XMLReader sees 
invalid XML, which makes our API a bit more consistent.
   
   Note that this discovered a case where the InfosetInputter.initialize() 
method could throw an UnparseError if there was no StartDocument event, which 
was not caught correctly. Fixing this requires moving the initialize call 
inside the try/catch block, which is after the UState is created. This means 
the UState can no longer assert that the InfosetInputter is initialized, but 
this isn't necessary UState creation to succeed, as long as the infoset 
inputter is initialized shortly thereafter.
   
   Deprecation/Compatibility:
   
   A new DaffodilUnparseContentHandler.finish() method is added for users of 
the SAX unparse API. This should be called at the end of the XMLReader.parse() 
method to to ensure all internal state is cleaned up and an unparse result is 
available. For example:
   
       DaffodilUnparseContentHandler contentHandler = 
dp.newContentHandlerInstance();
       xmlReader.setContentHandler(contentHandler);
       try {
           xmlReader.parse(...):
       } catch (...)
           ...
       } finally {
           contentHandler.finish();
       }
       UnparseResult ur = contentHandler.getUnparseResult();
   
   DAFFODIL-2768


-- 
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.

To unsubscribe, e-mail: [email protected]

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

Reply via email to