FOray
|
The FOray ApplicationIf 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. ContentsEmbedded StartupA 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:
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 ConfigurationIntroductionEvery configuration option available from the command-line and configuration file is also accessible through FOray’s API. FOray configuration is managed in two classes:
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 OptionThe general procedure for configuring one option from a Java program is as follows.
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 FileThe general procedure for configuring all options in a configuration file is as follows:
You can safely repeat this for multiple configuration files, if desired. |