/*
 * The Apache Software License, Version 1.1  
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, 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 "Xalan" 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 (INCLUDING, 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 based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xalan.xslt;

import java.util.TooManyListenersException;
import java.util.Vector;

import org.apache.xalan.xpath.XObject;
import org.apache.xalan.xpath.XNodeSet;
import org.apache.xalan.xpath.XBoolean;
import org.apache.xalan.xpath.XNumber;
import org.apache.xalan.xpath.XNull;
import org.apache.xalan.xpath.XString;
import org.apache.xalan.xpath.xml.XMLParserLiaison;
import org.apache.xalan.xpath.xml.ProblemListener;

import org.apache.xalan.templates.Stylesheet;
//import org.apache.xalan.templates.StylesheetRoot;
//import org.apache.xalan.xslt.StylesheetSpec;
import org.apache.xalan.trace.*;

import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.xml.sax.DocumentHandler;
import org.xml.sax.SAXException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import org.apache.xml.serialize.OutputFormat;
import org.xml.sax.ext.LexicalHandler;

/**
 * <meta name="usage" content="general"/>
 * The transformation processor -- use {@link org.apache.xalan.xslt.XSLTProcessorFactory} to instantiate an implementation of this interface.
 * It's the responsibility of the implementation (XSLTEngineImpl),
 * collaborating with a XMLParserLiaison, the DOM,
 * and the XPath engine, to transform a source tree
 * of nodes into a result tree according to instructions
 * and templates specified by a stylesheet tree.
 * Use the <code>process(...)</code> are the primary
 * public entry points.
 *
 * Look at the Process class main() method for
 * for an advanced usage example.
 *
 * <p>If you reuse the processor instance, you should call reset() between transformations.</p>
 */
public interface XSLTProcessor extends DocumentHandler, LexicalHandler
{
  /**
   * Use the XSL stylesheet to transform the XML input, placing the result in the result tree.
   * @param xmlSource  The XML input to be transformed.
   * @param xslStylesheet  The XSL stylesheet to be used for the transformation.  May be null if XML input
   * has an XSL stylesheet PI.
   * @param resultTree The tree where the result of the transformation is placed.
   * @exception XSLProcessorException thrown if the active ProblemListener and XMLParserLiaison decide
   * the error condition is severe enough to halt processing.
   */
  public void process( XSLTInputSource xmlSource,
                       XSLTInputSource xslStylesheet,
                       XSLTResultTarget resultTree)
    throws SAXException;

  /**
   * Compile the XSL stylesheet represented by an XSLTInputSource object into an internal representation,
   * and use it to set the XSLTProcessor Stylesheet property.
   * This operation is required if the XSLTProcessor is to function as a
   * SAX DocumentHandler.
   * If the Stylesheet property has already been set to non-null, this operation
   * calls reset() before a transformation is performed.
   *
   * @param stylesheetSource  The XSL stylesheet.
   * @return The compiled stylesheet object.
   * @exception XSLProcessorException thrown if the active ProblemListener and XMLParserLiaison decide
   * the error condition is severe enough to halt processing.
   */
  public StylesheetRoot processStylesheet(XSLTInputSource stylesheetSource)
    throws SAXException;

  /**
   * Given a URL to (or file name of) an XSL stylesheet,
   * Compile the stylesheet into an internal representation, and use it to
   * set the XSLTProcessor Stylesheet property.
   * This operation is required if the XSLTProcessor is to function as a
   * SAX DocumentHandler.
   * If the Stylesheet property has already been set to non-null, this operation
   * calls reset() before a transformation is performed.
   *
   * @param xsldocURLString  The URL to the XSL stylesheet.
   * @return The compiled stylesheet object.
   * @exception XSLProcessorException thrown if the active ProblemListener and XMLParserLiaison decide
   * the error condition is severe enough to halt processing.
   */
  public StylesheetRoot processStylesheet(String xsldocURLString)
    throws SAXException;

  /**
   * Set the output stream. Required when the XSLTProcessor is being used
   * as a SAX DocumentHandler.
   */
  public void setOutputStream(java.io.OutputStream os);

  /**
   * Reset the XSLTProcessor state.  Must be used after a process() call
   * if the XSLTProcessor instance is to be used again.
   */
  public void reset();

  /**
   * Get the DOM Node from the XSLTInputSource object. Returns null if the XSLTInputSource
   * object does not contain a Node (it may, for example, contain an input stream).
   */
  public Node getSourceTreeFromInput(XSLTInputSource inputSource)
    throws org.xml.sax.SAXException;

  /**
   * Use a compiled stylesheet to set the Stylesheet property for this processor.
   * When this property is set, the process method uses this stylesheet rather than
   * looking for a stylesheet PI if the stylesheet parameter is null.  Also required
   * if you are going to use the XSLTProcessor as a SAX DocumentHandler.
   */
  public void setStylesheet(StylesheetRoot stylesheetRoot);

  /**
   * Get the current Stylesheet setting for this XSLTProcessor.
   */
  public StylesheetRoot getStylesheet();

  /**
   * Get the XMLParserLiaison that this processor uses.
   */
  public XMLParserLiaison getXMLProcessorLiaison();

  /**
   * Get the preferred stylesheet for the XSLTInputSource XML document,
   * as identified by the xml-stylesheet PI, and matching the media and
   * charset criteria. See <a href="http://www.w3.org/TR/xml-stylesheet/">
   * Associating Style Sheets with XML documents</a>.
   * Does not yet handle the LINK REL="stylesheet" syntax.
   *
   * @param media The media attribute to be matched.  May be null, in which
   *              case the prefered stylesheet will be used (i.e., alternate = no).
   * @param title The value of the title attribute to match.  May be null.
   * @param charset The value of the charset attribute to match.  May be null.
   * @returns StylesheetSpec extends XSLTInputSource extends SAX InputSource; the return value
   * can be passed to the processStylesheet method.
   */
  public StylesheetSpec getAssociatedStylesheet(XSLTInputSource source,
                                                      String media,
                                                      String charset)
    throws SAXException;

  /**
   * Get a list of stylesheet specifications for the XSLTInputSource XML document,
   * as identified by the xml-stylesheet PI, and matching the media and
   * charset criteria. See <a href="http://www.w3.org/TR/xml-stylesheet/">
   * Associating Style Sheets with XML documents</a>.
   * Does not yet handle the LINK REL="stylesheet" syntax.
   *
   * @param media The media attribute to be matched.  May be null, in which
   *              case the prefered stylesheet will be used (i.e., alternate = no).
   * @param title The value of the title attribute to match.  May be null.
   * @param charset The value of the charset attribute to match.  May be null.
   * @returns list of StylesheetSpecs (extend XSLTInputSources extend SAX InputSources; a
   * list member may be passsed to the processStylesheet method.
   */
  public Vector getAssociatedStylesheets(XSLTInputSource source,
                                                      String media,
                                                      String charset)
    throws SAXException;


  /**
   * Convenience function to create an XString.
   * @param s A valid string.
   * @return An XString object.
   */
  public XString createXString(String s);

  /**
   * Convenience function to create an XObject.
   * @param o Any java object.
   * @return An XObject object.
   */
  public XObject createXObject(Object o);

  /**
   * Convenience function to create an XNumber.
   * @param d Any double number.
   * @return An XNumber object.
   */
  public XNumber createXNumber(double d);

  /**
   * Convenience function to create an XBoolean.
   * @param b boolean value.
   * @return An XBoolean object.
   */
  public XBoolean createXBoolean(boolean b);

  /**
   * Convenience function to create an XNodeSet.
   * @param nl A NodeList object.
   * @return An XNodeSet object.
   */
  public XNodeSet createXNodeSet(NodeList nl);

  /**
   * Convenience function to create an XNodeSet from a node.
   * @param n A DOM node.
   * @return An XNodeSet object.
   */
  public XNodeSet createXNodeSet(Node n);

  /**
   * Convenience function to create an XNull.
   * @return An XNull object.
   */
  public XNull createXNull();

  /**
   * Submit a top-level stylesheet parameter.  This value can
   * be evaluated in the stylesheet via xsl:param-variable.
   * @param key The name of the param.
   * @param value An XObject that will be used.
   */
  public void setStylesheetParam(String key, XObject value);

  /**
   * Set a top-level stylesheet parameter.  This value can
   * be evaluated via xsl:param-variable.  Note that the value
   * passed is an expression, and not a string.  This means that
   * setStylesheetParam("foo", "hello"); will look for the
   * element "hello".  If you want to pass a string, you'll
   * need to put quotes around it:
   * setStylesheetParam("foo", "'hello'"); will look for the
   * @param key The name of the param.
   * @param expression An expression that will be evaluated.
   */
  public void setStylesheetParam(String key, String expression);

  /**
   * Get the current FormatterListener (SAX DocumentHandler), or null if none has been set.
   */
  public DocumentHandler getFormatterListener();

  /**
   * Set the FormatterListener (the SAX DocumentHandler).
   */
  public void setFormatterListener(DocumentHandler flistener);

  /**
   * Get the current SAX DocumentHandler (the same object as the FormatterListener), or null if none has been set.
   */
  public DocumentHandler getDocumentHandler();

  /**
   * Set the current SAX DocumentHandler (the same
   * object as the FormatterListener).
   */
  public void setDocumentHandler(DocumentHandler listener);

  /**
   * Add a trace listener for the purposes of debugging and diagnosis.
   * @param tl Trace listener to be added.
   */
  public void addTraceListener(TraceListener tl)
    throws TooManyListenersException;

  /**
   * If set to true, template calls are traced.
   */
  public void setTraceTemplates(boolean b);

  /**
   * If set to true, selection events are traced.
   */
  public void setTraceSelect(boolean b);

  /**
   * If set to true (the default is false), as template children are being constructed, debug diagnostics
   * are written to the m_diagnosticsPrintWriter
   * stream.
   */
  public void setTraceTemplateChildren(boolean b);

  /**
   * If set to true (the default), pattern conflict warnings are not printed to the diagnostics stream.
   * @param b true if conflict warnings should be suppressed.
   */
  public void setQuietConflictWarnings(boolean b);

  /**
   * Remove a trace listener.
   * @param tl Trace listener to be removed.
   */
  public void removeTraceListener(TraceListener tl);

  /**
   * If set, diagnostics will be
   * written to the m_diagnosticsPrintWriter stream. If
   * null, diagnostics are turned off. This convenience method calls
   * {@link #setDiagnosticsOutput(java.io.PrintWriter)}.
   */
  public void setDiagnosticsOutput(java.io.OutputStream out);

  /**
   * If set, diagnostics will be
   * written to the m_diagnosticsPrintWriter stream. If
   * null, diagnostics are turned off.
   */
  public void setDiagnosticsOutput(java.io.PrintWriter pw);

  /**
   * Set the problem listener property.
   * The XSL class can have a single listener to be informed
   * of errors and warnings. The problem listener normally controls whether an exception
   * is thrown or not (or the problem listeners can throw its own RuntimeException).
   * @param l A ProblemListener interface.
   */
  public void setProblemListener(ProblemListener l);

  /**
   * Get the problem listener property.
   * The XSL class can have a single listener to be informed
   * of errors and warnings. The problem listener normally controls whether an exception
   * is thrown or not (or the problem listener can throw its own RuntimeException).
   * @return A ProblemListener interface.
   */
  public ProblemListener getProblemListener();

}
