Skip navigation links

Package org.apache.daffodil.japi

Provides the classes necessary to compile DFDL schemas, parse and unparse files using the compiled objects, and retrieve results and parsing diagnostics

See: Description

Package org.apache.daffodil.japi Description

Provides the classes necessary to compile DFDL schemas, parse and unparse files using the compiled objects, and retrieve results and parsing diagnostics

Overview

The Daffodil object is a factory object to create a Compiler. The Compiler provides a method to compils a provided DFDL schema into a ProcessorFactory, which creates a DataProcessor:
 
 Compiler c = Daffodil.compiler();
 ProcessorFactory pf = c.compileFile(file);
 DataProcessor dp = pf.onPath("/");
 
The DataProcessor provides the necessary functions to parse and unparse data, returning a ParseResult or UnparseResult, respectively. These contain information about the parse/unparse, such as whether or not the processing succeeded any diagnostic information.

Parse

The DataProcessor.parse(java.nio.channels.ReadableByteChannel, org.apache.daffodil.japi.infoset.InfosetOutputter, long) method accepts input data to parse in the form of a ReadableByteChannel and an InfosetOutputter to determine the output representation of the infoset (e.g. Scala XML Nodes, JDOM2 Documents, etc.):
 
 JDOMInfosetOutputter jdomOutputter= new JDOMInfosetOutputter();
 ParseResult pr = dp.parse(data, jdomOutputter);
 Document doc = jdomOutputter.getResult();
 
The DataProcessor.parse(java.nio.channels.ReadableByteChannel, org.apache.daffodil.japi.infoset.InfosetOutputter, long) method is thread-safe and may be called multiple times without the need to create other data processors. However, InfosetOutputter's are not thread safe, requiring a unique instance per thread. An InfosetOutputter should call InfosetOutputter.reset() before reuse (or a new one should be allocated). For example:
 
 JDOMInfosetOutputter jdomOutputter = new JDOMInfosetOutputter();
 for (File f : inputFiles) {
   jdomOutputter.reset();
   ParseResult pr = dp.parse(f, jdomOutputter);
   Document doc = jdomOutputter.getResult();
 }
 

Unparse

The same DataProcessor used for parse can be used to unparse an infoset via the DataProcessor.unparse(org.apache.daffodil.japi.infoset.InfosetInputter, java.nio.channels.WritableByteChannel) method. An InfosetInputter provides the infoset to unparse, with the unparsed data written to the provided WritableByteChannel. For example:
 
 JDOMInfosetInputter jdomInputter = new JDOMInfosetInputter(doc);
 UnparseResult ur = dp.unparse(jdomInputter, wbc)
 

Failures and Diagnostics

It is possible that failures could occur during the creation of the ProcessorFactory, DataProcessor, or ParseResult. However, rather than throwing an exception on error (e.g. invalid DFDL schema, parse error, etc), these classes extend WithDiagnostics, which is used to determine if an error occurred, and any diagnostic information (see Diagnostic) related to the step. Thus, before continuing, one must check WithDiagnostics.isError(). For example:
 
 ProcessorFactor pf = c.compile(files);
 if (pf.isError()) {
   java.util.List<Diagnostic> diags = pf.getDiagnostics();
   foreach (Diagnostic d : diags) {
     System.out.println(d.toString());
   }
   return -1;
 }
 

Saving and Reloading Parsers

In some cases, it may be beneficial to save a parser and reload it. For example, when starting up, it may be quicker to reload an already compiled parser than to compile it from scratch. To save a DataProcessor:
 
 DataProcessor dp = pf.onPath("/");
 dp.save(saveFile);
 
And to restore a saved DataProcessor:
 
 DataProcessor dp = Daffodil.reload(saveFile);
 ParseResult pr = dp.parse(data);
 
Skip navigation links