aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKelly Campbell <kellyc@apache.org>2001-03-03 07:06:04 +0000
committerKelly Campbell <kellyc@apache.org>2001-03-03 07:06:04 +0000
commit506dc799d08fece47bd72f1d0ede606a80013c52 (patch)
tree381a245304b2a10722f585f51c072ed24d7d0a3f
parent9902c22a0e180d5a3cc8f683be8ebcbcd8a23c23 (diff)
downloadxmlgraphics-fop-506dc799d08fece47bd72f1d0ede606a80013c52.tar.gz
xmlgraphics-fop-506dc799d08fece47bd72f1d0ede606a80013c52.zip
Refactored Driver to simplify usage required for other apps
to integrate Fop. PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194114 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--docs/examples/embedding/FopServlet.java14
-rw-r--r--src/org/apache/fop/apps/AWTStarter.java10
-rw-r--r--src/org/apache/fop/apps/CommandLineOptions.java10
-rw-r--r--src/org/apache/fop/apps/CommandLineStarter.java13
-rw-r--r--src/org/apache/fop/apps/Driver.java571
-rw-r--r--src/org/apache/fop/apps/FOPException.java11
-rw-r--r--src/org/apache/fop/apps/PrintStarter.java4
-rw-r--r--src/org/apache/fop/tools/DocumentInputSource.java48
-rw-r--r--src/org/apache/fop/tools/DocumentReader.java520
-rw-r--r--src/org/apache/fop/tools/anttasks/Fop.java48
10 files changed, 934 insertions, 315 deletions
diff --git a/docs/examples/embedding/FopServlet.java b/docs/examples/embedding/FopServlet.java
index 56dbf9852..53a54ec27 100644
--- a/docs/examples/embedding/FopServlet.java
+++ b/docs/examples/embedding/FopServlet.java
@@ -114,17 +114,9 @@ public class FopServlet extends HttpServlet
response.setContentType("application/pdf");
- Driver driver = new Driver();
- driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer",
- Version.getVersion());
- driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
- driver.setOutputStream(out);
- driver.buildFOTree(createParser(), foFile);
- driver.format();
- driver.render();
+ Driver driver = new Driver(foFile, out);
+ driver.run();
+
byte[] content = out.toByteArray();
response.setContentLength(content.length);
response.getOutputStream().write(content);
diff --git a/src/org/apache/fop/apps/AWTStarter.java b/src/org/apache/fop/apps/AWTStarter.java
index 061c391ba..1aa7de739 100644
--- a/src/org/apache/fop/apps/AWTStarter.java
+++ b/src/org/apache/fop/apps/AWTStarter.java
@@ -90,7 +90,7 @@ public class AWTStarter extends CommandLineStarter {
public void run () {
- Driver driver = new Driver();
+ Driver driver = new Driver();
if (errorDump) {
driver.setErrorDump(true);
}
@@ -109,14 +109,6 @@ public class AWTStarter extends CommandLineStarter {
try {
driver.setRenderer(renderer);
- // init mappings: time
- frame.progress(resource.getString("Init mappings") + " ...");
-
- driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
-
// build FO tree: time
frame.progress(resource.getString("Build FO tree") + " ...");
driver.buildFOTree(parser, inputHandler.getInputSource());
diff --git a/src/org/apache/fop/apps/CommandLineOptions.java b/src/org/apache/fop/apps/CommandLineOptions.java
index 939fc2c64..ccac4966d 100644
--- a/src/org/apache/fop/apps/CommandLineOptions.java
+++ b/src/org/apache/fop/apps/CommandLineOptions.java
@@ -260,18 +260,18 @@ public class CommandLineOptions {
/**
* returns the chosen renderer, throws FOPException
*/
- public String getRenderer () throws FOPException {
+ public int getRenderer () throws FOPException {
switch (outputmode) {
case NOT_SET:
throw new FOPException("Renderer has not been set!");
case PDF_OUTPUT:
- return "org.apache.fop.render.pdf.PDFRenderer";
+ return Driver.RENDER_PDF;
case AWT_OUTPUT:
- return "org.apache.fop.render.awt.AWTRenderer";
+ return Driver.RENDER_AWT;
case MIF_OUTPUT:
- return "org.apache.fop.render.mif.MIFRenderer";
+ return Driver.RENDER_MIF;
case PRINT_OUTPUT:
- return "org.apache.fop.render.awt.PrintRenderer";
+ return Driver.RENDER_PRINT;
default:
throw new FOPException("Invalid Renderer setting!");
}
diff --git a/src/org/apache/fop/apps/CommandLineStarter.java b/src/org/apache/fop/apps/CommandLineStarter.java
index fe8cddec6..7d6aae9fc 100644
--- a/src/org/apache/fop/apps/CommandLineStarter.java
+++ b/src/org/apache/fop/apps/CommandLineStarter.java
@@ -38,20 +38,15 @@ public class CommandLineStarter extends Starter {
XMLReader parser = inputHandler.getParser();
setParserFeatures(parser,errorDump);
- Driver driver = new Driver();
+ Driver driver = new Driver();
if (errorDump) {
driver.setErrorDump(true);
}
try {
- driver.setRenderer(commandLineOptions.getRenderer(), "");
- driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- driver.addElementMapping("org.apache.fop.extensions.ExtensionElementMapping");
- driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
- driver.addPropertyList("org.apache.fop.extensions.ExtensionPropertyListMapping");
- driver.buildFOTree(parser,inputHandler.getInputSource());
+ driver.setRenderer(commandLineOptions.getRenderer());
+
+ driver.buildFOTree(parser, inputHandler.getInputSource());
driver.format();
driver.setOutputStream(new FileOutputStream(commandLineOptions.getOutputFile()));
driver.render();
diff --git a/src/org/apache/fop/apps/Driver.java b/src/org/apache/fop/apps/Driver.java
index 0490b62df..9bb0099c4 100644
--- a/src/org/apache/fop/apps/Driver.java
+++ b/src/org/apache/fop/apps/Driver.java
@@ -17,6 +17,8 @@ import org.apache.fop.render.Renderer;
import org.apache.fop.messaging.MessageHandler;
import org.apache.fop.configuration.ConfigurationReader;
import org.apache.fop.configuration.Configuration;
+import org.apache.fop.tools.DocumentInputSource;
+import org.apache.fop.tools.DocumentReader;
// DOM
@@ -37,370 +39,443 @@ import java.io.*;
/**
- * <P>Primary class that drives overall FOP process.
+ * Primary class that drives overall FOP process.
+ * <P>
+ * The simplest way to use this is to instantiate it with the
+ * InputSource and OutputStream, then set the renderer desired, and
+ * calling run();
+ * <P>
+ * Here is an example use of Driver which outputs PDF:
*
- * <P>Once this class is instantiated, methods are called to set the
+ * <PRE>
+ * Driver driver = new Driver(new InputSource (args[0]),
+ * new FileOutputStream(args[1]));
+ * driver.setRenderer(RENDER_PDF);
+ * driver.run();
+ * </PRE>
+
+ * If neccessary, calling classes can call into the lower level
+ * methods to setup and
+ * render. Methods can be called to set the
* Renderer to use, the (possibly multiple) ElementMapping(s) to
- * use and the PrintWriter to use to output the results of the
+ * use and the OutputStream to use to output the results of the
* rendering (where applicable). In the case of the Renderer and
* ElementMapping(s), the Driver may be supplied either with the
* object itself, or the name of the class, in which case Driver will
* instantiate the class itself. The advantage of the latter is it
* enables runtime determination of Renderer and ElementMapping(s).
- *
- * <P>Once the Driver is set up, the buildFOTree method
+ * <P>
+ * Once the Driver is set up, the buildFOTree method
* is called. Depending on whether DOM or SAX is being used, the
* invocation of the method is either buildFOTree(Document) or
* buildFOTree(Parser, InputSource) respectively.
- *
- * <P>A third possibility may be used to build the FO Tree, namely
+ * <P>
+ * A third possibility may be used to build the FO Tree, namely
* calling getContentHandler() and firing the SAX events yourself.
- *
- * <P>Once the FO Tree is built, the format() and render() methods may be
+ * <P>
+ * Once the FO Tree is built, the format() and render() methods may be
* called in that order.
- *
- * <P>Here is an example use of Driver from CommandLine.java:
+ * <P>
+ * Here is an example use of Driver which outputs to AWT:
*
* <PRE>
* Driver driver = new Driver();
- * driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer", version);
- * driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- * driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- * driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- * driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
- * driver.setOutputStream(new FileOutputStream(args[1]));
+ * driver.setRenderer(new org.apache.fop.render.awt.AWTRenderer(translator));
* driver.buildFOTree(parser, fileInputSource(args[0]));
* driver.format();
* driver.render();
* </PRE>
*/
public class Driver {
+
+ /** Render to PDF. OutputStream must be set */
+ public static final int RENDER_PDF = 1;
+
+ /** Render to a GUI window. No OutputStream neccessary */
+ public static final int RENDER_AWT = 2;
+
+ /** Render to MIF. OutputStream must be set */
+ public static final int RENDER_MIF = 3;
+
+ /** Render to XML. OutputStream must be set */
+ public static final int RENDER_XML = 4;
+
+ /** Render to PRINT. No OutputStream neccessary */
+ public static final int RENDER_PRINT = 5;
/** the FO tree builder */
- protected FOTreeBuilder treeBuilder;
+ private FOTreeBuilder _treeBuilder;
/** the area tree that is the result of formatting the FO tree */
- protected AreaTree areaTree;
+ private AreaTree _areaTree;
/** the renderer to use to output the area tree */
- protected Renderer renderer;
+ private Renderer _renderer;
+ /** the source of the FO file */
+ private InputSource _source;
+
/** the stream to use to output the results of the renderer */
- protected OutputStream stream;
+ private OutputStream _stream;
+ /** The XML parser to use when building the FO tree */
+ private XMLReader _reader;
+
/** If true, full error stacks are reported */
- protected boolean errorDump = false;
+ private boolean _errorDump = false;
/** create a new Driver */
public Driver() {
- this.treeBuilder = new FOTreeBuilder();
+ reset();
+ }
+
+ public Driver(InputSource source, OutputStream stream) {
+ this();
+ _source = source;
+ _stream = stream;
}
- /** Set the error dump option
- * @param dump if true, full stacks will be reported to the error log
- */
+ /**
+ * Resets the Driver so it can be reused. Property and element mappings are reset to defaults.
+ * The output stream is cleared. The renderer is cleared.
+ */
+ public synchronized void reset()
+ {
+ _stream = null;
+ _treeBuilder = new FOTreeBuilder();
+ setupDefaultMappings();
+ }
+
+ /**
+ * Set the error dump option
+ * @param dump if true, full stacks will be reported to the error log
+ */
public void setErrorDump(boolean dump) {
- errorDump = dump;
+ _errorDump = dump;
}
- /** set the Renderer to use */
- public void setRenderer(Renderer renderer) {
- this.renderer = renderer;
+ /**
+ * Set the OutputStream to use to output the result of the Renderer
+ * (if applicable)
+ * @param stream the stream to output the result of rendering to
+ *
+ */
+ public void setOutputStream(OutputStream stream) {
+ _stream = stream;
}
/**
- * set the class name of the Renderer to use as well as the
- * producer string for those renderers that can make use of it
- */
- public void setRenderer(String rendererClassName, String producer) {
- this.renderer = createRenderer(rendererClassName);
- this.renderer.setProducer(producer);
+ * Set the source for the FO document. This can be a normal SAX
+ * InputSource, or an DocumentInputSource containing a DOM document.
+ * @see DocumentInputSource
+ */
+ public void setInputSource(InputSource source)
+ {
+ _source = source;
}
+
+ /**
+ * Sets the reader used when reading in the source. If not set,
+ * this defaults to a basic SAX parser.
+ */
+ public void setXMLReader(XMLReader reader)
+ {
+ _reader = reader;
+ }
+
/**
- * protected method used by setRenderer(String, String) to
- * instantiate the Renderer class
- */
- protected Renderer createRenderer(String rendererClassName) {
- MessageHandler.logln("using renderer " + rendererClassName);
+ * Sets all the element and property list mappings to their default values.
+ *
+ */
+ public void setupDefaultMappings()
+ {
+ addElementMapping("org.apache.fop.fo.StandardElementMapping");
+ addPropertyList ("org.apache.fop.fo.StandardPropertyListMapping");
+
+ addElementMapping("org.apache.fop.svg.SVGElementMapping");
+ addPropertyList ("org.apache.fop.svg.SVGPropertyListMapping");
+
+ addElementMapping("org.apache.fop.extensions.ExtensionElementMapping");
+ addPropertyList ("org.apache.fop.extensions.ExtensionPropertyListMapping");
+ }
- try {
- return (Renderer) Class.forName(
- rendererClassName).newInstance();
- } catch (ClassNotFoundException e) {
- MessageHandler.errorln("Could not find " + rendererClassName);
+ /**
+ * Set the rendering type to use. Must be one of
+ * <ul>
+ * <li>RENDER_PDF
+ * <li>RENDER_AWT
+ * <li>RENDER_MIF
+ * <li>RENDER_XML
+ * </ul>
+ * @param renderer the type of renderer to use
+ */
+ public void setRenderer(int renderer)
+ throws IllegalArgumentException
+ {
+ switch (renderer) {
+ case RENDER_PDF:
+ setRenderer(new org.apache.fop.render.pdf.PDFRenderer());
+ break;
+ case RENDER_AWT:
+ throw new IllegalArgumentException("Use renderer form of setRenderer() for AWT");
+ case RENDER_PRINT:
+ throw new IllegalArgumentException("Use renderer form of setRenderer() for PRINT");
+ case RENDER_MIF:
+ setRenderer(new org.apache.fop.render.mif.MIFRenderer());
+ break;
+ case RENDER_XML:
+ setRenderer(new org.apache.fop.render.xml.XMLRenderer());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown renderer type");
+ }
+
+ }
+
+
+ /**
+ * Set the Renderer to use
+ * @param renderer the renderer instance to use
+ */
+ public void setRenderer(Renderer renderer) {
+ _renderer = renderer;
+ }
+
+ /**
+ * @deprecated use renderer.setProducer(version) + setRenderer(renderer) or just setRenderer(renderer_type) which will use the default producer string.
+ * @see #setRenderer(int)
+ * @see #setRenderer(Renderer)
+ */
+ public void setRenderer(String rendererClassName, String version)
+ {
+ setRenderer(rendererClassName);
+ }
+
+ /**
+ * Set the class name of the Renderer to use as well as the
+ * producer string for those renderers that can make use of it.
+ * @param rendererClassName classname of the renderer to use such as
+ * "org.apache.fop.render.pdf.PDFRenderer"
+ * @exception IllegalArgumentException if the classname was invalid.
+ * @see #setRenderer(int)
+ */
+ public void setRenderer(String rendererClassName)
+ throws IllegalArgumentException
+ {
+ try {
+ _renderer = (Renderer) Class.forName(rendererClassName).newInstance();
+ _renderer.setProducer(Version.getVersion());
+ }
+ catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("Could not find " +
+ rendererClassName);
}
catch (InstantiationException e) {
- MessageHandler.errorln("Could not instantiate " +
+ throw new IllegalArgumentException("Could not instantiate " +
rendererClassName);
}
catch (IllegalAccessException e) {
- MessageHandler.errorln("Could not access " + rendererClassName);
+ throw new IllegalArgumentException("Could not access " + rendererClassName);
}
catch (ClassCastException e) {
- MessageHandler.errorln(rendererClassName + " is not a renderer");
+ throw new IllegalArgumentException(rendererClassName + " is not a renderer");
}
- return null;
}
/**
- * add the given element mapping.
- *
- * an element mapping maps element names to Java classes
- */
+ * Add the given element mapping.
+ * An element mapping maps element names to Java classes.
+ *
+ * @param mapping the element mappingto add
+ */
public void addElementMapping(ElementMapping mapping) {
- mapping.addToBuilder(this.treeBuilder);
+ mapping.addToBuilder(_treeBuilder);
}
/**
- * add the element mapping with the given class name
- */
- public void addElementMapping(String mappingClassName) {
- createElementMapping(mappingClassName).addToBuilder(
- this.treeBuilder);
- }
-
- /**
- * protected method used by addElementMapping(String) to
- * instantiate element mapping class
- */
- protected ElementMapping createElementMapping(
- String mappingClassName) {
- MessageHandler.logln("using element mapping " + mappingClassName);
-
- try {
- return (ElementMapping) Class.forName(
+ * add the element mapping with the given class name
+ */
+ public void addElementMapping(String mappingClassName)
+ throws IllegalArgumentException
+ {
+ try {
+ ElementMapping mapping = (ElementMapping) Class.forName(
mappingClassName).newInstance();
- } catch (ClassNotFoundException e) {
- MessageHandler.errorln("Could not find " + mappingClassName);
- dumpError(e);
- }
+ addElementMapping(mapping);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("Could not find " + mappingClassName);
+ }
catch (InstantiationException e) {
- MessageHandler.errorln("Could not instantiate " +
+ throw new IllegalArgumentException("Could not instantiate " +
mappingClassName);
- dumpError(e);
- }
+ }
catch (IllegalAccessException e) {
- MessageHandler.errorln("Could not access " + mappingClassName);
- dumpError(e);
- }
+ throw new IllegalArgumentException("Could not access " + mappingClassName);
+ }
catch (ClassCastException e) {
- MessageHandler.errorln(mappingClassName + " is not an element mapping");
- dumpError(e);
- }
- return null;
+ throw new IllegalArgumentException(mappingClassName + " is not an ElementMapping");
+ }
}
/**
- * add the element mapping with the given class name
- */
- public void addPropertyList(String listClassName) {
- createPropertyList(listClassName).addToBuilder(this.treeBuilder);
+ * Add the PropertyListMapping.
+ */
+ public void addPropertyList(PropertyListMapping mapping)
+ {
+ mapping.addToBuilder(_treeBuilder);
}
+
/**
- * protected method used by addPropertyList(String) to
- * instantiate list mapping class
- */
- protected PropertyListMapping createPropertyList(
- String listClassName) {
- MessageHandler.logln("using property list mapping " +
- listClassName);
-
- try {
- return (PropertyListMapping) Class.forName(
+ * Add the PropertyListMapping with the given class name.
+ */
+ public void addPropertyList(String listClassName)
+ throws IllegalArgumentException
+ {
+ try {
+ PropertyListMapping mapping = (PropertyListMapping) Class.forName(
listClassName).newInstance();
- } catch (ClassNotFoundException e) {
- MessageHandler.errorln("Could not find " + listClassName);
- dumpError(e);
- }
+ addPropertyList(mapping);
+
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("Could not find " + listClassName);
+ }
catch (InstantiationException e) {
- MessageHandler.errorln("Could not instantiate " +
- listClassName);
- dumpError(e);
- }
+ throw new IllegalArgumentException("Could not instantiate " +
+ listClassName);
+ }
catch (IllegalAccessException e) {
- MessageHandler.errorln("Could not access " + listClassName);
- dumpError(e);
- }
+ throw new IllegalArgumentException("Could not access " + listClassName);
+ }
catch (ClassCastException e) {
- MessageHandler.errorln(listClassName + " is not an property list");
- dumpError(e);
- }
- return null;
+ throw new IllegalArgumentException(listClassName + " is not an ElementMapping");
+ }
}
/**
- * return the tree builder (a SAX ContentHandler).
- *
- * used in situations where SAX is used but not via a FOP-invoked
- * SAX parser. A good example is an XSLT engine that fires SAX
- * events but isn't a SAX Parser itself.
- */
+ * Returns the tree builder (a SAX ContentHandler).
+ *
+ * Used in situations where SAX is used but not via a FOP-invoked
+ * SAX parser. A good example is an XSLT engine that fires SAX
+ * events but isn't a SAX Parser itself.
+ */
public ContentHandler getContentHandler() {
- return this.treeBuilder;
+ return _treeBuilder;
}
/**
- * build the formatting object tree using the given SAX Parser and
- * SAX InputSource
- */
- public void buildFOTree(XMLReader parser,
- InputSource source) throws FOPException {
-
- parser.setContentHandler(this.treeBuilder);
+ * Build the formatting object tree using the given SAX Parser and
+ * SAX InputSource
+ */
+ public synchronized void buildFOTree(XMLReader parser,
+ InputSource source)
+ throws FOPException
+ {
+
+ parser.setContentHandler(_treeBuilder);
try {
parser.parse(source);
} catch (SAXException e) {
if (e.getException() instanceof FOPException) {
- dumpError(e.getException());
throw (FOPException) e.getException();
} else {
- dumpError(e);
- throw new FOPException(e.getMessage());
+ throw new FOPException(e);
}
}
catch (IOException e) {
- dumpError(e);
- throw new FOPException(e.getMessage());
+ throw new FOPException(e);
}
}
/**
- * build the formatting object tree using the given DOM Document
- */
- public void buildFOTree(Document document) throws FOPException {
-
- /* most of this code is modified from John Cowan's */
-
- Node currentNode;
- AttributesImpl currentAtts;
-
- /* temporary array for making Strings into character arrays */
- char[] array = null;
-
- currentAtts = new AttributesImpl();
-
- /* start at the document element */
- currentNode = document;
-
- try {
- while (currentNode != null) {
- switch (currentNode.getNodeType()) {
- case Node.DOCUMENT_NODE:
- this.treeBuilder.startDocument();
- break;
- case Node.CDATA_SECTION_NODE:
- case Node.TEXT_NODE:
- String data = currentNode.getNodeValue();
- int datalen = data.length();
- if (array == null || array.length < datalen) {
- /* if the array isn't big enough, make a new
- one */
- array = new char[datalen];
- }
- data.getChars(0, datalen, array, 0);
- this.treeBuilder.characters(array, 0, datalen);
- break;
- case Node.PROCESSING_INSTRUCTION_NODE:
- this.treeBuilder.processingInstruction(
- currentNode.getNodeName(),
- currentNode.getNodeValue());
- break;
- case Node.ELEMENT_NODE:
- NamedNodeMap map = currentNode.getAttributes();
- currentAtts.clear();
- for (int i = map.getLength() - 1; i >= 0; i--) {
- Attr att = (Attr) map.item(i);
- currentAtts.addAttribute( att.getNamespaceURI(),
- att.getLocalName(), att.getName(),
- "CDATA", att.getValue());
- }
- this.treeBuilder.startElement(
- currentNode.getNamespaceURI(),
- currentNode.getLocalName(),
- currentNode.getNodeName(), currentAtts);
- break;
- }
-
- Node nextNode = currentNode.getFirstChild();
- if (nextNode != null) {
- currentNode = nextNode;
- continue;
- }
-
- while (currentNode != null) {
- switch (currentNode.getNodeType()) {
- case Node.DOCUMENT_NODE:
- this.treeBuilder.endDocument();
- break;
- case Node.ELEMENT_NODE:
- this.treeBuilder.endElement(
- currentNode.getNamespaceURI(),
- currentNode.getLocalName(),
- currentNode.getNodeName());
- break;
- }
-
- nextNode = currentNode.getNextSibling();
- if (nextNode != null) {
- currentNode = nextNode;
- break;
- }
-
- currentNode = currentNode.getParentNode();
- }
- }
- } catch (SAXException e) {
- dumpError(e);
- throw new FOPException(e.getMessage());
- }
- }
+ * Build the formatting object tree using the given DOM Document
+ */
+ public synchronized void buildFOTree(Document document)
+ throws FOPException
+ {
+ try {
+ DocumentInputSource source = new DocumentInputSource(document);
+ DocumentReader reader = new DocumentReader();
+ reader.setContentHandler(_treeBuilder);
+ reader.parse(source);
+ } catch (SAXException e) {
+ throw new FOPException(e);
+ } catch (IOException e) {
+ throw new FOPException(e);
+ }
+
+ }
/**
- * Dumps an error
- */
+ * Dumps an error
+ */
public void dumpError(Exception e) {
- if (errorDump) {
+ if (_errorDump) {
if (e instanceof SAXException) {
e.printStackTrace();
if (((SAXException) e).getException() != null) {
((SAXException) e).getException().printStackTrace();
}
- } else {
+ }
+ else if (e instanceof FOPException) {
+ e.printStackTrace();
+ if (((FOPException) e).getException() != null) {
+ ((FOPException) e).getException().printStackTrace();
+ }
+ }
+ else {
e.printStackTrace();
}
}
-
}
/**
- * set the OutputStream to use to output the result of the Renderer
- * (if applicable)
- */
- public void setOutputStream(OutputStream stream) {
- this.stream = stream;
- }
-
- /**
- * format the formatting object tree into an area tree
- */
- public void format() throws FOPException {
+ * format the formatting object tree into an area tree
+ */
+ public synchronized void format() throws FOPException {
FontInfo fontInfo = new FontInfo();
- this.renderer.setupFontInfo(fontInfo);
+ _renderer.setupFontInfo(fontInfo);
- this.areaTree = new AreaTree();
- this.areaTree.setFontInfo(fontInfo);
+ _areaTree = new AreaTree();
+ _areaTree.setFontInfo(fontInfo);
- this.treeBuilder.format(areaTree);
+ _treeBuilder.format(_areaTree);
}
/**
- * render the area tree to the output form
- */
- public void render() throws IOException, FOPException {
- this.renderer.render(areaTree, this.stream);
+ * render the area tree to the output form
+ */
+ public synchronized void render() throws IOException, FOPException {
+ _renderer.render(_areaTree, _stream);
}
-
+ /**
+ * Runs the formatting and renderering process using the previously set
+ * inputsource and outputstream
+ */
+ public synchronized void run()
+ throws IOException, FOPException
+ {
+ if (_renderer == null) {
+ setRenderer(RENDER_PDF);
+ }
+ if (_source == null) {
+ throw new FOPException("InputSource is not set.");
+ }
+ if (_reader == null) {
+ if (!(_source instanceof DocumentInputSource)) {
+ _reader = ConfigurationReader.createParser();
+ }
+ }
+ if (_source instanceof DocumentInputSource) {
+ buildFOTree(((DocumentInputSource)_source).getDocument());
+ }
+ else {
+ buildFOTree(_reader, _source);
+ }
+ format();
+ render();
+ }
+
}
diff --git a/src/org/apache/fop/apps/FOPException.java b/src/org/apache/fop/apps/FOPException.java
index d28d36052..94ca52bdf 100644
--- a/src/org/apache/fop/apps/FOPException.java
+++ b/src/org/apache/fop/apps/FOPException.java
@@ -11,6 +11,8 @@ package org.apache.fop.apps;
*/
public class FOPException extends Exception {
+ private Throwable _exception;
+
/**
* create a new FOP Exception
*
@@ -19,4 +21,13 @@ public class FOPException extends Exception {
public FOPException(String message) {
super(message);
}
+ public FOPException(Throwable e) {
+ super(e.getMessage());
+ _exception = e;
+ }
+
+ public Throwable getException()
+ {
+ return _exception;
+ }
}
diff --git a/src/org/apache/fop/apps/PrintStarter.java b/src/org/apache/fop/apps/PrintStarter.java
index e246335cc..91c24f9ba 100644
--- a/src/org/apache/fop/apps/PrintStarter.java
+++ b/src/org/apache/fop/apps/PrintStarter.java
@@ -65,10 +65,6 @@ public class PrintStarter extends CommandLineStarter {
try {
driver.setRenderer(renderer);
- driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
driver.buildFOTree(parser, inputHandler.getInputSource());
driver.format();
driver.render();
diff --git a/src/org/apache/fop/tools/DocumentInputSource.java b/src/org/apache/fop/tools/DocumentInputSource.java
new file mode 100644
index 000000000..1228ce05a
--- /dev/null
+++ b/src/org/apache/fop/tools/DocumentInputSource.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources."
+ */
+
+
+package org.apache.fop.tools;
+
+import java.util.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+/**
+ * This is an InputSource to be used with DocumentReader.
+ *
+ * @author Kelly A Campbell
+ *
+ */
+
+public class DocumentInputSource extends InputSource
+{
+ private Document _document;
+
+ public DocumentInputSource()
+ {
+ super();
+ }
+
+ public DocumentInputSource(Document document)
+ {
+ this();
+ _document = document;
+ }
+
+ public Document getDocument()
+ {
+ return _document;
+ }
+
+ public void setDocument(Document document)
+ {
+ _document = document;
+ }
+
+}
+
+
diff --git a/src/org/apache/fop/tools/DocumentReader.java b/src/org/apache/fop/tools/DocumentReader.java
new file mode 100644
index 000000000..2abdd537c
--- /dev/null
+++ b/src/org/apache/fop/tools/DocumentReader.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources."
+ */
+
+
+package org.apache.fop.tools;
+
+import java.io.IOException;
+//import java.util.*;
+
+// DOM
+import org.w3c.dom.*;
+
+// SAX
+import org.xml.sax.*;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This presents a DOM as an XMLReader to make it easy to use a Document
+ * with a SAX-based implementation.
+ *
+ * @author Kelly A Campbell
+ *
+ */
+
+public class DocumentReader implements XMLReader
+{
+
+ ////////////////////////////////////////////////////////////////////
+ // Configuration.
+ ////////////////////////////////////////////////////////////////////
+ private boolean _namespaces = true;
+ private boolean _namespace_prefixes = true;
+
+
+ /**
+ * Look up the value of a feature.
+ *
+ * <p>The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a feature name but
+ * to be unable to return its value; this is especially true
+ * in the case of an adapter for a SAX1 Parser, which has
+ * no way of knowing whether the underlying parser is
+ * performing validation or expanding external entities.</p>
+ *
+ * <p>All XMLReaders are required to recognize the
+ * http://xml.org/sax/features/namespaces and the
+ * http://xml.org/sax/features/namespace-prefixes feature names.</p>
+ *
+ * <p>Some feature values may be available only in specific
+ * contexts, such as before, during, or after a parse.</p>
+ *
+ * <p>Typical usage is something like this:</p>
+ *
+ * <pre>
+ * XMLReader r = new MySAXDriver();
+ *
+ * // try to activate validation
+ * try {
+ * r.setFeature("http://xml.org/sax/features/validation", true);
+ * } catch (SAXException e) {
+ * System.err.println("Cannot activate validation.");
+ * }
+ *
+ * // register event handlers
+ * r.setContentHandler(new MyContentHandler());
+ * r.setErrorHandler(new MyErrorHandler());
+ *
+ * // parse the first document
+ * try {
+ * r.parse("http://www.foo.com/mydoc.xml");
+ * } catch (IOException e) {
+ * System.err.println("I/O exception reading XML document");
+ * } catch (SAXException e) {
+ * System.err.println("XML exception reading document.");
+ * }
+ * </pre>
+ *
+ * <p>Implementors are free (and encouraged) to invent their own features,
+ * using names built on their own URIs.</p>
+ *
+ * @param name The feature name, which is a fully-qualified URI.
+ * @return The current state of the feature (true or false).
+ * @exception org.xml.sax.SAXNotRecognizedException When the
+ * XMLReader does not recognize the feature name.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the feature name but
+ * cannot determine its value at this time.
+ * @see #setFeature
+ */
+ public boolean getFeature (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if ("http://xml.org/sax/features/namespaces".equals(name)) {
+ return _namespaces;
+ }
+ else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
+ return _namespace_prefixes;
+ }
+ else {
+ throw new SAXNotRecognizedException("Feature '"+name+"' not recognized or supported by Document2SAXAdapter");
+ }
+
+ }
+
+
+
+ /**
+ * Set the state of a feature.
+ *
+ * <p>The feature name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a feature name but
+ * to be unable to set its value; this is especially true
+ * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser Parser},
+ * which has no way of affecting whether the underlying parser is
+ * validating, for example.</p>
+ *
+ * <p>All XMLReaders are required to support setting
+ * http://xml.org/sax/features/namespaces to true and
+ * http://xml.org/sax/features/namespace-prefixes to false.</p>
+ *
+ * <p>Some feature values may be immutable or mutable only
+ * in specific contexts, such as before, during, or after
+ * a parse.</p>
+ *
+ * @param name The feature name, which is a fully-qualified URI.
+ * @param state The requested state of the feature (true or false).
+ * @exception org.xml.sax.SAXNotRecognizedException When the
+ * XMLReader does not recognize the feature name.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the feature name but
+ * cannot set the requested value.
+ * @see #getFeature
+ */
+ public void setFeature (String name, boolean value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ if ("http://xml.org/sax/features/namespaces".equals(name)) {
+ _namespaces = value;
+ }
+ else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
+ _namespace_prefixes = value;
+ }
+ else {
+ throw new SAXNotRecognizedException("Feature '"+name+"' not recognized or supported by Document2SAXAdapter");
+ }
+
+ }
+
+
+
+ /**
+ * Look up the value of a property.
+ *
+ * <p>The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * to be unable to return its state; this is especially true
+ * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
+ * Parser}.</p>
+ *
+ * <p>XMLReaders are not required to recognize any specific
+ * property names, though an initial core set is documented for
+ * SAX2.</p>
+ *
+ * <p>Some property values may be available only in specific
+ * contexts, such as before, during, or after a parse.</p>
+ *
+ * <p>Implementors are free (and encouraged) to invent their own properties,
+ * using names built on their own URIs.</p>
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @return The current value of the property.
+ * @exception org.xml.sax.SAXNotRecognizedException When the
+ * XMLReader does not recognize the property name.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the property name but
+ * cannot determine its value at this time.
+ * @see #setProperty
+ */
+ public Object getProperty (String name)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ throw new SAXNotRecognizedException("Property '"+name+"' not recognized or supported by Document2SAXAdapter");
+ }
+
+
+
+ /**
+ * Set the value of a property.
+ *
+ * <p>The property name is any fully-qualified URI. It is
+ * possible for an XMLReader to recognize a property name but
+ * to be unable to set its value; this is especially true
+ * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
+ * Parser}.</p>
+ *
+ * <p>XMLReaders are not required to recognize setting
+ * any specific property names, though a core set is provided with
+ * SAX2.</p>
+ *
+ * <p>Some property values may be immutable or mutable only
+ * in specific contexts, such as before, during, or after
+ * a parse.</p>
+ *
+ * <p>This method is also the standard mechanism for setting
+ * extended handlers.</p>
+ *
+ * @param name The property name, which is a fully-qualified URI.
+ * @param state The requested value for the property.
+ * @exception org.xml.sax.SAXNotRecognizedException When the
+ * XMLReader does not recognize the property name.
+ * @exception org.xml.sax.SAXNotSupportedException When the
+ * XMLReader recognizes the property name but
+ * cannot set the requested value.
+ */
+ public void setProperty (String name, Object value)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ throw new SAXNotRecognizedException("Property '"+name+"' not recognized or supported by Document2SAXAdapter");
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Event handlers.
+ ////////////////////////////////////////////////////////////////////
+ private EntityResolver _entityResolver = null;
+ private DTDHandler _dtdHandler = null;
+ private ContentHandler _contentHandler = null;
+ private ErrorHandler _errorHandler = null;
+
+
+ /**
+ * Allow an application to register an entity resolver.
+ *
+ * <p>If the application does not register an entity resolver,
+ * the XMLReader will perform its own default resolution.</p>
+ *
+ * <p>Applications may register a new or different resolver in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * resolver immediately.</p>
+ *
+ * @param resolver The entity resolver.
+ * @exception java.lang.NullPointerException If the resolver
+ * argument is null.
+ * @see #getEntityResolver
+ */
+ public void setEntityResolver (EntityResolver resolver)
+ {
+ _entityResolver = resolver;
+ }
+
+
+
+ /**
+ * Return the current entity resolver.
+ *
+ * @return The current entity resolver, or null if none
+ * has been registered.
+ * @see #setEntityResolver
+ */
+ public EntityResolver getEntityResolver ()
+ {
+ return _entityResolver;
+ }
+
+
+
+ /**
+ * Allow an application to register a DTD event handler.
+ *
+ * <p>If the application does not register a DTD handler, all DTD
+ * events reported by the SAX parser will be silently ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The DTD handler.
+ * @exception java.lang.NullPointerException If the handler
+ * argument is null.
+ * @see #getDTDHandler
+ */
+ public void setDTDHandler (DTDHandler handler)
+ {
+ _dtdHandler = handler;
+ }
+
+
+
+ /**
+ * Return the current DTD handler.
+ *
+ * @return The current DTD handler, or null if none
+ * has been registered.
+ * @see #setDTDHandler
+ */
+ public DTDHandler getDTDHandler ()
+ {
+ return _dtdHandler;
+ }
+
+
+
+ /**
+ * Allow an application to register a content event handler.
+ *
+ * <p>If the application does not register a content handler, all
+ * content events reported by the SAX parser will be silently
+ * ignored.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The content handler.
+ * @exception java.lang.NullPointerException If the handler
+ * argument is null.
+ * @see #getContentHandler
+ */
+ public void setContentHandler (ContentHandler handler)
+ {
+ _contentHandler = handler;
+ }
+
+
+
+ /**
+ * Return the current content handler.
+ *
+ * @return The current content handler, or null if none
+ * has been registered.
+ * @see #setContentHandler
+ */
+ public ContentHandler getContentHandler ()
+ {
+ return _contentHandler;
+ }
+
+
+
+ /**
+ * Allow an application to register an error event handler.
+ *
+ * <p>If the application does not register an error handler, all
+ * error events reported by the SAX parser will be silently
+ * ignored; however, normal processing may not continue. It is
+ * highly recommended that all SAX applications implement an
+ * error handler to avoid unexpected bugs.</p>
+ *
+ * <p>Applications may register a new or different handler in the
+ * middle of a parse, and the SAX parser must begin using the new
+ * handler immediately.</p>
+ *
+ * @param handler The error handler.
+ * @exception java.lang.NullPointerException If the handler
+ * argument is null.
+ * @see #getErrorHandler
+ */
+ public void setErrorHandler (ErrorHandler handler)
+ {
+ _errorHandler = handler;
+ }
+
+ /**
+ * Return the current error handler.
+ *
+ * @return The current error handler, or null if none
+ * has been registered.
+ * @see #setErrorHandler
+ */
+ public ErrorHandler getErrorHandler ()
+ {
+ return _errorHandler;
+ }
+
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Parsing.
+ ////////////////////////////////////////////////////////////////////
+
+ /**
+ * Parse an XML DOM document.
+ *
+ *
+ *
+ * @param source The input source for the top-level of the
+ * XML document.
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see org.xml.sax.InputSource
+ * @see #parse(java.lang.String)
+ * @see #setEntityResolver
+ * @see #setDTDHandler
+ * @see #setContentHandler
+ * @see #setErrorHandler
+ */
+ public void parse (InputSource input)
+ throws IOException, SAXException
+ {
+ if (input instanceof DocumentInputSource) {
+ Document document = ((DocumentInputSource)input).getDocument();
+ if (_contentHandler == null) {
+ throw new SAXException("ContentHandler is null. Please use setContentHandler()");
+ }
+
+ // refactored from org.apache.fop.apps.Driver
+ /* most of this code is modified from John Cowan's */
+
+ Node currentNode;
+ AttributesImpl currentAtts;
+
+ /* temporary array for making Strings into character arrays */
+ char[] array = null;
+
+ currentAtts = new AttributesImpl();
+
+ /* start at the document element */
+ currentNode = document;
+ while (currentNode != null) {
+ switch (currentNode.getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ _contentHandler.startDocument();
+ break;
+ case Node.CDATA_SECTION_NODE:
+ case Node.TEXT_NODE:
+ String data = currentNode.getNodeValue();
+ int datalen = data.length();
+ if (array == null || array.length < datalen) {
+ /* if the array isn't big enough, make a new
+ one */
+ array = new char[datalen];
+ }
+ data.getChars(0, datalen, array, 0);
+ _contentHandler.characters(array, 0, datalen);
+ break;
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ _contentHandler.processingInstruction(currentNode.getNodeName(),
+ currentNode.getNodeValue());
+ break;
+ case Node.ELEMENT_NODE:
+ NamedNodeMap map = currentNode.getAttributes();
+ currentAtts.clear();
+ for (int i = map.getLength() - 1; i >= 0; i--) {
+ Attr att = (Attr) map.item(i);
+ currentAtts.addAttribute( att.getNamespaceURI(),
+ att.getLocalName(), att.getName(),
+ "CDATA", att.getValue());
+ }
+ _contentHandler.startElement(currentNode.getNamespaceURI(),
+ currentNode.getLocalName(),
+ currentNode.getNodeName(),
+ currentAtts);
+ break;
+ }
+
+ Node nextNode = currentNode.getFirstChild();
+ if (nextNode != null) {
+ currentNode = nextNode;
+ continue;
+ }
+
+ while (currentNode != null) {
+ switch (currentNode.getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ _contentHandler.endDocument();
+ break;
+ case Node.ELEMENT_NODE:
+ _contentHandler.endElement(currentNode.getNamespaceURI(),
+ currentNode.getLocalName(),
+ currentNode.getNodeName());
+ break;
+ }
+
+ nextNode = currentNode.getNextSibling();
+ if (nextNode != null) {
+ currentNode = nextNode;
+ break;
+ }
+
+ currentNode = currentNode.getParentNode();
+ }
+ }
+
+ }
+ else {
+ throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource");
+ }
+
+ }
+
+
+
+ /**
+ * DocumentReader requires a DocumentInputSource, so this is not
+ * implements and simply throws a SAXException. Use parse(DocumentInputSource)
+ * instead
+ *
+ * @param systemId The system identifier (URI).
+ * @exception org.xml.sax.SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception java.io.IOException An IO exception from the parser,
+ * possibly from a byte stream or character stream
+ * supplied by the application.
+ * @see #parse(org.xml.sax.InputSource)
+ */
+ public void parse (String systemId)
+ throws IOException, SAXException
+ {
+ throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource");
+ }
+}
+
+
diff --git a/src/org/apache/fop/tools/anttasks/Fop.java b/src/org/apache/fop/tools/anttasks/Fop.java
index ccdbfa8db..cf72a2400 100644
--- a/src/org/apache/fop/tools/anttasks/Fop.java
+++ b/src/org/apache/fop/tools/anttasks/Fop.java
@@ -99,42 +99,32 @@ public class Fop extends Starter {
}
- public void run () {
- Driver driver = new Driver();
- Options options = new Options();
- boolean errors = false;
+ public void run () {
+ Options options = new Options();
+ boolean errors = false;
String version = Version.getVersion();
-
- File fofileF = new File (fofile);
- Configuration.put("baseDir",new File(fofileF.getAbsolutePath()).getParent());
- if (!fofileF.exists()) {
+
+ File fofileF = new File (fofile);
+ Configuration.put("baseDir",new File(fofileF.getAbsolutePath()).getParent());
+ if (!fofileF.exists()) {
errors = true;
- MessageHandler.errorln(
- "Task Fop - ERROR: Formatting objects file " +
- fofile + " missing.");
+ MessageHandler.errorln("Task Fop - ERROR: Formatting objects file " +
+ fofile + " missing.");
}
-
- InputHandler inputHandler = new FOInputHandler(fofileF);
+
+ InputHandler inputHandler = new FOInputHandler(fofileF);
XMLReader parser = inputHandler.getParser();
- super.setParserFeatures(parser);
-
+ super.setParserFeatures(parser);
+
MessageHandler.logln("=======================\nTask " +
version + "\nconverting file " + fofile + " to " + pdffile);
-
+
if (!errors) {
try {
- driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer",
- version);
- driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- driver.addElementMapping("org.apache.fop.extensions.ExtensionElementMapping");
- driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
- driver.addPropertyList("org.apache.fop.extensions.ExtensionPropertyListMapping");
- driver.setOutputStream(new FileOutputStream(pdffile));
- driver.buildFOTree(parser, inputHandler.fileInputSource(fofileF));
- driver.format();
- driver.render();
+ Driver driver = new Driver(inputHandler.fileInputSource(fofileF), new FileOutputStream(pdffile));
+ driver.setRenderer(Driver.RENDER_PDF);
+ driver.setXMLReader(parser);
+ driver.run();
} catch (Exception e) {
MessageHandler.errorln("Task Fop - FATAL ERROR: " +
e.getMessage());
@@ -142,7 +132,7 @@ public class Fop extends Starter {
}
}
MessageHandler.logln("=======================\n");
- }
+ }
/**
* main method, starts execution of this task