/* PipelineFactory.java --
   Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.pipeline;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.util.StringTokenizer;

import org.xml.sax.*;
import org.xml.sax.ext.*;


/**
 * This provides static factory methods for creating simple event pipelines.
 * These pipelines are specified by strings, suitable for passing on
 * command lines or embedding in element attributes.  For example, one way
 * to write a pipeline that restores namespace syntax, validates (stopping
 * the pipeline on validity errors) and then writes valid data to standard
 * output is this: <pre>
 *      nsfix | validate | write ( stdout )</pre>
 *
 * <p> In this syntax, the tokens are always separated by whitespace, and each
 * stage of the pipeline may optionally have a parameter (which can be a
 * pipeline) in parentheses.  Interior stages are called filters, and the
 * rightmost end of a pipeline is called a terminus.
 *
 * <p> Stages are usually implemented by a single class, which may not be
 * able to act as both a filter and a terminus; but any terminus can be
 * automatically turned into a filter, through use of a {@link TeeConsumer}.
 * The stage identifiers are either class names, or are one of the following
 * short identifiers built into this class.  (Most of these identifiers are
 * no more than aliases for classes.)  The built-in identifiers include:</p>

 <table border="1" cellpadding="3" cellspacing="0">
    <tr bgcolor="#ccccff" class="TableHeadingColor">
        <th align="center" width="5%">Stage</th>
        <th align="center" width="9%">Parameter</th>
        <th align="center" width="1%">Terminus</th>
        <th align="center">Description</th>
    </tr>

    <tr valign="top" align="center">
        <td><a href="../dom/Consumer.html">dom</a></td>
        <td><em>none</em></td>
        <td> yes </td>
        <td align="left"> Applications code can access a DOM Document built
        from the input event stream.  When used as a filter, this buffers
        data up to an <em>endDocument</em> call, and then uses a DOM parser
        to report everything that has been recorded (which can easily be
        less than what was reported to it).  </td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="NSFilter.html">nsfix</a></td>
        <td><em>none</em></td>
        <td>no</td>
        <td align="left">This stage ensures that the XML element and attribute
        names in its output use namespace prefixes and declarations correctly.
        That is, so that they match the "Namespace plus LocalName" naming data
        with which each XML element and attribute is already associated.  </td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="EventFilter.html">null</a></td>
        <td><em>none</em></td>
        <td>yes</td>
        <td align="left">This stage ignores all input event data.</td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="CallFilter.html">server</a></td>
        <td><em>required</em><br> server URL </td>
        <td>no</td>
        <td align="left">Sends its input as XML request to a remote server,
        normally a web application server using the HTTP or HTTPS protocols.
        The output of this stage is the parsed response from that server.</td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="TeeConsumer.html">tee</a></td>
        <td><em>required</em><br> first pipeline</td>
        <td>no</td>
        <td align="left">This sends its events down two paths; its parameter
        is a pipeline descriptor for the first path, and the second path
        is the output of this stage.</td>
    </tr>

    <tr valign="top" align="center">
        <td><a href="ValidationConsumer.html">validate</a></td>
        <td><em>none</em></td>
        <td>yes</td>
        <td align="left">This checks for validity errors, and reports them
        through its error handler.  The input must include declaration events
        and some lexical events.  </td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="WellFormednessFilter.html">wf</a></td>
        <td><em>none</em></td>
        <td>yes</td>
        <td align="left"> This class provides some basic "well formedness"
        tests on the input event stream, and reports a fatal error if any
        of them fail.  One example: start/end calls for elements must match.
        No SAX parser is permitted to produce malformed output, but other
        components can easily do so.</td>
    </tr>
    <tr valign="top" align="center">
        <td>write</td>
        <td><em>required</em><br> "stdout", "stderr", or filename</td>
        <td>yes</td>
        <td align="left"> Writes its input to the specified output, as pretty
        printed XML text encoded using UTF-8.  Input events must be well
        formed and "namespace fixed", else the output won't be XML (or possibly
        namespace) conformant.  The symbolic names represent
        <em>System.out</em> and <em>System.err</em> respectively; names must
        correspond to files which don't yet exist.</td>
    </tr>
    <tr valign="top" align="center">
        <td>xhtml</td>
        <td><em>required</em><br> "stdout", "stderr", or filename</td>
        <td>yes</td>
        <td align="left"> Like <em>write</em> (above), except that XHTML rules
        are followed.  The XHTML 1.0 Transitional document type is declared,
        and only ASCII characters are written (for interoperability).  Other
        characters are written as entity or character references; the text is
        pretty printed.</td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="XIncludeFilter.html">xinclude</a></td>
        <td><em>none</em></td>
        <td>no</td>
        <td align="left">This stage handles XInclude processing.
        This is like entity inclusion, except that the included content
        is declared in-line rather than in the DTD at the beginning of
        a document.
        </td>
    </tr>
    <tr valign="top" align="center">
        <td><a href="XsltFilter.html">xslt</a></td>
        <td><em>required</em><br> XSLT stylesheet URI</td>
        <td>no</td>
        <td align="left">This stage handles XSLT transformation
        according to a stylesheet.
        The implementation of the transformation may not actually
        stream data, although if such an XSLT engine is in use
        then that can happen.
        </td>
    </tr>

 </table>

 * <p> Note that {@link EventFilter#bind} can automatically eliminate
 * some filters by setting SAX2 parser features appropriately.  This means
 * that you can routinely put filters like "nsfix", "validate", or "wf" at the
 * front of a pipeline (for components that need inputs conditioned to match
 * that level of correctness), and know that it won't actually be used unless
 * it's absolutely necessary.
 *
 * @author David Brownell
 */
public class PipelineFactory
{
    /**
     * Creates a simple pipeline according to the description string passed in.
     */
    public static EventConsumer createPipeline (String description)
    throws IOException
    {
        return createPipeline (description, null);
    }

    /**
     * Extends an existing pipeline by prepending the filter pipeline to the
     * specified consumer.  Some pipelines need more customization than can
     * be done through this simplified syntax.  When they are set up with
     * direct API calls, use this method to merge more complex pipeline
     * segments with easily configured ones.
     */
    public static EventConsumer createPipeline (
        String          description,
        EventConsumer   next
    ) throws IOException
    {
        // tokens are (for now) what's separated by whitespace;
        // very easy to parse, but IDs never have spaces.

        StringTokenizer         tokenizer;
        String                  tokens [];

        tokenizer = new StringTokenizer (description);
        tokens = new String [tokenizer.countTokens ()];
        for (int i = 0; i < tokens.length; i++)
            tokens [i] = tokenizer.nextToken ();

        PipelineFactory         factory = new PipelineFactory ();
        Pipeline                pipeline = factory.parsePipeline (tokens, next);

        return pipeline.createPipeline ();
    }


    private PipelineFactory () { /* NYET */ }


    /**
     * Extends an existing pipeline by prepending a pre-tokenized filter
     * pipeline to the specified consumer.  Tokens are class names (or the
     * predefined aliases) left and right parenthesis, and the vertical bar.
     */
    public static EventConsumer createPipeline (
        String          tokens [],
        EventConsumer   next
    ) throws IOException
    {
        PipelineFactory         factory = new PipelineFactory ();
        Pipeline                pipeline = factory.parsePipeline (tokens, next);

        return pipeline.createPipeline ();
    }


    private String              tokens [];
    private int                 index;

    private Pipeline parsePipeline (String toks [], EventConsumer next)
    {
        tokens = toks;
        index = 0;

        Pipeline retval = parsePipeline (next);

        if (index != toks.length)
            throw new ArrayIndexOutOfBoundsException (
                    "extra token: " + tokens [index]);
        return retval;
    }

    // pipeline  ::= stage | stage '|' pipeline
    private Pipeline parsePipeline (EventConsumer next)
    {
        Pipeline        retval = new Pipeline (parseStage ());

        // minimal pipelines:  "stage" and "... | id"
        if (index > (tokens.length - 2)
                || !"|".equals (tokens [index])
                ) {
            retval.next = next;
            return retval;
        }
        index++;
        retval.rest = parsePipeline (next);
        return retval;
    }

    // stage     ::= id    | id '(' pipeline ')'
    private Stage parseStage ()
    {
        Stage           retval = new Stage (tokens [index++]);

        // minimal stages:  "id" and "id ( id )"
        if (index > (tokens.length - 2)
                || !"(".equals (tokens [index]) /*)*/
                )
            return retval;

        index++;
        retval.param = parsePipeline (null);
        if (index >= tokens.length)
            throw new ArrayIndexOutOfBoundsException (
                    "missing right paren");
        if (/*(*/ !")".equals (tokens [index++]))
            throw new ArrayIndexOutOfBoundsException (
                    "required right paren, not: " + tokens [index - 1]);
        return retval;
    }


    //
    // these classes obey the conventions for constructors, so they're
    // only built in to this table of shortnames
    //
    //  - filter (one or two types of arglist)
    //     * last constructor is 'next' element
    //     * optional (first) string parameter
    //
    //  - terminus (one or types of arglist)
    //     * optional (only) string parameter
    //
    // terminus stages are transformed into filters if needed, by
    // creating a "tee".  filter stages aren't turned to terminus
    // stages though; either eliminate such stages, or add some
    // terminus explicitly.
    //
    private static final String builtinStages [][] = {
        { "dom",        "gnu.xml.dom.Consumer" },
        { "nsfix",      "gnu.xml.pipeline.NSFilter" },
        { "null",       "gnu.xml.pipeline.EventFilter" },
        { "server",     "gnu.xml.pipeline.CallFilter" },
        { "tee",        "gnu.xml.pipeline.TeeConsumer" },
        { "validate",   "gnu.xml.pipeline.ValidationConsumer" },
        { "wf",         "gnu.xml.pipeline.WellFormednessFilter" },
        { "xinclude",   "gnu.xml.pipeline.XIncludeFilter" },
        { "xslt",       "gnu.xml.pipeline.XsltFilter" },

// XXX want:  option for validate, to preload external part of a DTD

            //  xhtml, write ... nyet generic-ready
    };

    private static class Stage
    {
        String          id;
        Pipeline        param;

        Stage (String name)
            {  id = name; }

        public String toString ()
        {
            if (param == null)
                return id;
            return id + " ( " + param + " )";
        }

        private void fail (String message)
        throws IOException
        {
            throw new IOException ("in '" + id
                    + "' stage of pipeline, " + message);
        }

        EventConsumer createStage (EventConsumer next)
        throws IOException
        {
            String       name = id;

            // most builtins are just class aliases
            for (int i = 0; i < builtinStages.length; i++) {
                if (id.equals (builtinStages [i][0])) {
                    name = builtinStages [i][1];
                    break;
                }
            }

            // Save output as XML or XHTML text
            if ("write".equals (name) || "xhtml".equals (name)) {
                String          filename;
                boolean         isXhtml = "xhtml".equals (name);
                OutputStream    out = null;
                TextConsumer    consumer;

                if (param == null)
                    fail ("parameter is required");

                filename = param.toString ();
                if ("stdout".equals (filename))
                    out = System.out;
                else if ("stderr".equals (filename))
                    out = System.err;
                else {
                    File f = new File (filename);

/*
                    if (!f.isAbsolute ())
                        fail ("require absolute file paths");
 */
                    if (f.exists ())
                        fail ("file already exists: " + f.getName ());

// XXX this races against the existence test
                    out = new FileOutputStream (f);
                }

                if (!isXhtml)
                    consumer = new TextConsumer (out);
                else
                    consumer = new TextConsumer (
                        new OutputStreamWriter (out, "8859_1"),
                        true);

                consumer.setPrettyPrinting (true);
                if (next == null)
                    return consumer;
                return new TeeConsumer (consumer, next);

            } else {
                //
                // Here go all the builtins that are just aliases for
                // classes, and all stage IDs that started out as such
                // class names.  The following logic relies on several
                // documented conventions for constructor invocation.
                //
                String          msg = null;

                try {
                    Class       klass = Class.forName (name);
                    Class       argTypes [] = null;
                    Constructor constructor = null;
                    boolean     filter = false;
                    Object      params [] = null;
                    Object      obj = null;

                    // do we need a filter stage?
                    if (next != null) {
                        // "next" consumer is always passed, with
                        // or without the optional string param
                        if (param == null) {
                            argTypes = new Class [1];
                            argTypes [0] = EventConsumer.class;

                            params = new Object [1];
                            params [0] = next;

                            msg = "no-param filter";
                        } else {
                            argTypes = new Class [2];
                            argTypes [0] = String.class;
                            argTypes [1] = EventConsumer.class;

                            params = new Object [2];
                            params [0] = param.toString ();
                            params [1] = next;

                            msg = "one-param filter";
                        }


                        try {
                            constructor = klass.getConstructor (argTypes);
                        } catch (NoSuchMethodException e) {
                            // try creating a filter from a
                            // terminus and a tee
                            filter = true;
                            msg += " built from ";
                        }
                    }

                    // build from a terminus stage, with or
                    // without the optional string param
                    if (constructor == null) {
                        String  tmp;

                        if (param == null) {
                            argTypes = new Class [0];
                            params = new Object [0];

                            tmp = "no-param terminus";
                        } else {
                            argTypes = new Class [1];
                            argTypes [0] = String.class;

                            params = new Object [1];
                            params [0] = param.toString ();

                            tmp = "one-param terminus";
                        }
                        if (msg == null)
                            msg = tmp;
                        else
                            msg += tmp;
                        constructor = klass.getConstructor (argTypes);
                            // NOT creating terminus by dead-ending
                            // filters ... users should think about
                            // that one, something's likely wrong
                    }

                    obj = constructor.newInstance (params);

                    // return EventConsumers directly, perhaps after
                    // turning them into a filter
                    if (obj instanceof EventConsumer) {
                        if (filter)
                            return new TeeConsumer ((EventConsumer) obj, next);
                        return (EventConsumer) obj;
                    }

                    // if it's not a handler, it's an error
                    // we can wrap handlers in a filter
                    EventFilter         retval = new EventFilter ();
                    boolean             updated = false;

                    if (obj instanceof ContentHandler) {
                        retval.setContentHandler ((ContentHandler) obj);
                        updated = true;
                    }
                    if (obj instanceof DTDHandler) {
                        retval.setDTDHandler ((DTDHandler) obj);
                        updated = true;
                    }
                    if (obj instanceof LexicalHandler) {
                        retval.setProperty (
                            EventFilter.PROPERTY_URI + "lexical-handler",
                            obj);
                        updated = true;
                    }
                    if (obj instanceof DeclHandler) {
                        retval.setProperty (
                            EventFilter.PROPERTY_URI + "declaration-handler",
                            obj);
                        updated = true;
                    }

                    if (!updated)
                        fail ("class is neither Consumer nor Handler");

                    if (filter)
                        return new TeeConsumer (retval, next);
                    return retval;

                } catch (IOException e) {
                    throw e;

                } catch (NoSuchMethodException e) {
                    fail (name + " constructor missing -- " + msg);

                } catch (ClassNotFoundException e) {
                    fail (name + " class not found");

                } catch (Exception e) {
                    // e.printStackTrace ();
                    fail ("stage not available: " + e.getMessage ());
                }
            }
            // NOTREACHED
            return null;
        }
    }

    private static class Pipeline
    {
        Stage           stage;

        // rest may be null
        Pipeline        rest;
        EventConsumer   next;

        Pipeline (Stage s)
            { stage = s; }

        public String toString ()
        {
            if (rest == null && next == null)
                return stage.toString ();
            if (rest != null)
                return stage + " | " + rest;
            throw new IllegalArgumentException ("next");
        }

        EventConsumer createPipeline ()
        throws IOException
        {
            if (next == null) {
                if (rest == null)
                    next = stage.createStage (null);
                else
                    next = stage.createStage (rest.createPipeline ());
            }
            return next;
        }
    }

/*
    public static void main (String argv [])
    {
        try {
            // three basic terminus cases
            createPipeline ("null");
            createPipeline ("validate");
            createPipeline ("write ( stdout )");

            // four basic filters
            createPipeline ("nsfix | write ( stderr )");
            createPipeline ("wf | null");
            createPipeline ("null | null");
            createPipeline (
"call ( http://www.example.com/services/xml-1a ) | xhtml ( stdout )");

            // tee junctions
            createPipeline ("tee ( validate ) | write ( stdout )");
            createPipeline ("tee ( nsfix | write ( stdout ) ) | validate");

            // longer pipeline
            createPipeline ("nsfix | tee ( validate ) | write ( stdout )");
            createPipeline (
                "null | wf | nsfix | tee ( validate ) | write ( stdout )");

            // try some parsing error cases
            try {
                createPipeline ("null (");              // extra token '('
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }

            try {
                createPipeline ("nsfix |");             // extra token '|'
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }

            try {
                createPipeline ("xhtml ( foo");         // missing right paren
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }

            try {
                createPipeline ("xhtml ( foo bar");     // required right paren
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }

            try {
                createPipeline ("tee ( nsfix | validate");// missing right paren
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }

            // try some construction error cases

            try {
                createPipeline ("call");                // missing param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("call ( foobar )");     // broken param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("nsfix ( foobar )");    // illegal param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("null ( foobar )");     // illegal param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("wf ( foobar )");       // illegal param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("xhtml ( foobar.html )");
                new File ("foobar.html").delete ();
                // now supported
            } catch (Exception e) {
                System.err.println ("** err: " + e.getMessage ()); }
            try {
                createPipeline ("xhtml");               // missing param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("write ( stdout ) | null");     // nonterminal
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("validate | null");
                // now supported
            } catch (Exception e) {
                System.err.println ("** err: " + e.getMessage ()); }
            try {
                createPipeline ("validate ( foo )");    // illegal param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                createPipeline ("tee");                 // missing param
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }
            try {
                    // only builtins so far
                createPipeline ("com.example.xml.FilterClass");
                System.err.println ("** didn't report error");
            } catch (Exception e) {
                System.err.println ("== err: " + e.getMessage ()); }

        } catch (Exception e) {
            e.printStackTrace ();
        }
    }
/**/

}
