FOray

FOray Users
Module Users
Developers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

The FOray Application

If you wish to use FOray within a servlet or other embedded application, the FOray application as a whole can be considered a module to the embedded application. The purpose of this page is to document the outer API for FOray so that your application can use its features.

Warning: Although The FOray outer API is considered to be stable, it may change in the future to accommodate changing needs.

Contents

Embedded Startup

A working example of the API for running the FOray application can be found in the run() method of the class CommandLineStarter.

FOray follows the “everything is a tree” philosophy in its design, and the API is no exception:

FOraySession
  |
  |--FOrayDocument (one or more)
     |
     |--FOrayTarget (one or more, only the first is processed for now)
        |
        |--LayoutStrategy
        |--OutputTarget (Renderer or Converter)

Each parent encapsulates its own children. In addition:

  • FOraySession encapsulates a Logger, Configuration, FontServer, TextServer, and GraphicServer. After a FOraySession is instantiated, custom Namespace instances can be explicitly registered.
  • FOrayDocument encapsulates the SAX or DOM input, and the parser. It also serves as the FontConsumer implementation for the FOrayFont system, and as the FOTreeControl implementation for the FOrayFOTree system.
  • FOrayTarget encapsulates the OutputStream. It also serves as the FOTreeListener, AreaTreeControl, LayoutControl, and OutputControl implementations which manage the layout and output systems.

By allowing multiple documents and targets to be queued up for processing, this API introduces the possibility of documents and document processes in separate threads while still sharing shareable system resources. In addition, pulling the LayoutStrategy and OutputTarget construction out into the API allows the user to create and use custom layout and output systems.

Here is an example Session (extracted from the CommandLineStarter run() method):

        /*
         * Instantiate and configure the FOraySession. All parameters (Logger,
         * SessionConfig, FontServer, TextServer, and GraphicServer) are
         * optional. Each one that is passed as null in the constructor will
         * be created by the FOraySession. However, if an instance is
         * passed here, it needs to already be fully configured and ready to go.
         */
        Logger logger = this.logger;
        SessionConfig sessionConfig = this.options.getSessionConfig();
        FOrayFontServer fontServer = null;
        TextServer textServer = null;
        FOrayGraphicServer graphicServer = null;
        FOraySession session = new FOraySession(logger, sessionConfig,
                fontServer, textServer, graphicServer);

        /*
         * Instantiate and configure the FOrayDocument(s). The constructor
         * shown here is for regular SAX input.
         * There is also a constructor for a DOM document, and another for a
         * JAXP Transformer and Source.
         * Multiple documents can be instantiated, and they will be processed
         * in the order submitted.
         */
        InputSource saxInputSource = inputHandler.getInputSource();
        XMLReader parser = inputHandler.getParser();
        FOrayDocument document = new FOrayDocument(session, saxInputSource,
                parser);

        /*
         * Instantiate and configure the OutputTarget. The makeOutputTarget()
         * method of FOrayTarget knows how to make most of the standard
         * OutputTargets, but you can create and use a non-standard OutputTarget
         * as well.
         */
        int outputType = commandLineOptions.getOutputType();
        OutputConfig outputOptions = this.outputConfig;
        OutputTarget outputTarget = FOrayTarget.makeOutputTarget(outputType,
                outputOptions);

        /*
         * Instantiate and configure the FOrayTarget(s). Multiple targets can
         * be instantiated for each FOrayDocument, but right now only the first
         * one is actually processed.
         * LayoutStrategy is an optional parameter. Set it to null to have the
         * system use the default.
         * Targets that do not need an OutputStream should set that parameter
         * to null.
         */
        LayoutStrategy layout = new PioneerLS();
        FileOutputStream outputFileStream = getFileOutputStream();
        FOrayTarget target = new FOrayTarget(document, outputTarget, layout,
                outputFileStream);

        /*
         * Everything is now ready to go. There are two different processing
         * models possible here. The first is to let FOray manage and
         * complete the processing internally. The second is to manage that
         * process externally, e.g. those integrating with Cocoon or another
         * pipeline-type scheme. If you don't know which of those to use, you
         * should probably let FOray control the processing. The instructions
         * are separated below for the two models. IMPORTANT: Please note that
         * the instructions reunify below for some cleanup code that is common
         * to both.
         */


/* *****************************************************************************
 * Start instructions for internal FOray control. Ignore this section
 * if you are controlling externally.
 * ****************************************************************************/
        /*
         * Just push the button, and let FOray do the rest ...
         */
        session.process();
/* *****************************************************************************
 * End instructions for internal FOray control.
 * ****************************************************************************/


/* *****************************************************************************
 * Start instructions for external control. Ignore this section if
 * FOray is controlling the processing internally.
 * ****************************************************************************/
        /*
         * The task here is to mimic the internal FOray processing, but to do
         * it outside of FOray. The processing that needs to be duplicated can
         * be found at the FOrayDocument method processTarget(FOrayTarget
         * target). This is the method ultimately called from the FOraySession
         * method process(), documented above as the button to push for
         * internal FOray processing. The commented code below is the outline
         * of the steps that need to be taken:
         */
/*
        document.setTarget(target);
        // Get either a SAX ContentHandler ...
        ContentHandler contentHandler = document.getContentHandler();
        // ... or a JAXP SAXResult
        SAXResult jaxpResult = document.getJAXPResult();
        // Do something with contentHandler or JAXP SaxResult here.
        MyClass.myMethod(contentHandler);
        // Allow the document to do some cleanup.
        document.cleanup(target);
*/
/* *****************************************************************************
 * End instructions for external control.
 * ****************************************************************************/


/* *****************************************************************************
 * Start instructions for common cleanup code.
 * ****************************************************************************/
        /*
         * The process of closing the OutputStream is handled here instead of
         * internally within FOray so that those who wish to do something else
         * with it can.
         */
        target.cleanup();
*/
/* *****************************************************************************
 * End instructions for external control.
 * ****************************************************************************/


/* *****************************************************************************
 * Start instructions for common cleanup code.
 * ****************************************************************************/
        /*
         * The process of closing the OutputStream is handled here instead of
         * internally within FOray so that those who wish to do something else
         * with it can.
         */
        target.cleanup();

Embedded Configuration

Introduction

Every configuration option available from the command-line and configuration file is also accessible through FOray’s API. FOray configuration is managed in two classes:

  • org.foray.app.SessionConfig manages the Session configuration, which includes those options that are general in nature.
  • org.foray.output.OutputConfig manages the OutputTarget configuration, which includes those options that are specific to a Converter or Renderer.

FOray uses a precedence scheme to make sure that priorities are maintained as configuration options are received from various sources. As each option is parsed, an integer is passed that tells what precedence the item should receive. For the option to be set to the passed value, the precedence must be greater than or equal to the precedence of any pre-existing value for that option. The constants defining the various precedences are found in org.foray.common.Configuration, and are as follows: Defaults are 0, entries from a configuration file are 20, and command-line entries are 40. It is your program’s responsibility to set the precedence to an appropriate value. If you want your program value to override all others, set it the maximum integer value.

Configuring One Option

The general procedure for configuring one option from a Java program is as follows.

  1. Determine which configuration class you need to use. The Configuration Page documents the distinction between those options that are general and those that are specific to one output target.
  2. Get an instance of that class. These instances are supplied to the FOraySession and OutputTarget constructors respectively, so instantiate them as appropriate before instantiating those classes.
  3. Run the boolean parseOption(String key, String value, int precedenceValue) method. The key and value parameters are identical in nature to those supplied from the command-line or configuration file. Note that value must (as there) be supplied as a String, even though they may be used as a URL or boolean or something else. See above for discussion of the precedenceValue.
  4. Test the return value for true to make sure the item was successfully added.

This scheme is deliberately restrictive, providing intelligent validation and retrieval. If it is too restrictive for your purposes, you may want to extend these classes or write a custom implementation of org.foray.common.Configuration that exposes more of its (mostly protected) methods.

Parsing a Configuration File

The general procedure for configuring all options in a configuration file is as follows:

  1. Create an instance of org.foray.app.ConfigurationParser. The constructor needs an instance of both SessionConfig and OutputConfig, a SAX InputSource, and an Avalon logger.
  2. Run its parseDocument() method.

You can safely repeat this for multiple configuration files, if desired.