A Guide to MorganaXProc’s API

This document is a quick guide to using MorganaXProc in your Java applications. If you are not familiar with or not interested in Java programming, you are probably looking for A User's Guide to MorganaXProc.

Overview:

The basis usage pattern

Let us look at an example first:

public static void main(String args){

/* Create an XProcEngine */
XProcEngine engine = XProcEngine.newXProc();
/* Create a new compiler */
XProcCompiler compiler = engine.newXProcCompiler();
/* Create a source with the pipeline */
XProcSource pipelineSource = new XProcSource("file:///mypipelines/pipeline.xpl");
try{

/* Compile the pipeline */
XProcPipeline pipeline = compiler.compile(source);
/* Execute the pipeline */
XProcOutput output = pipeline.run();
/* Check if execution was successful */
if (output.wasSuccessful()){

/* Get names of output ports */
String[] ports = output.getPortNames();
for (int i=0; i < ports.length; i++){

/* Get the results for the port with the given name */
XProcResult result = output.getResults(ports[i]);
/* Get the documents on this port serialized */
String[] document = result.getDocumentsSerialized();
for (int j=0; j < documents.length; j++)

System.out.println(documents[j]);

}

}
else{

/* Examine runtime errors */
System.out.println(output.getErrorDocumentSerialized());

}

}
catch (XProcCompilerException ex){

/* Examine compilation error */
System.out.println(ex.getErrorDocumentSerialized());

}
catch (IOException ex){

System.out.println(ex.getMessage()+" ["+ex.getClass().getName()+"]");

}

}

This code fragment illustrates the basis usage pattern with MorganaXProc:

  1. Generate an XProcEngine instance from one of the static factory methods.
  2. Create a new XProcCompiler instance from it.
  3. Make a new instance of XProcSource with the uri of an XProc pipeline.
  4. Compile your XProc pipeline by using XProcCompiler.compiler(XProcSource source).
  5. If compilation is successful (no Exception thrown): Call run() on the XProcPipeline instance delivered from the compiler.
  6. Check that pipeline execution was successful by XProcResult.wasSuccessful().
  7. If so, deal with the xml documents generated on the <p:output&;gt; ports of your pipeline. If not, inspect the error document generated by calling XProcOutput.getErrorDocumentSerialized().

The instances of XProcEngine, XProcCompiler and XProcSource are reusable, so you have to create them only once as long as you stick to the configuration embedded into the first two classes. Once compiled, you can run an XProcPipeline as many times as you like of course with different documents connected to the input ports of the XProc pipeline.

Inspecting the output of an XProc pipeline

Calling XProcPipeline.run() will always return an instance of XProcOutput representing the results of running the pipeline. If something went wrong during execution, XProcOutput.wasSuccessful() will return "false" and you can get information about the cause of the error by calling XProcOutput.getErrorDocument() or XProcOutput.getErrorDocumentSerialized().

If running the XProc pipeline was successful, XProcOutput holds the results generated on the output ports of the pipeline. To get the results, you have to call XProcOutput.getResults(String portname) to get an XProcResult object for the port with the given name. As you have seen in our code fragment, you can get a list of all output port's names by calling XProcOutput.getPortNames(). You can get the document(s) on an output port by calling XProcResult.getDocuments() or XProcResult.getDocumentsSerialized().

Connecting the input ports of an XProc pipeline

Now as you know how to run an XProc pipeline with MorganaXProc and how to deal with the results of a pipeline execution, let us see how to connect the input ports of an XProc pipeline. To do this, first you have to create a new instance of XProcInput which will hold all connections for all the ports. The actual connection of an xml document to a pipeline's input port, you have to use XProcInput.addInput(String portName, XProcSource source). Here the instance of XProcSource holds the connection information for one document to be connected to the port, which may either be a uri or a XOM document instance. To use an XProcInput on a pipeline execution, call XProcPipeline.run(XProcInput input).

This procedure works well, if every port of your XProc pipeline is meant to be connected to exactly one document. But what about input ports allowing sequences? There a two ways to connect an input port to a sequence of documents: If you repeatedly call XProcInput.addInput(String portName, XProcSource source) with the same port name, the documents associated with the XProcSource will be added to the document list for this port. The other way is to use XProcInput.addInput(String portName, XProcSource[] source) which will add all the XProcSource objects to the document list for the port with the given name. Of course you can combine both methods to attach documents to an input port.

Setting the options of an XProc pipeline

Options declared in an XProc pipeline are also set using an XProcInput instance which is then delivered to the pipeline by calling XProcPipeline(XProcInput input). There are two methods you can use to set an option: XProcInput.setOption(QName optionName, String optionValue) or XProcInput.setOption(String optionName, String optionValue). The only difference between these two methods is that one gives the option's name as a QName, the other gives it as a String. So if you want to set an option in an XProc pipeline that is not declared using a namespace, you can either of them.

Unlike with ports, a setting for an option is replaced when XProcInput.setOption(...) is repeatedly called with the same option name.

Connecting parameters of an XProc pipeline

Concerning parameter input ports it is important that MorganaXProc does make not make a difference between connecting a document input port and a parameter input port, so you can use XProcInput.addInput() for both types of input ports. Additionally you can use XProcInput.setParameter(String portName, String parName, String namespace, String parValue). This method will construct a new <c:param> element, set the given name and the given value, wrap the element into a <c:param-set> and add the resulting document to the connections for the parameter input ports with the given name.

Using XProcConfiguration

As discussed when talking about the command line interface, MorganaXProc comes with a rich set of configuration options. These options can be used from the APIs as well. The relevant class is called XProcConfiguration. Instances of this class are held by the instances of XProcEngine, XProcCompiler and XProcPipeline. In accordance with the succession relation between the instances of these three classes they inherit the configuration from their ancestor, unless you explicitly give an XProcConfiguration instance when creating a new instance. So when you create a new instance of XProcEngine by calling XProcEngine.newXProc() the newly created object will inherit all configuration settings from its ancestor. Respectively an XProcCompiler will inherit the configuration settings from the XProcEngine object it was created from. Lastly any XProcPipeline instance will inherit the configuration settings from the compiler it was created from.

It is important to mention that the configuration settings are inherited, but not the XProcConfiguration itself. Therefore any change made to an XProcConfiguration instance will affect the holder of the instance and its successors but not its ancestors. You can get the XProcConfiguration controlling the behavior of an instance of XProcEngine, XProcCompiler or XProcPipeline by calling method getConfiguration() on any of them.

XProcConfiguration has four methods to create a new instance:

  • copy() creates a new XProcConfiguration with the same settings,
  • newConfiguration() creates a new XProcConfiguration with the default settings and the settings from the default configuration document.
  • newConfiguration(String uri) will create a new XProcConfiguration with the default settings, the settings from the default configuration document and the settings from the configuration document with the given uri.
  • newConfiguration(Element setting) will return a new XProcConfiguration with the default settings, the settings from the default configuration document and the settings taken from the given Element.

The getters and setters of XProcConfiguration correspond to the names of the setting elements discussed in Understanding Options In Configuration with a prefixed "set" or "get". In the API docs you will find more method to set some Java related configuration properties directly from a Java object (and not from a class name).

Having seen the basic pattern of usage and the basic Java classes to use for running XProc pipelines in MorganaXProc, we could now talk about some more advanced features of MorganaXProc's API such as wrappers for non-xml data, connectors to XSLT and XQuery processors and additional steps.