aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/tools
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2003-03-11 13:05:43 +0000
committerJeremias Maerki <jeremias@apache.org>2003-03-11 13:05:43 +0000
commit1e5d512c216d329effa693b91ef64652945def6a (patch)
tree5bd3521ee8121eade7bf1909ceaf29cfc0263fd1 /src/java/org/apache/fop/tools
parent73c824d39411bf11ad0c2f4e1c57cd9c484665f9 (diff)
downloadxmlgraphics-fop-1e5d512c216d329effa693b91ef64652945def6a.tar.gz
xmlgraphics-fop-1e5d512c216d329effa693b91ef64652945def6a.zip
Moved sources from src/org/** to src/java/org/**
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196061 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/tools')
-rw-r--r--src/java/org/apache/fop/tools/AreaTreeBuilder.java782
-rw-r--r--src/java/org/apache/fop/tools/DocumentInputSource.java99
-rw-r--r--src/java/org/apache/fop/tools/DocumentReader.java551
-rw-r--r--src/java/org/apache/fop/tools/TestConverter.java391
-rw-r--r--src/java/org/apache/fop/tools/anttasks/Compare.java235
-rw-r--r--src/java/org/apache/fop/tools/anttasks/Fop.java503
-rw-r--r--src/java/org/apache/fop/tools/anttasks/RunTest.java256
-rw-r--r--src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java197
-rw-r--r--src/java/org/apache/fop/tools/xslt/TraxTransform.java194
-rw-r--r--src/java/org/apache/fop/tools/xslt/XSLTransform.java215
10 files changed, 3423 insertions, 0 deletions
diff --git a/src/java/org/apache/fop/tools/AreaTreeBuilder.java b/src/java/org/apache/fop/tools/AreaTreeBuilder.java
new file mode 100644
index 000000000..c2f463dfa
--- /dev/null
+++ b/src/java/org/apache/fop/tools/AreaTreeBuilder.java
@@ -0,0 +1,782 @@
+/*
+ * $Id: AreaTreeBuilder.java,v 1.16 2003/03/07 10:09:29 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools;
+
+// Java
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.StringTokenizer;
+
+// JAXP
+import javax.xml.parsers.DocumentBuilderFactory;
+
+// DOM
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+// Batik
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+
+// FOP
+import org.apache.fop.area.Area;
+import org.apache.fop.area.AreaTree;
+import org.apache.fop.area.AreaTreeModel;
+import org.apache.fop.area.BeforeFloat;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.BodyRegion;
+import org.apache.fop.area.CTM;
+import org.apache.fop.area.Flow;
+import org.apache.fop.area.Footnote;
+import org.apache.fop.area.LineArea;
+import org.apache.fop.area.MainReference;
+import org.apache.fop.area.Page;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.RegionReference;
+import org.apache.fop.area.RegionViewport;
+import org.apache.fop.area.Span;
+import org.apache.fop.area.StorePagesModel;
+import org.apache.fop.area.Title;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.Character;
+import org.apache.fop.area.inline.Container;
+import org.apache.fop.area.inline.ForeignObject;
+import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.area.inline.Leader;
+import org.apache.fop.area.inline.Space;
+import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.area.inline.Word;
+import org.apache.fop.layout.FontInfo;
+import org.apache.fop.layout.FontState;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.render.pdf.PDFRenderer;
+import org.apache.fop.render.svg.SVGRenderer;
+import org.apache.fop.render.xml.XMLRenderer;
+import org.apache.fop.fo.FOUserAgent;
+import org.apache.fop.fo.properties.RuleStyle;
+import org.apache.fop.fonts.FontMetrics;
+
+// Avalon
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+
+/**
+ * Area tree tester.
+ * The purpose of this class is to create and render an area tree
+ * for the purpose of testing the area tree and rendering.
+ * This covers the set of possible properties that can be set
+ * on the area tree for rendering.
+ * As this is not for general purpose there is no attempt to handle
+ * invalid area tree xml.
+ *
+ * Tests: different renderers, saving and loading pages with serialization
+ * out of order rendering
+ */
+public class AreaTreeBuilder extends AbstractLogEnabled {
+
+ /**
+ * Main method
+ * @param args command line arguments
+ */
+ public static void main(String[] args) {
+ AreaTreeBuilder atb = new AreaTreeBuilder();
+ atb.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG));
+
+ atb.runTests(args[0], args[1], args[2]);
+ System.exit(0);
+ }
+
+ /**
+ * Run the tests.
+ * @param in input filename
+ * @param type output format
+ * @param out output filename
+ */
+ protected void runTests(String in, String type, String out) {
+ getLogger().debug("Starting tests");
+ runTest(in, type, out);
+ getLogger().debug("Finished");
+ }
+
+ /**
+ * Run a test.
+ * @param in input filename
+ * @param type output format
+ * @param out output filename
+ */
+ protected void runTest(String in, String type, String out) {
+ Renderer rend = null;
+ if ("xml".equals(type)) {
+ rend = new XMLRenderer();
+ } else if ("pdf".equals(type)) {
+ rend = new PDFRenderer();
+ } else if ("svg".equals(type)) {
+ rend = new SVGRenderer();
+ }
+ setupLogger(rend);
+ FontInfo fi = new FontInfo();
+ rend.setupFontInfo(fi);
+ FOUserAgent ua = new FOUserAgent();
+ setupLogger(ua);
+ rend.setUserAgent(ua);
+
+ StorePagesModel sm = AreaTree.createStorePagesModel();
+ TreeLoader tl = new TreeLoader(fi);
+ setupLogger(tl);
+ tl.setTreeModel(sm);
+ try {
+ InputStream is =
+ new java.io.BufferedInputStream(new java.io.FileInputStream(in));
+ tl.buildAreaTree(is);
+ renderAreaTree(sm, rend, out);
+ } catch (IOException e) {
+ getLogger().error("error reading file" + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Renders an area tree to a target format using a renderer.
+ * @param sm area tree pages
+ * @param rend renderer to use for output
+ * @param out target filename
+ */
+ protected void renderAreaTree(StorePagesModel sm,
+ Renderer rend, String out) {
+ try {
+ OutputStream os =
+ new java.io.BufferedOutputStream(new java.io.FileOutputStream(out));
+
+ rend.startRenderer(os);
+
+ int count = 0;
+ int seqc = sm.getPageSequenceCount();
+ while (count < seqc) {
+ Title title = sm.getTitle(count);
+ rend.startPageSequence(title);
+ int pagec = sm.getPageCount(count);
+ int c = 0;
+ while (c < pagec) {
+ PageViewport page = sm.getPage(count, c);
+ c++;
+ // save the page to a stream for testing
+ /*ObjectOutputStream tempstream = new ObjectOutputStream(
+ new BufferedOutputStream(
+ new FileOutputStream("temp.ser")));
+ page.savePage(tempstream);
+ tempstream.close();
+ File temp = new File("temp.ser");
+ getLogger().debug("page serialized to: " + temp.length());
+ temp = null;
+ ObjectInputStream in = new ObjectInputStream(
+ new BufferedInputStream(
+ new FileInputStream("temp.ser")));
+ page.loadPage(in);
+ in.close();*/
+
+ rend.renderPage(page);
+ }
+ count++;
+ }
+
+ rend.stopRenderer();
+ os.close();
+ } catch (Exception e) {
+ getLogger().error("error rendering output", e);
+ }
+ }
+
+
+}
+
+// this loads an area tree from an xml file
+// the xml format is the same as the xml renderer output
+class TreeLoader extends AbstractLogEnabled {
+ private AreaTree areaTree;
+ private AreaTreeModel model;
+ private FontInfo fontInfo;
+ private FontState currentFontState;
+
+ TreeLoader(FontInfo fi) {
+ fontInfo = fi;
+ }
+
+ public void setTreeModel(AreaTreeModel mo) {
+ model = mo;
+ }
+
+ public void buildAreaTree(InputStream is) {
+ Document doc = null;
+ try {
+ DocumentBuilderFactory fact =
+ DocumentBuilderFactory.newInstance();
+ fact.setNamespaceAware(true);
+ doc = fact.newDocumentBuilder().parse(is);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Element root = null;
+ root = doc.getDocumentElement();
+
+ areaTree = new AreaTree();
+ areaTree.setTreeModel(model);
+
+ readAreaTree(root);
+ }
+
+ public void readAreaTree(Element root) {
+
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("pageSequence")) {
+ readPageSequence((Element) obj);
+ }
+ }
+ }
+
+ public void readPageSequence(Element root) {
+ Title title = null;
+ boolean started = false;
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("title")) {
+ if (started) {
+ // problem
+ } else {
+ title = readTitle((Element) obj);
+ model.startPageSequence(title);
+ started = true;
+ }
+ } else if (obj.getNodeName().equals("pageViewport")) {
+ if (!started) {
+ model.startPageSequence(null);
+ started = true;
+ }
+ PageViewport viewport = readPageViewport((Element) obj);
+ areaTree.addPage(viewport);
+ }
+ }
+ }
+
+ public Title readTitle(Element root) {
+ Title title = new Title();
+ List childs = getInlineAreas(root);
+ for (int i = 0; i < childs.size(); i++) {
+ InlineArea obj = (InlineArea) childs.get(i);
+ title.addInlineArea(obj);
+ }
+ return title;
+ }
+
+ public PageViewport readPageViewport(Element root) {
+ Rectangle2D bounds = getRectangle(root, "bounds");
+ PageViewport viewport = null;
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("page")) {
+ Page page = readPage((Element) obj);
+ viewport = new PageViewport(page, bounds);
+ }
+ }
+ return viewport;
+ }
+
+ public Page readPage(Element root) {
+ //String bounds = root.getAttribute("bounds");
+ Page page = new Page();
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("regionViewport")) {
+ readRegionViewport(page, (Element) obj);
+ }
+ }
+ return page;
+ }
+
+ Rectangle2D getRectangle(Element root, String attr) {
+ String rect = root.getAttribute(attr);
+ StringTokenizer st = new StringTokenizer(rect, " ");
+ int x = 0, y = 0, w = 0, h = 0;
+ if (st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ x = Integer.parseInt(tok);
+ }
+ if (st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ y = Integer.parseInt(tok);
+ }
+ if (st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ w = Integer.parseInt(tok);
+ }
+ if (st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ h = Integer.parseInt(tok);
+ }
+ Rectangle2D r2d = new Rectangle2D.Float(x, y, w, h);
+ return r2d;
+ }
+
+ public RegionViewport readRegionViewport(Page page, Element root) {
+ RegionViewport reg = new RegionViewport(getRectangle(root, "rect"));
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("regionBefore")) {
+ reg.setRegion(readRegion((Element) obj, RegionReference.BEFORE));
+ page.setRegion(RegionReference.BEFORE, reg);
+ } else if (obj.getNodeName().equals("regionStart")) {
+ reg.setRegion(readRegion((Element) obj, RegionReference.START));
+ page.setRegion(RegionReference.START, reg);
+ } else if (obj.getNodeName().equals("regionBody")) {
+ reg.setRegion(readRegion((Element) obj, RegionReference.BODY));
+ page.setRegion(RegionReference.BODY, reg);
+ } else if (obj.getNodeName().equals("regionEnd")) {
+ reg.setRegion(readRegion((Element) obj, RegionReference.END));
+ page.setRegion(RegionReference.END, reg);
+ } else if (obj.getNodeName().equals("regionAfter")) {
+ reg.setRegion(readRegion((Element) obj, RegionReference.AFTER));
+ page.setRegion(RegionReference.AFTER, reg);
+ }
+ }
+
+ return reg;
+ }
+
+ public RegionReference readRegion(Element root, int type) {
+ RegionReference reg;
+ if (type == RegionReference.BODY) {
+ BodyRegion br = new BodyRegion();
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("beforeFloat")) {
+ BeforeFloat bf = readBeforeFloat((Element) obj);
+ br.setBeforeFloat(bf);
+ } else if (obj.getNodeName().equals("mainReference")) {
+ MainReference mr = readMainReference((Element) obj);
+ br.setMainReference(mr);
+ } else if (obj.getNodeName().equals("footnote")) {
+ Footnote foot = readFootnote((Element) obj);
+ br.setFootnote(foot);
+ }
+ }
+ reg = br;
+ } else {
+ reg = new RegionReference(type);
+ List blocks = getBlocks(root);
+ for (int i = 0; i < blocks.size(); i++) {
+ Block obj = (Block) blocks.get(i);
+ reg.addBlock(obj);
+ }
+ }
+ reg.setCTM(new CTM());
+ return reg;
+ }
+
+ public BeforeFloat readBeforeFloat(Element root) {
+ BeforeFloat bf = new BeforeFloat();
+ List blocks = getBlocks(root);
+ for (int i = 0; i < blocks.size(); i++) {
+ Block obj = (Block) blocks.get(i);
+ bf.addBlock(obj);
+ }
+ return bf;
+ }
+
+ public MainReference readMainReference(Element root) {
+ MainReference mr = new MainReference();
+ List spans = getSpans(root);
+ for (int i = 0; i < spans.size(); i++) {
+ Span obj = (Span) spans.get(i);
+ mr.addSpan(obj);
+ }
+ return mr;
+ }
+
+ List getSpans(Element root) {
+ List list = new java.util.ArrayList();
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("span")) {
+ List flows = getFlows((Element) obj);
+ Span span = new Span(flows.size());
+ for (int j = 0; j < flows.size(); j++) {
+ Flow flow = (Flow) flows.get(j);
+ span.addFlow(flow);
+ }
+ list.add(span);
+ }
+ }
+ return list;
+ }
+
+ List getFlows(Element root) {
+ List list = new java.util.ArrayList();
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("flow")) {
+ Flow flow = new Flow();
+ List blocks = getBlocks((Element) obj);
+ for (int j = 0; j < blocks.size(); j++) {
+ Block block = (Block) blocks.get(j);
+ flow.addBlock(block);
+ }
+ list.add(flow);
+ }
+ }
+ return list;
+ }
+
+ public Footnote readFootnote(Element root) {
+ Footnote foot = new Footnote();
+ List blocks = getBlocks(root);
+ for (int i = 0; i < blocks.size(); i++) {
+ Block obj = (Block) blocks.get(i);
+ foot.addBlock(obj);
+ }
+ return foot;
+ }
+
+
+ List getBlocks(Element root) {
+ List list = new java.util.ArrayList();
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("block")) {
+ Block block = new Block();
+ addTraits((Element)obj, block);
+ addBlockChildren(block, (Element) obj);
+ list.add(block);
+ }
+ }
+ return list;
+ }
+
+ protected void addBlockChildren(Block block, Element root) {
+ NodeList childs = root.getChildNodes();
+ int type = -1;
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("block")) {
+ if (type == 2) {
+ // error
+ }
+ Block b = new Block();
+ addBlockChildren(b, (Element) obj);
+ block.addBlock(b);
+ type = 1;
+ } else if (obj.getNodeName().equals("lineArea")) {
+ if (type == 1) {
+ // error
+ }
+ LineArea line = new LineArea();
+ addTraits((Element) obj, line);
+ String height = ((Element) obj).getAttribute("height");
+ int h = Integer.parseInt(height);
+ line.setHeight(h);
+
+ List inlines = getInlineAreas((Element) obj);
+ for (int j = 0; j < inlines.size(); j++) {
+ InlineArea inline = (InlineArea) inlines.get(j);
+ line.addInlineArea(inline);
+ }
+
+ block.addLineArea(line);
+ type = 2;
+ }
+ }
+ }
+
+ // children of element are inline areas
+ List getInlineAreas(Element root) {
+ List list = new java.util.ArrayList();
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("char")) {
+ Character ch =
+ new Character(getString((Element) obj).charAt(0));
+ addTraits((Element) obj, ch);
+ String fname = fontInfo.fontLookup("sans-serif", "normal", FontInfo.NORMAL);
+ FontMetrics metrics = fontInfo.getMetricsFor(fname);
+ currentFontState =
+ new FontState(fname, metrics, 12000);
+
+ ch.setWidth(currentFontState.getWidth(ch.getChar()));
+ ch.setOffset(currentFontState.getCapHeight());
+ list.add(ch);
+ } else if (obj.getNodeName().equals("space")) {
+ Space space = new Space();
+ String width = ((Element) obj).getAttribute("width");
+ int w = Integer.parseInt(width);
+ space.setWidth(w);
+ list.add(space);
+ } else if (obj.getNodeName().equals("viewport")) {
+ Viewport viewport = getViewport((Element) obj);
+ if (viewport != null) {
+ list.add(viewport);
+ }
+ } else if (obj.getNodeName().equals("leader")) {
+ Leader leader = getLeader((Element) obj);
+ if (leader != null) {
+ list.add(leader);
+ }
+ } else if (obj.getNodeName().equals("word")) {
+ String fname = fontInfo.fontLookup("sans-serif", "normal", FontInfo.NORMAL);
+ FontMetrics metrics = fontInfo.getMetricsFor(fname);
+ currentFontState =
+ new FontState(fname, metrics, 12000);
+ Word word = getWord((Element) obj);
+
+ word.addTrait(Trait.FONT_NAME, fname);
+ word.addTrait(Trait.FONT_SIZE, new Integer(12000));
+
+ if (word != null) {
+ list.add(word);
+ }
+ } else {
+ }
+ }
+ return list;
+ }
+
+ Viewport getViewport(Element root) {
+ Area child = null;
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj.getNodeName().equals("container")) {
+ child = getContainer((Element) obj);
+ } else if (obj.getNodeName().equals("foreignObject")) {
+ child = getForeignObject((Element) obj);
+ } else if (obj.getNodeName().equals("image")) {
+ child = getImage((Element) obj);
+ }
+ }
+ if (child == null) {
+ return null;
+ }
+ Viewport viewport = new Viewport(child);
+ String str = root.getAttribute("width");
+ if (str != null && !"".equals(str)) {
+ int width = Integer.parseInt(str);
+ viewport.setWidth(width);
+ }
+ return viewport;
+ }
+
+ Container getContainer(Element root) {
+ Container cont = new Container();
+ List blocks = getBlocks(root);
+ for (int i = 0; i < blocks.size(); i++) {
+ Block obj = (Block) blocks.get(i);
+ cont.addBlock(obj);
+ }
+ return cont;
+ }
+
+ ForeignObject getForeignObject(Element root) {
+ Document doc;
+ String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
+
+ NodeList childs = root.getChildNodes();
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ if (obj instanceof Element) {
+ //getLogger().debug(obj.getNodeName());
+ Element rootEle = (Element) obj;
+ String space = rootEle.getAttribute("xmlns");
+ if (svgNS.equals(space)) {
+ try {
+ DocumentBuilderFactory fact =
+ DocumentBuilderFactory.newInstance();
+ fact.setNamespaceAware(true);
+
+ doc = fact.newDocumentBuilder().newDocument();
+ Node node = doc.importNode(obj, true);
+ doc.appendChild(node);
+ //DOMImplementation impl =
+ // SVGDOMImplementation.getDOMImplementation();
+ // due to namespace problem attributes are not cloned
+ // serializing causes an npe
+ //doc = DOMUtilities.deepCloneDocument(doc, impl);
+
+ ForeignObject fo = new ForeignObject(doc, svgNS);
+ return fo;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ try {
+ DocumentBuilderFactory fact =
+ DocumentBuilderFactory.newInstance();
+ fact.setNamespaceAware(true);
+ doc = fact.newDocumentBuilder().newDocument();
+ Node node = doc.importNode(obj, true);
+ doc.appendChild(node);
+ ForeignObject fo = new ForeignObject(doc, space);
+ return fo;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ Image getImage(Element root) {
+ String url = root.getAttribute("url");
+ Image image = new Image(url);
+ return image;
+ }
+
+ Leader getLeader(Element root) {
+ Leader leader = new Leader();
+ String rs = root.getAttribute("ruleStyle");
+ if ("solid".equals(rs)) {
+ leader.setRuleStyle(RuleStyle.SOLID);
+ } else if ("dotted".equals(rs)) {
+ leader.setRuleStyle(RuleStyle.DOTTED);
+ } else if ("dashed".equals(rs)) {
+ leader.setRuleStyle(RuleStyle.DASHED);
+ } else if ("double".equals(rs)) {
+ leader.setRuleStyle(RuleStyle.DOUBLE);
+ } else if ("groove".equals(rs)) {
+ leader.setRuleStyle(RuleStyle.GROOVE);
+ } else if ("ridge".equals(rs)) {
+ leader.setRuleStyle(RuleStyle.RIDGE);
+ }
+ String rt = root.getAttribute("ruleThickness");
+ int thick = Integer.parseInt(rt);
+ leader.setRuleThickness(thick);
+ rt = root.getAttribute("width");
+ if (rt != null && !"".equals(rt)) {
+ thick = Integer.parseInt(rt);
+ leader.setWidth(thick);
+ }
+ leader.setOffset(currentFontState.getCapHeight());
+ addTraits(root, leader);
+ return leader;
+ }
+
+ Word getWord(Element root) {
+ String str = getString(root);
+ Word word = new Word();
+ word.setWord(str);
+ addTraits(root, word);
+ int width = 0;
+ for (int count = 0; count < str.length(); count++) {
+ width += currentFontState.getWidth(str.charAt(count));
+ }
+ word.setWidth(width);
+ word.setOffset(currentFontState.getCapHeight());
+
+ return word;
+ }
+
+
+ public void addTraits(Element ele, Area area) {
+ String str = ele.getAttribute("props");
+ StringTokenizer st = new StringTokenizer(str, ";");
+ while (st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ int index = tok.indexOf(":");
+ String id = tok.substring(0, index);
+ Object traitCode = Trait.getTraitCode(id);
+ if (traitCode != null) {
+ area.addTrait(traitCode,
+ Trait.makeTraitValue(traitCode,
+ tok.substring(index + 1)));
+ } else {
+ getLogger().error("Unknown trait: " + id);
+ }
+ }
+ }
+
+ public List getRanges(Element ele) {
+ List list = new java.util.ArrayList();
+ String str = ele.getAttribute("ranges");
+ StringTokenizer st = new StringTokenizer(str, ";");
+ while (st.hasMoreTokens()) {
+ /*String tok =*/ st.nextToken();
+ }
+ return list;
+ }
+
+ public String getString(Element ele) {
+ String str = "";
+ NodeList childs = ele.getChildNodes();
+ if (childs.getLength() == 0) {
+ return null;
+ }
+ for (int i = 0; i < childs.getLength(); i++) {
+ Node obj = childs.item(i);
+ str = str + obj.getNodeValue();
+ }
+ return str;
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/tools/DocumentInputSource.java b/src/java/org/apache/fop/tools/DocumentInputSource.java
new file mode 100644
index 000000000..c4067cc17
--- /dev/null
+++ b/src/java/org/apache/fop/tools/DocumentInputSource.java
@@ -0,0 +1,99 @@
+/*
+ * $Id: DocumentInputSource.java,v 1.4 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+/**
+ * This is an InputSource to be used with DocumentReader.
+ *
+ * @author Kelly A Campbell
+ */
+public class DocumentInputSource extends InputSource {
+
+ private Document document;
+
+ /**
+ * Default constructor.
+ */
+ public DocumentInputSource() {
+ super();
+ }
+
+ /**
+ * Main constructor
+ * @param document the DOM document to use as input
+ */
+ public DocumentInputSource(Document document) {
+ this();
+ setDocument(document);
+ }
+
+ /**
+ * Returns the input document.
+ * @return the input DOM document.
+ */
+ public Document getDocument() {
+ return this.document;
+ }
+
+ /**
+ * Sets the input document.
+ * @param document the DOM document to use as input
+ */
+ public void setDocument(Document document) {
+ this.document = document;
+ }
+
+}
+
+
diff --git a/src/java/org/apache/fop/tools/DocumentReader.java b/src/java/org/apache/fop/tools/DocumentReader.java
new file mode 100644
index 000000000..4c0f478ea
--- /dev/null
+++ b/src/java/org/apache/fop/tools/DocumentReader.java
@@ -0,0 +1,551 @@
+/*
+ * $Id: DocumentReader.java,v 1.4 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools;
+
+import java.io.IOException;
+
+// DOM
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+// SAX
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+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 namespacePrefixes = 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 SAXNotRecognizedException When the
+ * XMLReader does not recognize the feature name.
+ * @exception 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 namespacePrefixes;
+ } 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 value The requested state of the feature (true or false).
+ * @exception SAXNotRecognizedException When the
+ * XMLReader does not recognize the feature name.
+ * @exception 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)) {
+ namespacePrefixes = 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 SAXNotRecognizedException When the
+ * XMLReader does not recognize the property name.
+ * @exception 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 value The requested value for the property.
+ * @exception SAXNotRecognizedException When the
+ * XMLReader does not recognize the property name.
+ * @exception 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.
+ * @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.
+ * @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.
+ * @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.
+ * @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 input The input source for the top-level of the
+ * XML document.
+ * @exception SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception 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 SAXException Any SAX exception, possibly
+ * wrapping another exception.
+ * @exception 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/java/org/apache/fop/tools/TestConverter.java b/src/java/org/apache/fop/tools/TestConverter.java
new file mode 100644
index 000000000..1f8449043
--- /dev/null
+++ b/src/java/org/apache/fop/tools/TestConverter.java
@@ -0,0 +1,391 @@
+/*
+ * $Id: TestConverter.java,v 1.23 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools;
+
+import org.apache.fop.apps.Driver;
+import org.apache.fop.apps.FOInputHandler;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.InputHandler;
+import org.apache.fop.apps.XSLTInputHandler;
+import org.apache.fop.fo.FOUserAgent;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.XMLReader;
+import org.xml.sax.SAXException;
+
+/**
+ * TestConverter is used to process a set of tests specified in
+ * a testsuite.
+ * This class retrieves the data in the testsuite and uses FOP
+ * to convert the xml and xsl file into either an xml representation
+ * of the area tree or a pdf document.
+ * The area tree can be used for automatic comparisons between different
+ * versions of FOP or the pdf can be view for manual checking and
+ * pdf rendering.
+ *
+ * Modified by Mark Lillywhite mark-fop@inomial.com to use the new Driver
+ * interface.
+ */
+public class TestConverter extends AbstractLogEnabled {
+
+ private boolean failOnly = false;
+ private boolean outputPDF = false;
+ private File destdir;
+ private File compare = null;
+ private String baseDir = "./";
+ private Map differ = new java.util.HashMap();
+
+ /**
+ * This main method can be used to run the test converter from
+ * the command line.
+ * This will take a specified testsuite xml and process all
+ * tests in it.
+ * The command line options are:
+ * -b to set the base directory for where the testsuite and associated files are
+ * -failOnly to process only the tests which are specified as fail in the test results
+ * -pdf to output the result as pdf
+ * @param args command-line arguments
+ */
+ public static void main(String[] args) {
+ if (args == null || args.length == 0) {
+ System.out.println("test suite file name required");
+ }
+ TestConverter tc = new TestConverter();
+ tc.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_ERROR));
+
+ String testFile = null;
+ for (int count = 0; count < args.length; count++) {
+ if (args[count].equals("-failOnly")) {
+ tc.setFailOnly(true);
+ } else if (args[count].equals("-pdf")) {
+ tc.setOutputPDF(true);
+ } else if (args[count].equals("-b")) {
+ tc.setBaseDir(args[count + 1]);
+ } else {
+ testFile = args[count];
+ }
+ }
+ if (testFile == null) {
+ System.out.println("test suite file name required");
+ }
+
+ tc.runTests(testFile, "results", null);
+ }
+
+ /**
+ * Controls whether to generate PDF or XML.
+ * @param pdf If True, PDF is generated, Area Tree XML otherwise.
+ */
+ public void setOutputPDF(boolean pdf) {
+ outputPDF = pdf;
+ }
+
+ /**
+ * Controls whether to process only the tests which are specified as fail
+ * in the test results.
+ * @param fail True if only fail tests should be processed
+ */
+ public void setFailOnly(boolean fail) {
+ failOnly = fail;
+ }
+
+ /**
+ * Sets the base directory.
+ * @param str base directory
+ */
+ public void setBaseDir(String str) {
+ baseDir = str;
+ }
+
+ /**
+ * Run the Tests.
+ * This runs the tests specified in the xml file fname.
+ * The document is read as a dom and each testcase is covered.
+ * @param fname filename of the input file
+ * @param dest destination directory
+ * @param compDir comparison directory
+ * @return Map a Map containing differences
+ */
+ public Map runTests(String fname, String dest, String compDir) {
+ getLogger().debug("running tests in file:" + fname);
+ try {
+ if (compDir != null) {
+ compare = new File(baseDir + "/" + compDir);
+ }
+ destdir = new File(baseDir + "/" + dest);
+ destdir.mkdirs();
+ File f = new File(baseDir + "/" + fname);
+ DocumentBuilderFactory factory =
+ DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = factory.newDocumentBuilder();
+ Document doc = db.parse(f);
+
+ NodeList suitelist = doc.getChildNodes();
+ if (suitelist.getLength() == 0) {
+ return differ;
+ }
+
+ Node testsuite = null;
+ testsuite = doc.getDocumentElement();
+
+ if (testsuite.hasAttributes()) {
+ String profile =
+ testsuite.getAttributes().getNamedItem("profile").getNodeValue();
+ getLogger().debug("testing test suite:" + profile);
+ }
+
+ NodeList testcases = testsuite.getChildNodes();
+ for (int count = 0; count < testcases.getLength(); count++) {
+ Node testcase = testcases.item(count);
+ if (testcase.getNodeName().equals("testcases")) {
+ runTestCase(testcase);
+ }
+ }
+ } catch (Exception e) {
+ getLogger().error("Error while running tests", e);
+ }
+ return differ;
+ }
+
+ /**
+ * Run a test case.
+ * This goes through a test case in the document.
+ * A testcase can contain a test, a result or more test cases.
+ * A test case is handled recursively otherwise the test is run.
+ * @param tcase Test case node to run
+ */
+ protected void runTestCase(Node tcase) {
+ if (tcase.hasAttributes()) {
+ String profile =
+ tcase.getAttributes().getNamedItem("profile").getNodeValue();
+ getLogger().debug("testing profile:" + profile);
+ }
+
+ NodeList cases = tcase.getChildNodes();
+ for (int count = 0; count < cases.getLength(); count++) {
+ Node node = cases.item(count);
+ String nodename = node.getNodeName();
+ if (nodename.equals("testcases")) {
+ runTestCase(node);
+ } else if (nodename.equals("test")) {
+ runTest(tcase, node);
+ } else if (nodename.equals("result")) {
+ //nop
+ }
+
+ }
+
+ }
+
+ /**
+ * Run a particular test.
+ * This runs a test defined by the xml and xsl documents.
+ * If the test has a result specified it is checked.
+ * This creates an XSLTInputHandler to provide the input
+ * for FOP and writes the data out to an XML are tree.
+ * @param testcase Test case to run
+ * @param test Test
+ */
+ protected void runTest(Node testcase, Node test) {
+ String id = test.getAttributes().getNamedItem("id").getNodeValue();
+ Node result = locateResult(testcase, id);
+ boolean pass = false;
+ if (result != null) {
+ String agreement =
+ result.getAttributes().getNamedItem("agreement").getNodeValue();
+ pass = agreement.equals("full");
+ }
+
+ if (pass && failOnly) {
+ return;
+ }
+
+ String xml = test.getAttributes().getNamedItem("xml").getNodeValue();
+ Node xslNode = test.getAttributes().getNamedItem("xsl");
+ String xsl = null;
+ if (xslNode != null) {
+ xsl = xslNode.getNodeValue();
+ }
+ getLogger().debug("converting xml:" + xml + " and xsl:"
+ + xsl + " to area tree");
+
+ try {
+ File xmlFile = new File(baseDir + "/" + xml);
+ String baseURL = null;
+ try {
+ baseURL = xmlFile.getParentFile().toURL().toExternalForm();
+ } catch (Exception e) {
+ getLogger().error("Error setting base directory");
+ }
+
+ InputHandler inputHandler = null;
+ if (xsl == null) {
+ inputHandler = new FOInputHandler(xmlFile);
+ } else {
+ inputHandler = new XSLTInputHandler(xmlFile,
+ new File(baseDir + "/"
+ + xsl));
+ }
+
+ XMLReader parser = inputHandler.getParser();
+ setParserFeatures(parser);
+
+ Driver driver = new Driver();
+ setupLogger(driver, "fop");
+ driver.initialize();
+ FOUserAgent userAgent = new FOUserAgent();
+ userAgent.setBaseURL(baseURL);
+ driver.setUserAgent(userAgent);
+ if (outputPDF) {
+ driver.setRenderer(Driver.RENDER_PDF);
+ } else {
+ driver.setRenderer(Driver.RENDER_XML);
+ }
+
+ Map rendererOptions = new java.util.HashMap();
+ rendererOptions.put("fineDetail", new Boolean(false));
+ rendererOptions.put("consistentOutput", new Boolean(true));
+ driver.getRenderer().setOptions(rendererOptions);
+ driver.getRenderer().setProducer("Testsuite Converter");
+
+ String outname = xmlFile.getName();
+ if (outname.endsWith(".xml")) {
+ outname = outname.substring(0, outname.length() - 4);
+ }
+ driver.setOutputStream(new java.io.BufferedOutputStream(
+ new java.io.FileOutputStream(new File(destdir,
+ outname + (outputPDF ? ".pdf" : ".at.xml")))));
+ getLogger().debug("ddir:" + destdir + " on:" + outname + ".pdf");
+ driver.render(parser, inputHandler.getInputSource());
+
+ // check difference
+ if (compare != null) {
+ File f1 = new File(destdir, outname + ".at.xml");
+ File f2 = new File(compare, outname + ".at.xml");
+ if (!compareFiles(f1, f2)) {
+ differ.put(outname + ".at.xml", new Boolean(pass));
+ }
+ }
+ } catch (Exception e) {
+ getLogger().error("Error while running tests", e);
+ }
+ }
+
+ /**
+ * Compare files.
+ * @param f1 first file
+ * @param f2 second file
+ * @return true if equal
+ */
+ protected boolean compareFiles(File f1, File f2) {
+ if (f1.length() != f2.length()) {
+ return false;
+ }
+ try {
+ InputStream is1 = new java.io.BufferedInputStream(new java.io.FileInputStream(f1));
+ InputStream is2 = new java.io.BufferedInputStream(new java.io.FileInputStream(f2));
+ while (true) {
+ int ch1 = is1.read();
+ int ch2 = is2.read();
+ if (ch1 == ch2) {
+ if (ch1 == -1) {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+ } catch (Exception e) {
+ getLogger().error("Error while comparing files", e);
+ }
+
+ return false;
+ }
+
+ private void setParserFeatures(XMLReader parser) throws FOPException {
+ try {
+ parser.setFeature("http://xml.org/sax/features/namespace-prefixes",
+ true);
+ } catch (SAXException e) {
+ throw new FOPException("Error in setting up parser feature namespace-prefixes\n"
+ + "You need a parser which supports SAX version 2", e);
+ }
+ }
+
+ private Node locateResult(Node testcase, String id) {
+ NodeList cases = testcase.getChildNodes();
+ for (int count = 0; count < cases.getLength(); count++) {
+ Node node = cases.item(count);
+ String nodename = node.getNodeName();
+ if (nodename.equals("result")) {
+ String resultid =
+ node.getAttributes().getNamedItem("id").getNodeValue();
+ if (id.equals(resultid)) {
+ return node;
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/java/org/apache/fop/tools/anttasks/Compare.java b/src/java/org/apache/fop/tools/anttasks/Compare.java
new file mode 100644
index 000000000..ca3ab5182
--- /dev/null
+++ b/src/java/org/apache/fop/tools/anttasks/Compare.java
@@ -0,0 +1,235 @@
+/*
+ * $Id: Compare.java,v 1.5 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools.anttasks;
+
+import java.util.Date;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.apache.tools.ant.BuildException;
+import java.text.DateFormat;
+
+/**
+ * This class is an extension of Ant, a script utility from
+ * http://ant.apache.org.
+ * It provides methods to compare two files.
+ */
+
+public class Compare {
+
+ private static final boolean IDENTICAL_FILES = true;
+ private static final boolean NOTIDENTICAL_FILES = false;
+
+ private String referenceDirectory, testDirectory;
+ private String[] filenameList;
+ private String filenames;
+ private BufferedInputStream oldfileInput;
+ private BufferedInputStream newfileInput;
+
+ /**
+ * Sets directory for test files.
+ * @param testDirectory the test directory
+ */
+ public void setTestDirectory(String testDirectory) {
+ if (!(testDirectory.endsWith("/") | testDirectory.endsWith("\\"))) {
+ testDirectory += File.separator;
+ }
+ this.testDirectory = testDirectory;
+ }
+
+ /**
+ * Sets directory for reference files.
+ * @param referenceDirectory the reference directory
+ */
+ public void setReferenceDirectory(String referenceDirectory) {
+ if (!(referenceDirectory.endsWith("/")
+ | referenceDirectory.endsWith("\\"))) {
+ referenceDirectory += File.separator;
+ }
+ this.referenceDirectory = referenceDirectory;
+ }
+
+ /**
+ * Sets the comma-separated list of files to process.
+ * @param filenames list of files, comma-separated
+ */
+ public void setFilenames(String filenames) {
+ StringTokenizer tokens = new StringTokenizer(filenames, ",");
+ List filenameListTmp = new java.util.ArrayList(20);
+ while (tokens.hasMoreTokens()) {
+ filenameListTmp.add(tokens.nextToken());
+ }
+ filenameList = new String[filenameListTmp.size()];
+ filenameList = (String[])filenameListTmp.toArray(new String[0]);
+ }
+
+ private boolean compareBytes(File oldFile, File newFile) {
+ try {
+ oldfileInput =
+ new BufferedInputStream(new java.io.FileInputStream(oldFile));
+ newfileInput =
+ new BufferedInputStream(new java.io.FileInputStream(newFile));
+ int charactO = 0;
+ int charactN = 0;
+ boolean identical = true;
+
+ while (identical & (charactO != -1)) {
+ if (charactO == charactN) {
+ charactO = oldfileInput.read();
+ charactN = newfileInput.read();
+ } else {
+ return NOTIDENTICAL_FILES;
+ }
+ }
+ return IDENTICAL_FILES;
+ } catch (IOException io) {
+ System.err.println("Task Compare - Error: \n" + io.toString());
+ }
+ return NOTIDENTICAL_FILES;
+ }
+
+ private boolean compareFileSize(File oldFile, File newFile) {
+ if (oldFile.length() != newFile.length()) {
+ return NOTIDENTICAL_FILES;
+ } else {
+ return IDENTICAL_FILES;
+ }
+ } // end: compareBytes
+
+ private boolean filesExist(File oldFile, File newFile) {
+ if (!oldFile.exists()) {
+ System.err.println("Task Compare - ERROR: File "
+ + referenceDirectory + oldFile.getName()
+ + " doesn't exist!");
+ return false;
+ } else if (!newFile.exists()) {
+ System.err.println("Task Compare - ERROR: File " + testDirectory
+ + newFile.getName() + " doesn't exist!");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private void writeHeader(PrintWriter results) {
+ String dateTime = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
+ DateFormat.MEDIUM).format(new Date());
+ results.println("<html><head><title>Test Results</title></head><body>\n");
+ results.println("<h2>Compare Results<br>");
+ results.println("<font size='1'>created " + dateTime
+ + "</font></h2>");
+ results.println("<table cellpadding='10' border='2'><thead>"
+ + "<th align='center'>reference file</th>"
+ + "<th align='center'>test file</th>"
+ + "<th align='center'>identical?</th></thead>");
+
+
+ }
+
+ /**
+ * Main method of task compare
+ * @throws BuildException If the execution fails.
+ */
+ public void execute() throws BuildException {
+ boolean identical = false;
+ File oldFile;
+ File newFile;
+ try {
+ PrintWriter results =
+ new PrintWriter(new java.io.FileWriter("results.html"), true);
+ this.writeHeader(results);
+ for (int i = 0; i < filenameList.length; i++) {
+ oldFile = new File(referenceDirectory + filenameList[i]);
+ newFile = new File(testDirectory + filenameList[i]);
+ if (filesExist(oldFile, newFile)) {
+ identical = compareFileSize(oldFile, newFile);
+ if (identical) {
+ identical = compareBytes(oldFile, newFile);
+ }
+ if (!identical) {
+ System.out.println("Task Compare: \nFiles "
+ + referenceDirectory
+ + oldFile.getName() + " - "
+ + testDirectory
+ + newFile.getName()
+ + " are *not* identical.");
+ results.println("<tr><td><a href='"
+ + referenceDirectory
+ + oldFile.getName() + "'>"
+ + oldFile.getName()
+ + "</a> </td><td> <a href='"
+ + testDirectory + newFile.getName()
+ + "'>" + newFile.getName() + "</a>"
+ + " </td><td><font color='red'>No</font></td></tr>");
+ } else {
+ results.println("<tr><td><a href='"
+ + referenceDirectory
+ + oldFile.getName() + "'>"
+ + oldFile.getName()
+ + "</a> </td><td> <a href='"
+ + testDirectory + newFile.getName()
+ + "'>" + newFile.getName() + "</a>"
+ + " </td><td>Yes</td></tr>");
+ }
+ }
+ }
+ results.println("</table></html>");
+ } catch (IOException ioe) {
+ System.err.println("ERROR: " + ioe);
+ }
+ } // end: execute()
+
+}
+
diff --git a/src/java/org/apache/fop/tools/anttasks/Fop.java b/src/java/org/apache/fop/tools/anttasks/Fop.java
new file mode 100644
index 000000000..2dc3fd933
--- /dev/null
+++ b/src/java/org/apache/fop/tools/anttasks/Fop.java
@@ -0,0 +1,503 @@
+/*
+ * $Id: Fop.java,v 1.24 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools.anttasks;
+
+// Ant
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.GlobPatternMapper;
+
+// SAX
+import org.xml.sax.XMLReader;
+
+// Java
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.util.List;
+
+// FOP
+import org.apache.fop.apps.Starter;
+import org.apache.fop.apps.InputHandler;
+import org.apache.fop.apps.FOInputHandler;
+import org.apache.fop.apps.Driver;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FOUserAgent;
+
+// Avalon
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+
+/**
+ * Wrapper for FOP which allows it to be accessed from within an Ant task.
+ * Accepts the inputs:
+ * <ul>
+ * <li>fofile -> formatting objects file to be transformed</li>
+ * <li>format -> MIME type of the format to generate ex. "application/pdf"</li>
+ * <li>outfile -> output filename</li>
+ * <li>baseDir -> directory to work from</li>
+ * <li>userconfig -> file with user configuration (same as the "-c" command
+ * line option)</li>
+ * <li>messagelevel -> (error | warn | info | verbose | debug) level to output
+ * non-error messages</li>
+ * <li>logFiles -> Controls whether the names of the files that are processed
+ * are logged or not</li>
+ * </ul>
+ */
+public class Fop extends Task {
+
+ private File foFile;
+ private List filesets = new java.util.ArrayList();
+ private File outFile;
+ private File outDir;
+ private String format; //MIME type
+ private File baseDir;
+ private File userConfig;
+ private int messageType = Project.MSG_VERBOSE;
+ private boolean logFiles = true;
+
+ /**
+ * Sets the filename for the userconfig.xml.
+ * @param userConfig Configuration to use
+ */
+ public void setUserconfig(File userConfig) {
+ this.userConfig = userConfig;
+ }
+
+ /**
+ * Returns the file for the userconfig.xml.
+ * @return the userconfig.xml file
+ */
+ public File getUserconfig() {
+ return this.userConfig;
+ }
+
+ /**
+ * Sets the input XSL-FO file.
+ * @param foFile input XSL-FO file
+ */
+ public void setFofile(File foFile) {
+ this.foFile = foFile;
+ }
+
+ /**
+ * Gets the input XSL-FO file.
+ * @return input XSL-FO file
+ */
+ public File getFofile() {
+ return foFile;
+ }
+
+ /**
+ * Adds a set of XSL-FO files (nested fileset attribute).
+ * @param set a fileset
+ */
+ public void addFileset(FileSet set) {
+ filesets.add(set);
+ }
+
+ /**
+ * Returns the current list of filesets.
+ * @return the filesets
+ */
+ public List getFilesets() {
+ return this.filesets;
+ }
+
+ /**
+ * Sets the output file.
+ * @param outFile File to output to
+ */
+ public void setOutfile(File outFile) {
+ this.outFile = outFile;
+ }
+
+ /**
+ * Gets the output file.
+ * @return the output file
+ */
+ public File getOutfile() {
+ return this.outFile;
+ }
+
+ /**
+ * Sets the output directory.
+ * @param outDir Directory to output to
+ */
+ public void setOutdir(File outDir) {
+ this.outDir = outDir;
+ }
+
+ /**
+ * Gets the output directory.
+ * @return the output directory
+ */
+ public File getOutdir() {
+ return this.outDir;
+ }
+
+ /**
+ * Sets output format (MIME type).
+ * @param format the output format
+ */
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ /**
+ * Gets the output format (MIME type).
+ * @return the output format
+ */
+ public String getFormat() {
+ return this.format;
+ }
+
+ /**
+ * Sets the message level to be used while processing.
+ * @param messageLevel (error | warn| info | verbose | debug)
+ */
+ public void setMessagelevel(String messageLevel) {
+ if (messageLevel.equalsIgnoreCase("info")) {
+ messageType = Project.MSG_INFO;
+ } else if (messageLevel.equalsIgnoreCase("verbose")) {
+ messageType = Project.MSG_VERBOSE;
+ } else if (messageLevel.equalsIgnoreCase("debug")) {
+ messageType = Project.MSG_DEBUG;
+ } else if (messageLevel.equalsIgnoreCase("err")
+ || messageLevel.equalsIgnoreCase("error")) {
+ messageType = Project.MSG_ERR;
+ } else if (messageLevel.equalsIgnoreCase("warn")) {
+ messageType = Project.MSG_WARN;
+ } else {
+ log("messagelevel set to unknown value \"" + messageLevel
+ + "\"", Project.MSG_ERR);
+ throw new BuildException("unknown messagelevel");
+ }
+ }
+
+ /**
+ * Returns the message type corresponding to Project.MSG_*
+ * representing the current message level.
+ * @see org.apache.tools.ant.Project
+ */
+ public int getMessageType() {
+ return messageType;
+ }
+
+ /**
+ * Sets the base directory; currently ignored.
+ * @param baseDir File to use as a working directory
+ */
+ public void setBasedir(File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ /**
+ * Gets the base directory.
+ * @return the base directory
+ */
+ public File getBasedir() {
+ return (baseDir != null) ? baseDir : project.resolveFile(".");
+ }
+
+ /**
+ * Controls whether the filenames of the files that are processed are logged
+ * or not.
+ * @param logFiles True if the feature should be enabled
+ */
+ public void setLogFiles(boolean logFiles) {
+ this.logFiles = logFiles;
+ }
+
+ /**
+ * Returns True if the filename of each file processed should be logged.
+ * @return True if the filenames should be logged.
+ */
+ public boolean getLogFiles() {
+ return this.logFiles;
+ }
+
+ /**
+ * @see org.apache.tools.ant.Task#execute()
+ */
+ public void execute() throws BuildException {
+ int logLevel = ConsoleLogger.LEVEL_INFO;
+ switch (getMessageType()) {
+ case Project.MSG_DEBUG : logLevel = ConsoleLogger.LEVEL_DEBUG; break;
+ case Project.MSG_INFO : logLevel = ConsoleLogger.LEVEL_INFO; break;
+ case Project.MSG_WARN : logLevel = ConsoleLogger.LEVEL_WARN; break;
+ case Project.MSG_ERR : logLevel = ConsoleLogger.LEVEL_ERROR; break;
+ case Project.MSG_VERBOSE: logLevel = ConsoleLogger.LEVEL_DEBUG; break;
+ }
+ Logger log = new ConsoleLogger(logLevel);
+ try {
+ Starter starter = new FOPTaskStarter(this);
+ starter.enableLogging(log);
+ starter.run();
+ } catch (FOPException ex) {
+ throw new BuildException(ex);
+ }
+
+ }
+
+}
+
+class FOPTaskStarter extends Starter {
+
+ private Fop task;
+ private String baseURL = null;
+
+ FOPTaskStarter(Fop task) throws FOPException {
+ this.task = task;
+ }
+
+ private int determineRenderer(String format) {
+ if ((format == null)
+ || format.equalsIgnoreCase("application/pdf")
+ || format.equalsIgnoreCase("pdf")) {
+ return Driver.RENDER_PDF;
+ } else if (format.equalsIgnoreCase("application/postscript")
+ || format.equalsIgnoreCase("ps")) {
+ return Driver.RENDER_PS;
+ } else if (format.equalsIgnoreCase("application/vnd.mif")
+ || format.equalsIgnoreCase("mif")) {
+ return Driver.RENDER_MIF;
+ } else if (format.equalsIgnoreCase("application/msword")
+ || format.equalsIgnoreCase("application/rtf")
+ || format.equalsIgnoreCase("rtf")) {
+ return Driver.RENDER_RTF;
+ } else if (format.equalsIgnoreCase("application/vnd.hp-PCL")
+ || format.equalsIgnoreCase("pcl")) {
+ return Driver.RENDER_PCL;
+ } else if (format.equalsIgnoreCase("text/plain")
+ || format.equalsIgnoreCase("txt")) {
+ return Driver.RENDER_TXT;
+ } else if (format.equalsIgnoreCase("text/xml")
+ || format.equalsIgnoreCase("at")
+ || format.equalsIgnoreCase("xml")) {
+ return Driver.RENDER_XML;
+ } else {
+ String err = "Couldn't determine renderer to use: " + format;
+ throw new BuildException(err);
+ }
+ }
+
+ private String determineExtension(int renderer) {
+ switch (renderer) {
+ case Driver.RENDER_PDF:
+ return ".pdf";
+ case Driver.RENDER_PS:
+ return ".ps";
+ case Driver.RENDER_MIF:
+ return ".mif";
+ case Driver.RENDER_RTF:
+ return ".rtf";
+ case Driver.RENDER_PCL:
+ return ".pcl";
+ case Driver.RENDER_TXT:
+ return ".txt";
+ case Driver.RENDER_XML:
+ return ".xml";
+ default:
+ String err = "Unknown renderer: " + renderer;
+ throw new BuildException(err);
+ }
+ }
+
+ private File replaceExtension(File file, String expectedExt,
+ String newExt) {
+ String name = file.getName();
+ if (name.toLowerCase().endsWith(expectedExt)) {
+ name = name.substring(0, name.length() - expectedExt.length());
+ }
+ name = name.concat(newExt);
+ return new File(file.getParentFile(), name);
+ }
+
+ /**
+ * @see org.apache.fop.apps.Starter#run()
+ */
+ public void run() throws FOPException {
+ //Setup configuration
+ if (task.getUserconfig() != null) {
+ /**@todo implement me */
+ }
+
+ //Set base directory
+ if (task.getBasedir() != null) {
+ try {
+ this.baseURL = task.getBasedir().toURL().toExternalForm();
+ } catch (MalformedURLException mfue) {
+ getLogger().error("Error creating base URL from base directory", mfue);
+ }
+ } else {
+ try {
+ if (task.getFofile() != null) {
+ this.baseURL = task.getFofile().getParentFile().toURL().
+ toExternalForm();
+ }
+ } catch (MalformedURLException mfue) {
+ getLogger().error("Error creating base URL from XSL-FO input file", mfue);
+ }
+ }
+
+ task.log("Using base URL: " + baseURL, Project.MSG_DEBUG);
+
+ int rint = determineRenderer(task.getFormat());
+ String newExtension = determineExtension(rint);
+
+ int actioncount = 0;
+
+ // deal with single source file
+ if (task.getFofile() != null) {
+ if (task.getFofile().exists()) {
+ File outf = task.getOutfile();
+ if (outf == null) {
+ throw new BuildException("outfile is required when fofile is used");
+ }
+ if (task.getOutdir() != null) {
+ outf = new File(task.getOutdir(), outf.getName());
+ }
+ render(task.getFofile(), outf, rint);
+ actioncount++;
+ }
+ }
+
+ GlobPatternMapper mapper = new GlobPatternMapper();
+ mapper.setFrom("*.fo");
+ mapper.setTo("*" + newExtension);
+
+ // deal with the filesets
+ for (int i = 0; i < task.getFilesets().size(); i++) {
+ FileSet fs = (FileSet) task.getFilesets().get(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(task.getProject());
+ String[] files = ds.getIncludedFiles();
+
+ for (int j = 0; j < files.length; j++) {
+ File f = new File(fs.getDir(task.getProject()), files[j]);
+
+ File outf = null;
+ if (task.getOutdir() != null && files[j].endsWith(".fo")) {
+ String[] sa = mapper.mapFileName(files[j]);
+ outf = new File(task.getOutdir(), sa[0]);
+ } else {
+ outf = replaceExtension(f, ".fo", newExtension);
+ if (task.getOutdir() != null) {
+ outf = new File(task.getOutdir(), outf.getName());
+ }
+ }
+
+ try {
+ if (this.baseURL == null) {
+ this.baseURL = fs.getDir(task.getProject()).toURL().
+ toExternalForm();
+ }
+
+ } catch (Exception e) {
+ task.log("Error setting base URL", Project.MSG_DEBUG);
+ }
+
+ render(f, outf, rint);
+ actioncount++;
+ }
+ }
+
+ if (actioncount == 0) {
+ task.log("No files processed. No files were selected by the filesets "
+ + "and no fofile was set." , Project.MSG_WARN);
+ }
+ }
+
+ private void render(File foFile, File outFile,
+ int renderer) throws FOPException {
+ InputHandler inputHandler = new FOInputHandler(foFile);
+ XMLReader parser = inputHandler.getParser();
+ setParserFeatures(parser);
+
+ OutputStream out = null;
+ try {
+ out = new java.io.FileOutputStream(outFile);
+ } catch (Exception ex) {
+ throw new BuildException("Failed to open " + outFile, ex);
+ }
+
+ if (task.getLogFiles()) {
+ task.log(foFile + " -> " + outFile, Project.MSG_INFO);
+ }
+
+ try {
+ Driver driver = new Driver();
+ setupLogger(driver);
+ driver.initialize();
+ FOUserAgent userAgent = new FOUserAgent();
+ userAgent.setBaseURL(this.baseURL);
+ userAgent.enableLogging(getLogger());
+ driver.setUserAgent(userAgent);
+ driver.setRenderer(renderer);
+ driver.setOutputStream(out);
+ driver.render(parser, inputHandler.getInputSource());
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ } finally {
+ try {
+ out.close();
+ } catch (IOException ioe) {
+ getLogger().error("Error closing output file", ioe);
+ }
+ }
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/tools/anttasks/RunTest.java b/src/java/org/apache/fop/tools/anttasks/RunTest.java
new file mode 100644
index 000000000..1fa6d00dc
--- /dev/null
+++ b/src/java/org/apache/fop/tools/anttasks/RunTest.java
@@ -0,0 +1,256 @@
+/*
+ * $Id: RunTest.java,v 1.8 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools.anttasks;
+
+// Ant
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+// Java
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URLClassLoader;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * Testing ant task.
+ * This task is used to test FOP as a build target.
+ * This uses the TestConverter (with weak code dependancy) to run the tests
+ * and check the results.
+ */
+public class RunTest extends Task {
+
+ private String basedir;
+ private String testsuite = "";
+ private String referenceJar = "";
+ private String refVersion = "";
+
+ /**
+ * Sets the test suite name.
+ * @param str name of the test suite
+ */
+ public void setTestSuite(String str) {
+ testsuite = str;
+ }
+
+ /**
+ * Sets the base directory.
+ * @param str base directory
+ */
+ public void setBasedir(String str) {
+ basedir = str;
+ }
+
+ /**
+ * Sets the reference directory.
+ * @param str reference directory
+ */
+ public void setReference(String str) {
+ referenceJar = str;
+ }
+
+ /**
+ * Sets the reference version.
+ * @param str reference version
+ */
+ public void setRefVersion(String str) {
+ refVersion = str;
+ }
+
+ /**
+ * This creates the reference output, if required, then tests
+ * the current build.
+ * @see org.apache.tools.ant.Task#execute()
+ */
+ public void execute() throws BuildException {
+ runReference();
+ testNewBuild();
+ }
+
+ /**
+ * Test the current build.
+ * This uses the current jar file (in build/fop.jar) to run the
+ * tests with.
+ * The output is then compared with the reference output.
+ */
+ protected void testNewBuild() {
+ try {
+ ClassLoader loader = new URLClassLoader(new URL[] {
+ new URL("file:build/fop.jar")
+ });
+ Map diff = runConverter(loader, "areatree",
+ "reference/output/");
+ if (diff != null && !diff.isEmpty()) {
+ System.out.println("====================================");
+ System.out.println("The following files differ:");
+ boolean broke = false;
+ for (Iterator keys = diff.keySet().iterator();
+ keys.hasNext();) {
+ Object fname = keys.next();
+ Boolean pass = (Boolean)diff.get(fname);
+ System.out.println("file: " + fname
+ + " - reference success: " + pass);
+ if (pass.booleanValue()) {
+ broke = true;
+ }
+ }
+ if (broke) {
+ throw new BuildException("Working tests have been changed.");
+ }
+ }
+ } catch (MalformedURLException mue) {
+ mue.printStackTrace();
+ }
+ }
+
+ /**
+ * Run the tests for the reference jar file.
+ * This checks that the reference output has not already been
+ * run and then checks the version of the reference jar against
+ * the version required.
+ * The reference output is then created.
+ * @throws BuildException if an error occurs
+ */
+ protected void runReference() throws BuildException {
+ // check not already done
+ File f = new File(basedir + "/reference/output/");
+ // if(f.exists()) {
+ // need to check that files have actually been created.
+ // return;
+ // } else {
+ try {
+ ClassLoader loader = new URLClassLoader(new URL[] {
+ new URL("file:" + referenceJar)
+ });
+ boolean failed = false;
+
+ try {
+ Class cla = Class.forName("org.apache.fop.apps.Options",
+ true, loader);
+ /*Object opts =*/ cla.newInstance();
+ cla = Class.forName("org.apache.fop.apps.Version", true,
+ loader);
+ Method get = cla.getMethod("getVersion", new Class[]{});
+ if (!get.invoke(null, new Object[]{}).equals(refVersion)) {
+ throw new BuildException("Reference jar is not correct version it must be: "
+ + refVersion);
+ }
+ } catch (IllegalAccessException iae) {
+ failed = true;
+ } catch (IllegalArgumentException are) {
+ failed = true;
+ } catch (InvocationTargetException are) {
+ failed = true;
+ } catch (ClassNotFoundException are) {
+ failed = true;
+ } catch (InstantiationException are) {
+ failed = true;
+ } catch (NoSuchMethodException are) {
+ failed = true;
+ }
+ if (failed) {
+ throw new BuildException("Reference jar could not be found in: "
+ + basedir + "/reference/");
+ }
+ f.mkdirs();
+ runConverter(loader, "reference/output/", null);
+ } catch (MalformedURLException mue) {
+ mue.printStackTrace();
+ }
+ // }
+ }
+
+ /**
+ * Run the Converter.
+ * Runs the test converter using the specified class loader.
+ * This loads the TestConverter using the class loader and
+ * then runs the test suite for the current test suite
+ * file in the base directory.
+ * @param loader the class loader to use to run the tests with
+ * @param dest destination directory
+ * @param compDir comparison directory
+ * @return A Map with differences
+ */
+ protected Map runConverter(ClassLoader loader, String dest,
+ String compDir) {
+ String converter = "org.apache.fop.tools.TestConverter";
+
+ Map diff = null;
+ try {
+ Class cla = Class.forName(converter, true, loader);
+ Object tc = cla.newInstance();
+ Method meth;
+
+ meth = cla.getMethod("setBaseDir", new Class[] {
+ String.class
+ });
+ meth.invoke(tc, new Object[] {
+ basedir
+ });
+
+ meth = cla.getMethod("runTests", new Class[] {
+ String.class, String.class, String.class
+ });
+ diff = (Map)meth.invoke(tc, new Object[] {
+ testsuite, dest, compDir
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return diff;
+ }
+
+}
diff --git a/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java b/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java
new file mode 100644
index 000000000..8a15847a1
--- /dev/null
+++ b/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java
@@ -0,0 +1,197 @@
+/*
+ * $Id: SerializeHyphPattern.java,v 1.5 2003/03/07 10:09:30 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools.anttasks;
+
+// Java
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+// Ant
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.DirectoryScanner;
+
+// FOP
+import org.apache.fop.layout.hyphenation.HyphenationTree;
+import org.apache.fop.layout.hyphenation.HyphenationException;
+
+/**
+ * SerializeHyphPattern
+ */
+
+
+public class SerializeHyphPattern extends MatchingTask {
+ private File sourceDir, targetDir;
+ private boolean errorDump = false;
+
+ /**
+ * @see org.apache.tools.ant.Task#execute()
+ */
+ public void execute() throws org.apache.tools.ant.BuildException {
+ DirectoryScanner ds = this.getDirectoryScanner(sourceDir);
+ String[] files = ds.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ processFile(files[i].substring(0, files[i].length() - 4));
+ }
+ } // end execute
+
+
+ /**
+ * Sets the source directory.
+ * @param sourceDir source directory
+ */
+ public void setSourceDir(String sourceDir) {
+ File dir = new File(sourceDir);
+ if (!dir.exists()) {
+ System.err.println("Fatal Error: source directory " + sourceDir
+ + " for hyphenation files doesn't exist.");
+ System.exit(1);
+ }
+ this.sourceDir = dir;
+ }
+
+ /**
+ * Sets the target directory
+ * @param targetDir target directory
+ */
+ public void setTargetDir(String targetDir) {
+ File dir = new File(targetDir);
+ this.targetDir = dir;
+ }
+
+ /**
+ * Controls the amount of error information dumped.
+ * @param errorDump True if more error info should be provided
+ */
+ public void setErrorDump(boolean errorDump) {
+ this.errorDump = errorDump;
+ }
+
+
+ /*
+ * checks whether input or output files exists or the latter is older than input file
+ * and start build if necessary
+ */
+ private void processFile(String filename) {
+ File infile = new File(sourceDir, filename + ".xml");
+ File outfile = new File(targetDir, filename + ".hyp");
+ //long outfileLastModified = outfile.lastModified();
+ boolean startProcess = true;
+
+ startProcess = rebuild(infile, outfile);
+ if (startProcess) {
+ buildPatternFile(infile, outfile);
+ }
+ }
+
+ /*
+ * serializes pattern files
+ */
+ private void buildPatternFile(File infile, File outfile) {
+ System.out.println("Processing " + infile);
+ HyphenationTree hTree = new HyphenationTree();
+ try {
+ hTree.loadPatterns(infile.toString());
+ if (errorDump) {
+ System.out.println("Stats: ");
+ hTree.printStats();
+ }
+ } catch (HyphenationException ex) {
+ System.err.println("Can't load patterns from xml file " + infile
+ + " - Maybe hyphenation.dtd is missing?");
+ if (errorDump) {
+ System.err.println(ex.toString());
+ }
+ }
+ // serialize class
+ try {
+ ObjectOutputStream out = new ObjectOutputStream(
+ new java.io.BufferedOutputStream(
+ new java.io.FileOutputStream(outfile)));
+ out.writeObject(hTree);
+ out.close();
+ } catch (IOException ioe) {
+ System.err.println("Can't write compiled pattern file: "
+ + outfile);
+ System.err.println(ioe);
+ }
+ }
+
+ /**
+ * Checks for existence of output file and compares
+ * dates with input and stylesheet file
+ */
+ private boolean rebuild(File infile, File outfile) {
+ if (outfile.exists()) {
+ // checks whether output file is older than input file
+ if (outfile.lastModified() < infile.lastModified()) {
+ return true;
+ }
+ } else {
+ // if output file does not exist, start process
+ return true;
+ }
+ return false;
+ } // end rebuild
+
+ /*
+ * //quick access for debugging
+ * public static void main (String args[]) {
+ * SerializeHyphPattern ser = new SerializeHyphPattern();
+ * ser.setIncludes("*.xml");
+ * ser.setSourceDir("\\xml-fop\\hyph\\");
+ * ser.setTargetDir("\\xml-fop\\hyph\\");
+ * ser.execute();
+ * }
+ */
+
+
+}
diff --git a/src/java/org/apache/fop/tools/xslt/TraxTransform.java b/src/java/org/apache/fop/tools/xslt/TraxTransform.java
new file mode 100644
index 000000000..c2d227b1a
--- /dev/null
+++ b/src/java/org/apache/fop/tools/xslt/TraxTransform.java
@@ -0,0 +1,194 @@
+/*
+ * $Id: TraxTransform.java,v 1.5 2003/03/07 10:09:31 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools.xslt;
+
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.Map;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+
+import org.w3c.dom.Document;
+
+/**
+ * Handles xslt tranformations via Trax (xalan2)
+ */
+public class TraxTransform {
+
+ /**
+ * Cache of compiled stylesheets (filename, StylesheetRoot)
+ */
+ private static Map stylesheetCache = new java.util.Hashtable();
+
+ /**
+ * Gets a Trax transformer
+ * @param xsltFilename Filename of the XSLT file
+ * @param cache True, if caching of the stylesheet is allowed
+ * @return Transformer the Trax transformer
+ */
+ public static Transformer getTransformer(String xsltFilename,
+ boolean cache) {
+ try {
+ if (cache && stylesheetCache.containsKey(xsltFilename)) {
+ Templates cachedStylesheet =
+ (Templates)stylesheetCache.get(xsltFilename);
+ return cachedStylesheet.newTransformer();
+ }
+
+ Source xslSheet =
+ new javax.xml.transform.stream.StreamSource(xsltFilename);
+
+
+ /*
+ * System.out.println("****************************");
+ * System.out.println("trax compile \nin: " + xsltFilename);
+ * System.out.println("****************************");
+ */
+ TransformerFactory factory = TransformerFactory.newInstance();
+
+ Templates compiledSheet = factory.newTemplates(xslSheet);
+ if (cache) {
+ stylesheetCache.put(xsltFilename, compiledSheet);
+ }
+ return compiledSheet.newTransformer();
+ } catch (TransformerConfigurationException ex) {
+ ex.printStackTrace();
+ }
+ return null;
+
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Filename of the source XML file
+ * @param xslURL Filename of the XSLT filename
+ * @param outputFile Target filename
+ */
+ public static void transform(String xmlSource, String xslURL,
+ String outputFile) {
+ transform(new javax.xml.transform.stream.StreamSource(xmlSource),
+ new javax.xml.transform.stream.StreamSource(xslURL),
+ new javax.xml.transform.stream.StreamResult(outputFile));
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Source DOM Document
+ * @param xslURL Filename of the XSLT filename
+ * @param outputFile Target filename
+ */
+ public static void transform(Document xmlSource, String xslURL,
+ String outputFile) {
+
+ transform(new javax.xml.transform.dom.DOMSource(xmlSource),
+ new javax.xml.transform.stream.StreamSource(xslURL),
+ new javax.xml.transform.stream.StreamResult(outputFile));
+
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Filename of the source XML file
+ * @param xslURL Filename of the XSLT filename
+ * @param output Target Writer instance
+ */
+ public static void transform(String xmlSource, String xslURL,
+ Writer output) {
+ transform(new javax.xml.transform.stream.StreamSource(xmlSource),
+ new javax.xml.transform.stream.StreamSource(xslURL),
+ new javax.xml.transform.stream.StreamResult(output));
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Source DOM Document
+ * @param xsl Filename of the XSLT filename
+ * @param outputDoc Target DOM document
+ */
+ public static void transform(Document xmlSource, InputStream xsl,
+ Document outputDoc) {
+ transform(new javax.xml.transform.dom.DOMSource(xmlSource),
+ new javax.xml.transform.stream.StreamSource(xsl),
+ new javax.xml.transform.dom.DOMResult(outputDoc));
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource XML Source
+ * @param xslSource XSLT Source
+ * @param result Target Result
+ */
+ public static void transform(Source xmlSource, Source xslSource,
+ Result result) {
+ try {
+ Transformer transformer;
+ if (xslSource.getSystemId() == null) {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ transformer = factory.newTransformer(xslSource);
+ } else {
+ transformer = getTransformer(xslSource.getSystemId(), true);
+ }
+ transformer.transform(xmlSource, result);
+ } catch (TransformerConfigurationException ex) {
+ ex.printStackTrace();
+ } catch (TransformerException ex) {
+ ex.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/src/java/org/apache/fop/tools/xslt/XSLTransform.java b/src/java/org/apache/fop/tools/xslt/XSLTransform.java
new file mode 100644
index 000000000..9f76567a9
--- /dev/null
+++ b/src/java/org/apache/fop/tools/xslt/XSLTransform.java
@@ -0,0 +1,215 @@
+/*
+ * $Id: XSLTransform.java,v 1.5 2003/03/07 10:09:31 jeremias Exp $
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "FOP" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation and was originally created by
+ * James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ * Software Foundation, please see <http://www.apache.org/>.
+ */
+package org.apache.fop.tools.xslt;
+
+import java.io.InputStream;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Class for transforming XML using XSLT. Wraps either Trax (JAXP) or Xalan 1.x.
+ */
+public class XSLTransform {
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Filename of the source XML file
+ * @param xslURL Filename of the XSLT filename
+ * @param outputFile Target filename
+ * @throws Exception If the conversion fails
+ */
+ public static void transform(String xmlSource, String xslURL,
+ String outputFile) throws Exception {
+ Class[] argTypes = {
+ String.class, String.class, String.class
+ };
+ Object[] params = {
+ xmlSource, xslURL, outputFile
+ };
+ transform(params, argTypes);
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Source DOM Document
+ * @param xslURL Filename of the XSLT filename
+ * @param outputFile Target filename
+ * @throws Exception If the conversion fails
+ */
+ public static void transform(org.w3c.dom.Document xmlSource,
+ String xslURL,
+ String outputFile) throws Exception {
+ Class[] argTypes = {
+ org.w3c.dom.Document.class, String.class, String.class
+ };
+
+ Object[] params = {
+ xmlSource, xslURL, outputFile
+ };
+ transform(params, argTypes);
+
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Filename of the source XML file
+ * @param xslURL Filename of the XSLT filename
+ * @param outputWriter Target Writer instance
+ * @throws Exception If the conversion fails
+ */
+ public static void transform(String xmlSource, String xslURL,
+ Writer outputWriter) throws Exception {
+ Class[] argTypes = {
+ String.class, String.class, Writer.class
+ };
+ Object[] params = {
+ xmlSource, xslURL, outputWriter
+ };
+ transform(params, argTypes);
+
+ }
+
+ /**
+ * Transforms an XML file using XSLT.
+ * @param xmlSource Source DOM Document
+ * @param xsl Filename of the XSLT filename
+ * @param outputDoc Target DOM document
+ * @throws Exception If the conversion fails
+ */
+ public static void transform(org.w3c.dom.Document xmlSource,
+ InputStream xsl,
+ org.w3c.dom.Document outputDoc) throws Exception {
+ Class[] argTypes = {
+ org.w3c.dom.Document.class, InputStream.class,
+ org.w3c.dom.Document.class
+ };
+ Object[] params = {
+ xmlSource, xsl, outputDoc
+ };
+ transform(params, argTypes);
+
+ }
+
+
+ private static void transform(Object[] args,
+ Class[] argTypes) throws Exception {
+ Class transformer = getTransformClass();
+ if (transformer != null) {
+ Method transformMethod = getTransformMethod(transformer,
+ argTypes);
+ if (transformMethod != null) {
+ try {
+ transformMethod.invoke(null, args);
+ } catch (InvocationTargetException ex) {
+ ex.printStackTrace();
+ }
+ } else {
+ throw new Exception("transform method not found");
+ }
+ } else {
+ throw new Exception("no transformer class found");
+ }
+
+ }
+
+
+ private static Class getTransformClass() {
+ try {
+ // try trax first
+ Class transformer =
+ Class.forName("javax.xml.transform.Transformer");
+ // ok, make sure we have a liaison to trax
+ transformer =
+ Class.forName("org.apache.fop.tools.xslt.TraxTransform");
+ return transformer;
+
+ } catch (ClassNotFoundException ex) {
+ //nop
+ }
+ // otherwise, try regular xalan1
+ try {
+ Class transformer =
+ Class.forName("org.apache.xalan.xslt.XSLTProcessor");
+ // get the liaison
+ transformer =
+ Class.forName("org.apache.fop.tools.xslt.Xalan1Transform");
+ return transformer;
+ } catch (ClassNotFoundException ex) {
+ //nop
+ }
+ return null;
+
+ }
+
+
+ private static Method getTransformMethod(Class c, Class[] argTypes) {
+ // System.out.println("transformer class = "+c);
+
+ try {
+ // Class[] argTypes = new Class[args.length];
+ for (int i = 0; i < argTypes.length; i++) {
+ // argTypes[i] = args[i].getClass();
+ // System.out.println("arg["+i+"] type = "+argTypes[i]);
+
+ }
+
+ Method transformer = c.getMethod("transform", argTypes);
+ return transformer;
+
+ } catch (NoSuchMethodException ex) {
+ ex.printStackTrace();
+
+ }
+ return null;
+ }
+
+}