API - Pipeline Engine API

Introduction

The pipeline engine API allows embedding the execution of pipelines in your Java applications, whether server-side or client-side.

API

The reference example using those APIs is the command-line application found under OPS.java. The steps required to execute a pipeline are detailed below. Please also refer to the source code of OPS.java.

Parse the command-line arguments

Please refer to the source code for more details.

Initialize a resource manager

Pipelines usually access resources (or files) through an abstraction layer composed of one or more resource managers. The code below initializes a Priority Resource Manager, which attempts to load resources first from the filesystem, then from the classloader. The reason for using the classloader is that the Orbeon JAR file contain bundled configuration resources that must be accessible.

In this particular case, if the -r command-line argument is present, a sandbox directory path is passed to the Filesystem resource manager upon instanciation.

Map props = new HashMap();
props.put("oxf.resources.factory", "org.orbeon.oxf.resources.PriorityResourceManagerFactory");
if (resourceManagerSandbox != null) {
    // Use a sandbox
    props.put("oxf.resources.filesystem.sandbox-directory", resourceManagerSandbox);
}
props.put("oxf.resources.priority.1", "org.orbeon.oxf.resources.FilesystemResourceManagerFactory");
props.put("oxf.resources.priority.2", "org.orbeon.oxf.resources.ClassLoaderResourceManagerFactory");
if (logger.isInfoEnabled())
    logger.info("Initializing Resource Manager with: " + props);
ResourceManagerWrapper.init(props);

Initialize Orbeon Forms properties

This initializes the Orbeon Forms properties with the default properties file bundled in the Orbeon JAR file.

OXFProperties.init(OXFProperties.DEFAULT_PROPERTIES_URI);

Initialize logger based on properties

This initializes a logger.

LoggerFactory.initLogger();

Build a processor definition object

This step builds a ProcessorDefinition object containing the name of the processor to run (here the oxf:pipeline processor), as well as the URL to bind to the config input of that processor. The mapping of processor names to classes is done in processors.xml, a resource bundled in the Orbeon JAR file.

if (otherArgs != null && otherArgs.length == 1) {
    // Assume the pipeline processor and a config input
    processorDefinition = new ProcessorDefinition();
    processorDefinition.setName(new QName("pipeline", XMLConstants.OXF_PROCESSORS_NAMESPACE));

    String configURL;
    if (!NetUtils.urlHasProtocol(otherArgs[0])) {
        // URL is considered relative to current directory
        try {
            // Create absolute URL, and switch to the oxf: protocol
            String fileURL = new URL(new File(".").toURL(), otherArgs[0]).toExternalForm();
            configURL = "oxf:" + fileURL.substring(fileURL.indexOf(':') + 1);
        } catch (MalformedURLException e) {
            throw new OXFException(e);
        }
    } else {
        configURL = otherArgs[0];
    }

    processorDefinition.addInput("config", configURL);
} else {
    throw new OXFException("No main processor definition found.");
}

Initialize a PipelineContext

The PipelineContext represents a context object passed to all the processors running in a given pipeline session. In general, you just need to create an instance.

PipelineContext pipelineContext = new PipelineContext();

// Some processors may require a JNDI context. In general, this is not required.
Context jndiContext;
try {
    jndiContext = new InitialContext();
} catch (NamingException e) {
    throw new OXFException(e);
}
pipelineContext.setAttribute(PipelineContext.JNDI_CONTEXT, jndiContext);

Run the pipeline

This is where all the real work is done. A PipelineEngineFactory instanciates a PipelineEngine object, which then runs the pipeline. This method is provided with the ProcessorDefinition and the PipelineContext created earlier, as well as an ExternalContext instance providing input and output access to the pipeline.

PipelineEngineFactory.instance().executePipeline(processorDefinition, new CommandLineExternalContext(), pipelineContext);

Display exceptions if needed

If an exception is caught, information about the error is displayed.

LocationData locationData = ValidationException.getRootLocationData(e);
Throwable throwable = OXFException.getRootThrowable(e);
String message = locationData == null
        ? "Exception with no location data"
        : "Exception at " + locationData.toString();
logger.error(message, throwable);

Comments