From 74567e49f4caf648926ab2ba7a034ae84c30b2e9 Mon Sep 17 00:00:00 2001 From: Adrian Cumiskey Date: Fri, 11 Jul 2008 18:10:28 +0000 Subject: [PATCH] Merged revisions 675590,675604,675698,675845,675854 via svnmerge from https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk ........ r675590 | vhennebert | 2008-07-10 15:31:52 +0100 (Thu, 10 Jul 2008) | 2 lines Bugzilla #45369: footnotes were rendered at the top of the region-body when using the intermediate format ........ r675604 | jeremias | 2008-07-10 16:02:15 +0100 (Thu, 10 Jul 2008) | 1 line Beware! An evil tab character! But it's been eliminated. ;-) ........ r675698 | jeremias | 2008-07-10 20:47:12 +0100 (Thu, 10 Jul 2008) | 6 lines Added support for piping: - input from stdin (-imagein not supported) - output to stdout Syntax: fop -xml # -xsl mystylesheet.xsl -pdf # (reads the XML from stdin and sends the generated PDF to stdout) ........ r675845 | jeremias | 2008-07-11 08:22:29 +0100 (Fri, 11 Jul 2008) | 1 line Check the result of mkdirs() to see if the target directory could be created. ........ r675854 | jeremias | 2008-07-11 09:00:31 +0100 (Fri, 11 Jul 2008) | 1 line Ignore FindBugs preference file from Eclipse. ........ git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@676040 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/tools/EventProducerCollectorTask.java | 32 ++-- .../org/apache/fop/area/AreaTreeParser.java | 28 ++-- .../apache/fop/cli/CommandLineOptions.java | 149 +++++++++++++----- src/java/org/apache/fop/cli/InputHandler.java | 67 +++++--- src/java/org/apache/fop/cli/Main.java | 18 ++- .../apache/fop/render/xml/XMLRenderer.java | 4 +- .../org/apache/fop/tools/anttasks/Fop.java | 34 ++-- .../standard-testcases/footnote_basic.xml | 1 + 8 files changed, 214 insertions(+), 119 deletions(-) diff --git a/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java b/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java index 60ffaf103..743811142 100644 --- a/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java +++ b/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java @@ -56,13 +56,17 @@ public class EventProducerCollectorTask extends Task { private List filesets = new java.util.ArrayList(); private File modelFile; private File translationFile; - + /** {@inheritDoc} */ public void execute() throws BuildException { try { EventProducerCollector collector = new EventProducerCollector(); processFileSets(collector); - getModelFile().getParentFile().mkdirs(); + File parentDir = getModelFile().getParentFile(); + if (!parentDir.exists() && !parentDir.mkdirs()) { + throw new BuildException( + "Could not create target directory for event model file: " + parentDir); + } collector.saveModelToXML(getModelFile()); log("Event model written to " + getModelFile()); if (getTranslationFile() != null) { @@ -76,10 +80,10 @@ public class EventProducerCollectorTask extends Task { throw new BuildException(ioe); } } - + private static final String MODEL2TRANSLATION = "model2translation.xsl"; private static final String MERGETRANSLATION = "merge-translation.xsl"; - + /** * Updates the translation file with new entries for newly found event producer methods. * @throws IOException if an I/O error occurs @@ -89,7 +93,7 @@ public class EventProducerCollectorTask extends Task { boolean resultExists = getTranslationFile().exists(); SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); - + //Generate fresh generated translation file as template Source src = new StreamSource(getModelFile()); StreamSource xslt1 = new StreamSource( @@ -101,7 +105,7 @@ public class EventProducerCollectorTask extends Task { Transformer transformer = tFactory.newTransformer(xslt1); transformer.transform(src, domres); final Node generated = domres.getNode(); - + Node sourceDocument; if (resultExists) { //Load existing translation file into memory (because we overwrite it later) @@ -176,7 +180,7 @@ public class EventProducerCollectorTask extends Task { public void addFileset(FileSet set) { filesets.add(set); } - + /** * Sets the model file to be written. * @param f the model file @@ -184,7 +188,7 @@ public class EventProducerCollectorTask extends Task { public void setModelFile(File f) { this.modelFile = f; } - + /** * Returns the model file to be written. * @return the model file @@ -192,7 +196,7 @@ public class EventProducerCollectorTask extends Task { public File getModelFile() { return this.modelFile; } - + /** * Sets the translation file for the event producer methods. * @param f the translation file @@ -200,7 +204,7 @@ public class EventProducerCollectorTask extends Task { public void setTranslationFile(File f) { this.translationFile = f; } - + /** * Returns the translation file for the event producer methods. * @return the translation file @@ -208,7 +212,7 @@ public class EventProducerCollectorTask extends Task { public File getTranslationFile() { return this.translationFile; } - + /** * Command-line interface for testing purposes. * @param args the command-line arguments @@ -222,15 +226,15 @@ public class EventProducerCollectorTask extends Task { project.setName("Test"); FileSet fileset = new FileSet(); fileset.setDir(new File("test/java")); - + FilenameSelector selector = new FilenameSelector(); selector.setName("**/*.java"); fileset.add(selector); generator.addFileset(fileset); - + File targetDir = new File("build/codegen1"); targetDir.mkdirs(); - + generator.setModelFile(new File("D:/out.xml")); generator.setTranslationFile(new File("D:/out1.xml")); generator.execute(); diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java index 6d9fd4f32..e4de505b0 100644 --- a/src/java/org/apache/fop/area/AreaTreeParser.java +++ b/src/java/org/apache/fop/area/AreaTreeParser.java @@ -21,12 +21,11 @@ package org.apache.fop.area; import java.awt.Color; import java.awt.geom.Rectangle2D; +import java.nio.CharBuffer; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; -import java.util.StringTokenizer; -import java.nio.CharBuffer; import javax.xml.transform.Source; import javax.xml.transform.Transformer; @@ -37,22 +36,8 @@ import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; -import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Document; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.util.QName; - import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.Trait.Background; import org.apache.fop.area.Trait.InternalLink; @@ -80,6 +65,16 @@ import org.apache.fop.util.ContentHandlerFactory; import org.apache.fop.util.ContentHandlerFactoryRegistry; import org.apache.fop.util.ConversionUtils; import org.apache.fop.util.DefaultErrorListener; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; +import org.apache.xmlgraphics.util.QName; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; /** * This is a parser for the area tree XML (intermediate format) which is used to reread an area @@ -559,6 +554,7 @@ public class AreaTreeParser { public void startElement(Attributes attributes) { Footnote fn = getCurrentBodyRegion().getFootnote(); transferForeignObjects(attributes, fn); + fn.setTop(getAttributeAsInteger(attributes, "top-offset", 0)); areaStack.push(fn); } diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java index 4e5c8ae44..c740339b2 100644 --- a/src/java/org/apache/fop/cli/CommandLineOptions.java +++ b/src/java/org/apache/fop/cli/CommandLineOptions.java @@ -59,7 +59,7 @@ public class CommandLineOptions { /** Used to indicate that only the result of the XSL transformation should be output */ public static final int RENDER_NONE = -1; - /* These following constants are used to describe the input (either .FO, .XML/.XSL or + /* These following constants are used to describe the input (either .FO, .XML/.XSL or * intermediate format) */ @@ -96,11 +96,15 @@ public class CommandLineOptions { private int inputmode = NOT_SET; /* output mode */ private String outputmode = null; + /* true if System.in (stdin) should be used for the input file */ + private boolean useStdIn = false; + /* true if System.out (stdout) should be used for the output file */ + private boolean useStdOut = false; /* rendering options (for the user agent) */ private Map renderingOptions = new java.util.HashMap(); /* target resolution (for the user agent) */ private int targetResolution = 0; - + private FopFactory factory = FopFactory.newInstance(); private FOUserAgent foUserAgent; @@ -149,7 +153,7 @@ public class CommandLineOptions { } checkSettings(); setUserConfig(); - + //Factory config is set up, now we can create the user agent foUserAgent = factory.newFOUserAgent(); foUserAgent.getRendererOptions().putAll(renderingOptions); @@ -372,7 +376,12 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the fo file for the '-fo' option"); } else { - fofile = new File(args[i + 1]); + String filename = args[i + 1]; + if (isSystemInOutFile(filename)) { + this.useStdIn = true; + } else { + fofile = new File(filename); + } return 1; } } @@ -396,7 +405,12 @@ public class CommandLineOptions { throw new FOPException("you must specify the input file " + "for the '-xml' option"); } else { - xmlfile = new File(args[i + 1]); + String filename = args[i + 1]; + if (isSystemInOutFile(filename)) { + this.useStdIn = true; + } else { + xmlfile = new File(filename); + } return 1; } } @@ -412,7 +426,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the PDF output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); if (pdfAMode != null) { if (renderingOptions.get("pdf-a-mode") != null) { throw new FOPException("PDF/A mode already set"); @@ -423,13 +437,25 @@ public class CommandLineOptions { } } + private void setOutputFile(String filename) { + if (isSystemInOutFile(filename)) { + this.useStdOut = true; + } else { + outfile = new File(filename); + } + } + + private boolean isSystemInOutFile(String filename) { + return "#".equals(filename); + } + private int parseMIFOutputOption(String[] args, int i) throws FOPException { setOutputMode(MimeConstants.MIME_MIF); if ((i + 1 == args.length) || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the MIF output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -440,7 +466,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the RTF output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -451,7 +477,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the TIFF output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -462,7 +488,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the PNG output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -508,7 +534,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the PDF output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -519,7 +545,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the PostScript output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -530,7 +556,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the text output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -541,7 +567,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the SVG output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -552,7 +578,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the AFP output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -563,7 +589,7 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the FO output file"); } else { - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } } @@ -588,7 +614,7 @@ public class CommandLineOptions { throw new FOPException("you must specify the output format and the output file"); } else { setOutputMode(mime); - outfile = new File(args[i + 2]); + setOutputFile(args[i + 2]); return 2; } } @@ -599,7 +625,7 @@ public class CommandLineOptions { fofile = new File(args[i]); } else if (outputmode == null) { outputmode = MimeConstants.MIME_PDF; - outfile = new File(args[i]); + setOutputFile(args[i]); } else { throw new FOPException("Don't know what to do with " + args[i]); @@ -612,15 +638,15 @@ public class CommandLineOptions { if ((i + 1 == args.length) || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the area-tree output file"); - } else if ((i + 2 == args.length) + } else if ((i + 2 == args.length) || (args[i + 2].charAt(0) == '-')) { // only output file is specified - outfile = new File(args[i + 1]); + setOutputFile(args[i + 1]); return 1; } else { // mimic format and output file have been specified mimicRenderer = args[i + 1]; - outfile = new File(args[i + 2]); + setOutputFile(args[i + 2]); return 2; } } @@ -631,7 +657,12 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the Area Tree file for the '-atin' option"); } else { - areatreefile = new File(args[i + 1]); + String filename = args[i + 1]; + if (isSystemInOutFile(filename)) { + this.useStdIn = true; + } else { + areatreefile = new File(filename); + } return 1; } } @@ -642,14 +673,19 @@ public class CommandLineOptions { || (args[i + 1].charAt(0) == '-')) { throw new FOPException("you must specify the image file for the '-imagein' option"); } else { - imagefile = new File(args[i + 1]); + String filename = args[i + 1]; + if (isSystemInOutFile(filename)) { + this.useStdIn = true; + } else { + imagefile = new File(filename); + } return 1; } } private PDFEncryptionParams getPDFEncryptionParams() throws FOPException { PDFEncryptionParams params = (PDFEncryptionParams)renderingOptions.get( - PDFRenderer.ENCRYPTION_PARAMS); + PDFRenderer.ENCRYPTION_PARAMS); if (params == null) { if (!PDFEncryptionManager.checkAvailableAlgorithms()) { throw new FOPException("PDF encryption requested but it is not available." @@ -760,7 +796,7 @@ public class CommandLineOptions { if (inputmode == XSLT_INPUT) { // check whether xml *and* xslt file have been set - if (xmlfile == null) { + if (xmlfile == null && !this.useStdIn) { throw new FOPException("XML file must be specified for the transform mode"); } if (xsltfile == null) { @@ -777,7 +813,7 @@ public class CommandLineOptions { + "\n fofile: " + fofile.getAbsolutePath()); } - if (!xmlfile.exists()) { + if (xmlfile != null && !xmlfile.exists()) { throw new FileNotFoundException("Error: xml file " + xmlfile.getAbsolutePath() + " not found "); @@ -795,10 +831,10 @@ public class CommandLineOptions { } if (xmlfile != null || xsltfile != null) { log.warn("fo input mode, but xmlfile or xslt file are set:"); - log.error("xml file: " + xmlfile.toString()); - log.error("xslt file: " + xsltfile.toString()); + log.error("xml file: " + xmlfile); + log.error("xslt file: " + xsltfile); } - if (!fofile.exists()) { + if (fofile != null && !fofile.exists()) { throw new FileNotFoundException("Error: fo file " + fofile.getAbsolutePath() + " not found "); @@ -813,10 +849,10 @@ public class CommandLineOptions { } if (xmlfile != null || xsltfile != null) { log.warn("area tree input mode, but xmlfile or xslt file are set:"); - log.error("xml file: " + xmlfile.toString()); - log.error("xslt file: " + xsltfile.toString()); + log.error("xml file: " + xmlfile); + log.error("xslt file: " + xsltfile); } - if (!areatreefile.exists()) { + if (areatreefile != null && !areatreefile.exists()) { throw new FileNotFoundException("Error: area tree file " + areatreefile.getAbsolutePath() + " not found "); @@ -830,7 +866,7 @@ public class CommandLineOptions { log.warn("image input mode, but XML file is set:"); log.error("XML file: " + xmlfile.toString()); } - if (!imagefile.exists()) { + if (imagefile != null && !imagefile.exists()) { throw new FileNotFoundException("Error: image file " + imagefile.getAbsolutePath() + " not found "); @@ -944,6 +980,22 @@ public class CommandLineOptions { return suppressLowLevelAreas; } + /** + * Indicates whether input comes from standard input (stdin). + * @return true if input comes from standard input (stdin) + */ + public boolean isInputFromStdIn() { + return this.useStdIn; + } + + /** + * Indicates whether output is sent to standard output (stdout). + * @return true if output is sent to standard output (stdout) + */ + public boolean isOutputToStdOut() { + return this.useStdOut; + } + /** * Returns the input file. * @return either the fofile or the xmlfile @@ -986,15 +1038,17 @@ public class CommandLineOptions { + " (Examples for prof: PDF/A-1b or PDF/X-3:2003)\n\n" + " [INPUT] \n" + " infile xsl:fo input file (the same as the next) \n" + + " (use # for infile to pipe input from stdin)\n" + " -fo infile xsl:fo input file \n" + " -xml infile xml input file, must be used together with -xsl \n" + " -atin infile area tree input file \n" - + " -imagein infile image input file \n" + + " -imagein infile image input file (piping through stdin not supported)\n" + " -xsl stylesheet xslt stylesheet \n \n" + " -param name value to use for parameter in xslt stylesheet\n" + " (repeat '-param name value' for each parameter)\n \n" + " [OUTPUT] \n" + " outfile input will be rendered as PDF into outfile\n" + + " (use # for outfile to pipe output to stdout)\n" + " -pdf outfile input will be rendered as PDF (outfile req'd)\n" + " -pdfa1b outfile input will be rendered as PDF/A-1b compliant PDF\n" + " (outfile req'd, same as \"-pdf outfile -pdfprofile PDF/A-1b\")\n" @@ -1027,6 +1081,7 @@ public class CommandLineOptions { + " Fop -fo foo.fo -pdf foo.pdf (does the same as the previous line)\n" + " Fop -xml foo.xml -xsl foo.xsl -pdf foo.pdf\n" + " Fop -xml foo.xml -xsl foo.xsl -foout foo.fo\n" + + " Fop -xml # -xsl foo.xsl -pdf #\n" + " Fop foo.fo -mif foo.mif\n" + " Fop foo.fo -rtf foo.rtf\n" + " Fop foo.fo -print\n" @@ -1057,11 +1112,19 @@ public class CommandLineOptions { break; case FO_INPUT: log.info("FO "); - log.info("fo input file: " + fofile.toString()); + if (this.useStdIn) { + log.info("fo input file: from stdin"); + } else { + log.info("fo input file: " + fofile.toString()); + } break; case XSLT_INPUT: log.info("xslt transformation"); - log.info("xml input file: " + xmlfile.toString()); + if (this.useStdIn) { + log.info("xml input file: from stdin"); + } else { + log.info("xml input file: " + xmlfile.toString()); + } log.info("xslt stylesheet: " + xsltfile.toString()); break; default: @@ -1074,7 +1137,7 @@ public class CommandLineOptions { log.info("awt on screen"); if (outfile != null) { log.error("awt mode, but outfile is set:"); - log.info("out file: " + outfile.toString()); + log.error("out file: " + outfile.toString()); } } else if (MimeConstants.MIME_FOP_PRINT.equals(outputmode)) { log.info("print directly"); @@ -1087,10 +1150,18 @@ public class CommandLineOptions { if (mimicRenderer != null) { log.info("mimic renderer: " + mimicRenderer); } - log.info("output file: " + outfile.toString()); + if (this.useStdOut) { + log.info("output file: to stdout"); + } else { + log.info("output file: " + outfile.toString()); + } } else { log.info(outputmode); - log.info("output file: " + outfile.toString()); + if (this.useStdOut) { + log.info("output file: to stdout"); + } else { + log.info("output file: " + outfile.toString()); + } } log.info("OPTIONS"); diff --git a/src/java/org/apache/fop/cli/InputHandler.java b/src/java/org/apache/fop/cli/InputHandler.java index 4c38fa5c7..f00de3c6f 100644 --- a/src/java/org/apache/fop/cli/InputHandler.java +++ b/src/java/org/apache/fop/cli/InputHandler.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,8 +21,8 @@ package org.apache.fop.cli; // Imported java.io classes import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; @@ -61,7 +61,7 @@ import org.xml.sax.XMLReader; * parameters) or FO File input alone */ public class InputHandler implements ErrorListener, Renderable { - + /** original source file */ protected File sourcefile = null; private File stylesheet = null; // for XML/XSLT usage @@ -69,12 +69,12 @@ public class InputHandler implements ErrorListener, Renderable { /** the logger */ protected Log log = LogFactory.getLog(InputHandler.class); - + /** * Constructor for XML->XSLT->FO input * @param xmlfile XML file * @param xsltfile XSLT file - * @param params Vector of command-line parameters (name, value, + * @param params Vector of command-line parameters (name, value, * name, value, ...) for XSL stylesheet, null if none */ public InputHandler(File xmlfile, File xsltfile, Vector params) { @@ -98,7 +98,7 @@ public class InputHandler implements ErrorListener, Renderable { * @param out the output stream to write the generated output to (may be null if not applicable) * @throws FOPException in case of an error during processing */ - public void renderTo(FOUserAgent userAgent, String outputFormat, OutputStream out) + public void renderTo(FOUserAgent userAgent, String outputFormat, OutputStream out) throws FOPException { FopFactory factory = userAgent.getFactory(); @@ -110,7 +110,7 @@ public class InputHandler implements ErrorListener, Renderable { } // if base URL was not explicitly set in FOUserAgent, obtain here - if (fop.getUserAgent().getBaseURL() == null) { + if (fop.getUserAgent().getBaseURL() == null && sourcefile != null) { String baseURL = null; try { @@ -127,7 +127,7 @@ public class InputHandler implements ErrorListener, Renderable { transformTo(res); } - + /** {@inheritDoc} */ public void renderTo(FOUserAgent userAgent, String outputFormat) throws FOPException { renderTo(userAgent, outputFormat, null); @@ -143,34 +143,53 @@ public class InputHandler implements ErrorListener, Renderable { Result res = new StreamResult(out); transformTo(res); } - + /** * Creates a Source for the main input file. Processes XInclude if * available in the XML parser. - * + * * @return the Source for the main input file */ protected Source createMainSource() { Source result; + InputStream in; + String uri; + if (this.sourcefile != null) { + try { + in = new java.io.FileInputStream(this.sourcefile); + uri = this.sourcefile.toURI().toASCIIString(); + } catch (FileNotFoundException e) { + //handled elsewhere + return new StreamSource(this.sourcefile); + } + } else { + in = System.in; + uri = null; + } try { - InputSource is = new InputSource(new FileInputStream( - this.sourcefile)); - is.setSystemId(this.sourcefile.toURI().toASCIIString()); + InputSource is = new InputSource(in); + is.setSystemId(uri); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setFeature("http://xml.org/sax/features/namespaces", true); spf.setFeature("http://apache.org/xml/features/xinclude", true); XMLReader xr = spf.newSAXParser().getXMLReader(); result = new SAXSource(xr, is); } catch (SAXException e) { - result = new StreamSource(this.sourcefile); - } catch (IOException e) { - result = new StreamSource(this.sourcefile); + if (this.sourcefile != null) { + result = new StreamSource(this.sourcefile); + } else { + result = new StreamSource(in, uri); + } } catch (ParserConfigurationException e) { - result = new StreamSource(this.sourcefile); + if (this.sourcefile != null) { + result = new StreamSource(this.sourcefile); + } else { + result = new StreamSource(in, uri); + } } return result; } - + /** * Creates a Source for the selected stylesheet. * @return the Source for the selected stylesheet or null if there's no stylesheet @@ -182,7 +201,7 @@ public class InputHandler implements ErrorListener, Renderable { return null; } } - + /** * Transforms the input document to the input format expected by FOP using XSLT. * @param result the Result object where the result of the XSL transformation is sent to @@ -193,15 +212,15 @@ public class InputHandler implements ErrorListener, Renderable { // Setup XSLT TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer; - + Source xsltSource = createXSLTSource(); if (xsltSource == null) { // FO Input transformer = factory.newTransformer(); } else { // XML/XSLT input transformer = factory.newTransformer(xsltSource); - + // Set the value of parameters, if any, defined for stylesheet - if (xsltParams != null) { + if (xsltParams != null) { for (int i = 0; i < xsltParams.size(); i += 2) { transformer.setParameter((String) xsltParams.elementAt(i), (String) xsltParams.elementAt(i + 1)); diff --git a/src/java/org/apache/fop/cli/Main.java b/src/java/org/apache/fop/cli/Main.java index 43da8d966..545aef7ff 100644 --- a/src/java/org/apache/fop/cli/Main.java +++ b/src/java/org/apache/fop/cli/Main.java @@ -62,7 +62,7 @@ public class Main { fopJar = new File(baseDir, "fop.jar"); } if (!fopJar.exists()) { - throw new RuntimeException("fop.jar not found in directory: " + throw new RuntimeException("fop.jar not found in directory: " + baseDir.getAbsolutePath() + " (or below)"); } List jars = new java.util.ArrayList(); @@ -99,7 +99,7 @@ public class Main { }*/ return urls; } - + /** * @return true if FOP's dependecies are available in the current ClassLoader setup. */ @@ -115,7 +115,7 @@ public class Main { return false; } } - + /** * Dynamically builds a ClassLoader and executes FOP. * @param args command-line arguments @@ -123,7 +123,7 @@ public class Main { public static void startFOPWithDynamicClasspath(String[] args) { try { URL[] urls = getJARList(); - //System.out.println("CCL: " + //System.out.println("CCL: " // + Thread.currentThread().getContextClassLoader().toString()); ClassLoader loader = new java.net.URLClassLoader(urls, null); Thread.currentThread().setContextClassLoader(loader); @@ -137,13 +137,13 @@ public class Main { System.exit(-1); } } - + /** * Executes FOP with the given ClassLoader setup. * @param args command-line arguments */ public static void startFOP(String[] args) { - //System.out.println("static CCL: " + //System.out.println("static CCL: " // + Thread.currentThread().getContextClassLoader().toString()); //System.out.println("static CL: " + Fop.class.getClassLoader().toString()); CommandLineOptions options = null; @@ -155,7 +155,7 @@ public class Main { if (!options.parse(args)) { System.exit(1); } - + foUserAgent = options.getFOUserAgent(); String outputFormat = options.getOutputFormat(); @@ -164,6 +164,8 @@ public class Main { out = new java.io.BufferedOutputStream( new java.io.FileOutputStream(options.getOutputFile())); foUserAgent.setOutputFile(options.getOutputFile()); + } else if (options.isOutputToStdOut()) { + out = new java.io.BufferedOutputStream(System.out); } if (!MimeConstants.MIME_XSL_FO.equals(outputFormat)) { options.getInputHandler().renderTo(foUserAgent, outputFormat, out); @@ -190,7 +192,7 @@ public class Main { System.exit(1); } } - + /** * The main routine for the command line interface * @param args the command line parameters diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index b41de7387..aec067b91 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -544,7 +544,9 @@ public class XMLRenderer extends AbstractXMLRenderer { * {@inheritDoc} */ protected void renderFootnote(Footnote footnote) { - startElement("footnote"); + atts.clear(); + addAttribute("top-offset", footnote.getTop()); + startElement("footnote", atts); super.renderFootnote(footnote); endElement("footnote"); } diff --git a/src/java/org/apache/fop/tools/anttasks/Fop.java b/src/java/org/apache/fop/tools/anttasks/Fop.java index a33c396d4..83217651e 100644 --- a/src/java/org/apache/fop/tools/anttasks/Fop.java +++ b/src/java/org/apache/fop/tools/anttasks/Fop.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -54,7 +54,7 @@ import org.xml.sax.SAXException; *
  • format -> MIME type of the format to generate ex. "application/pdf"
  • *
  • outfile -> output filename
  • *
  • baseDir -> directory to work from
  • - *
  • relativebase -> (true | false) control whether to use each FO's + *
  • relativebase -> (true | false) control whether to use each FO's * directory as base directory. false uses the baseDir parameter.
  • *
  • userconfig -> file with user configuration (same as the "-c" command * line option)
  • @@ -137,7 +137,7 @@ public class Fop extends Task { public void setRelativebase(boolean relbase) { this.relativebase = relbase; } - + /** * Gets the relative base attribute * @return the relative base attribute @@ -294,7 +294,7 @@ public class Fop extends Task { public boolean getLogFiles() { return this.logFiles; } - + /** * {@inheritDoc} */ @@ -330,7 +330,7 @@ class FOPTaskStarter { // configure fopFactory as desired private FopFactory fopFactory = FopFactory.newInstance(); - + private Fop task; private String baseURL = null; @@ -411,13 +411,13 @@ class FOPTaskStarter { {MimeConstants.MIME_AFP_ALT, ".afp"}, {MimeConstants.MIME_XSL_FO, ".fo"} }; - + private String determineExtension(String outputFormat) { for (int i = 0; i < EXTENSIONS.length; i++) { if (EXTENSIONS[i][0].equals(outputFormat)) { String ext = EXTENSIONS[i][1]; if (ext == null) { - throw new RuntimeException("Output format '" + throw new RuntimeException("Output format '" + outputFormat + "' does not produce a file."); } else { return ext; @@ -467,7 +467,7 @@ class FOPTaskStarter { // actioncount = # of fofiles actually processed through FOP int actioncount = 0; // skippedcount = # of fofiles which haven't changed (force = "false") - int skippedcount = 0; + int skippedcount = 0; // deal with single source file if (task.getFofile() != null) { @@ -479,14 +479,14 @@ class FOPTaskStarter { if (task.getOutdir() != null) { outf = new File(task.getOutdir(), outf.getName()); } - // Render if "force" flag is set OR + // Render if "force" flag is set OR // OR output file doesn't exist OR // output file is older than input file - if (task.getForce() || !outf.exists() + if (task.getForce() || !outf.exists() || (task.getFofile().lastModified() > outf.lastModified() )) { render(task.getFofile(), outf, outputFormat); actioncount++; - } else if (outf.exists() + } else if (outf.exists() && (task.getFofile().lastModified() <= outf.lastModified() )) { skippedcount++; } @@ -531,10 +531,10 @@ class FOPTaskStarter { task.log("Error setting base URL", Project.MSG_DEBUG); } - // Render if "force" flag is set OR + // Render if "force" flag is set OR // OR output file doesn't exist OR // output file is older than input file - if (task.getForce() || !outf.exists() + if (task.getForce() || !outf.exists() || (f.lastModified() > outf.lastModified() )) { render(f, outf, outputFormat); actioncount++; @@ -543,11 +543,11 @@ class FOPTaskStarter { } } } - + if (actioncount + skippedcount == 0) { task.log("No files processed. No files were selected by the filesets " + "and no fofile was set." , Project.MSG_WARN); - } else if (skippedcount > 0) { + } else if (skippedcount > 0) { task.log(skippedcount + " xslfo file(s) skipped (no change found" + " since last generation; set force=\"true\" to override)." , Project.MSG_INFO); @@ -579,7 +579,7 @@ class FOPTaskStarter { } catch (Exception ex) { if (task.getThrowexceptions()) { throw new BuildException(ex); - } + } logger.error("Error rendering fo file: " + foFile, ex); } finally { try { diff --git a/test/layoutengine/standard-testcases/footnote_basic.xml b/test/layoutengine/standard-testcases/footnote_basic.xml index 29678fab9..402f1d6ad 100644 --- a/test/layoutengine/standard-testcases/footnote_basic.xml +++ b/test/layoutengine/standard-testcases/footnote_basic.xml @@ -68,6 +68,7 @@ + -- 2.39.5