/*
 * $Id$
 * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
 * For details on use and redistribution please refer to the
 * LICENSE file included with these sources.
 */

package org.apache.fop.apps;

import java.lang.reflect.*;


// Imported SAX classes
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

// Imported java.io classes
import java.io.*;

// FOP
import org.apache.fop.tools.xslt.XSLTransform;

/*
add url constructer
*/

/**
 * XSLTInputHandler basically takes an xmlfile and transforms it with an xsltfile
 * and the resulting xsl:fo document is input for Fop.
 */
public class XSLTInputHandler extends InputHandler {

    File xmlfile, xsltfile;
    boolean useOldTransform = false;

    public XSLTInputHandler(File xmlfile, File xsltfile) {
        this.xmlfile = xmlfile;
        this.xsltfile = xsltfile;
    }

    /**
     * overwrites the method of the super class to return the xmlfile
     */
    public InputSource getInputSource() {
        if (useOldTransform) {
            try {
                java.io.Writer writer;
                java.io.Reader reader;
                File tmpFile = null;

                // create a Writer
                // the following is an ugly hack to allow processing of larger files
                // if xml file size is larger than 500 kb write the fo:file to disk
                if ((xmlfile.length()) > 500000) {
                    tmpFile = new File(xmlfile.getName() + ".fo.tmp");
                    writer = new FileWriter(tmpFile);
                } else {
                    writer = new StringWriter();
                }

                XSLTransform.transform(xmlfile.getCanonicalPath(),
                                       xsltfile.getCanonicalPath(), writer);

                writer.flush();
                writer.close();

                if (tmpFile != null) {
                    reader = new FileReader(tmpFile);
                } else {
                    // create a input source containing the xsl:fo file which can be fed to Fop
                    reader = new StringReader(writer.toString());
                }
                return new InputSource(reader);
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
        } else {
            return fileInputSource(xmlfile);
        }

    }

    /**
     * This looks to see if the Trax api is supported and uses that to
     * get an XMLFilter. Otherwise, it falls back to using DOM documents
     *
     */
    public XMLReader getParser() throws FOPException {
        XMLReader result = null;
        try {
            // try trax first
            Class transformer =
                Class.forName("javax.xml.transform.Transformer");
            transformer =
                Class.forName("org.apache.fop.apps.TraxInputHandler");
            Class[] argTypes = {
                File.class, File.class
            };
            Method getFilterMethod = transformer.getMethod("getXMLFilter",
                    argTypes);
            File[] args = {
                xmlfile, xsltfile
            };
            Object obj = getFilterMethod.invoke(null, args);
            if (obj instanceof XMLReader) {
                result = (XMLReader)obj;
            }
        } catch (ClassNotFoundException ex) {
            throw new FOPException(ex);
        } catch (InvocationTargetException ex) {
            throw new FOPException(ex);
        } catch (IllegalAccessException ex) {
            throw new FOPException(ex);
        } catch (NoSuchMethodException ex) {
            throw new FOPException(ex);
        }
        // otherwise, use DOM documents via our XSLTransform tool class old style
        if (result == null) {
            useOldTransform = true;
            result = createParser();
        }
        return result;

    }

}


@@ -762,16 +762,47 @@
 = false;
+%0A    boolean gotParser = false;
 %0A%0A    pu
@@ -1051,24 +1051,193 @@
 tSource() %7B%0A
+        if(!gotParser) %7B%0A            throw new IllegalStateException(%22The method getParser() must be called and the parser used when using XSLTInputHandler%22);%0A        %7D%0A
         if (
@@ -2838,16 +2838,43 @@
 ption %7B%0A
+        gotParser = true;%0A%0A
         

enforce users to call getParser so it can setup the xslt filter