/*
 *  Simple servlet witth tests of DOM, XPath and XSLT
 *  Copyright (C) 2002 Ludovic MAITRE
 *
 *  This program 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 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */ 
import javax.servlet.*;
import javax.servlet.http.*;

import java.io.*;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;

//import org.apache.xml.utils.TreeWalker;
import org.apache.xml.utils.DOMBuilder;

import org.w3c.dom.*;
import org.w3c.dom.traversal.*;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;

// Imported JAVA API for XML Parsing 1.0 classes,
// Xerces implementation and XPath API
import org.apache.xerces.parsers.*;
import org.apache.xpath.XPathAPI;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

// Imported Serializer classes
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;

/**
 * Apply an XSL Stylesheet to an XML source
 */

public class myTransformer extends HttpServlet
{

    private String xmlFile;
    private String xslFile;
    private String media;

    public void setXmlFile(String xmlFile)
    {
        this.xmlFile = xmlFile;
    }
    public void setXslFile(String xslFile)
    {
        this.xslFile = xslFile;
    }
    public void setMedia(String media)
    {
        this.media = media;
    }
    public String getXmlFile()
    {
        return this.xmlFile;
    }
    public String getXslFile()
    {
        return this.xslFile;
    }
    public String getMedia()
    {
        return this.media;
    }

    private int getNodeDepth(Node n)
    {
        if (n.getParentNode() == null)
        {
            return 1;
        }

        return (1 + getNodeDepth(n.getParentNode()));
    }

    public void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException,
    IOException
    {
        ServletContext cx = getServletContext();
        cx.log("Ouverture de la servlet "+getServletName());
        PrintWriter out = response.getWriter();
        response.setContentType("text/xml");
        //String filename = request.getRequestURI();
        String filename = cx.getRealPath(request.getServletPath());
        this.setXmlFile(filename);
        cx.log("Traitement du fichier "+getXmlFile());

        try
        {
            // Set up a DOM tree to query.
            InputSource is = new InputSource(new FileInputStream(filename));
            if (is == null)
            {
                cx.log("Erreur a l'ouverture de "+filename);
            }
            DocumentBuilderFactory dfactory =
                    DocumentBuilderFactory.newInstance();
            dfactory.setNamespaceAware(true);
            Document doc = dfactory.newDocumentBuilder().parse(is);

            if (!doc.isSupported("Traversal", "2.0"))
            {
                // This cannot happen with the DOMParser...
                throw new ServletException("This DOM Document does not support Traversal");
            }

            out.println("<output>");

            //Write the DOM tree with a treewlaker
            NameNodeFilter nf = new NameNodeFilter();
            TreeWalker baladeDoc =
                    ((DocumentTraversal) doc). createTreeWalker(
                    (Node) doc.getDocumentElement(), 1, nf, true);
            //Iterate on the tree wlaker  and display his element
            Node n = baladeDoc.getRoot();
            while ((n = baladeDoc.nextNode()) != null)
            {
                out.println("<node><name>"+n.getNodeName()+"</name><value>"+n.getNodeValue()+"</value></node>");
            }

            out.println("</output>");
        }
        catch (Exception e)
        {
            cx.log("Exception : "+e);
        }
}
    /** Decide if the node is text, and so must be handled specially */
    static boolean isTextNode(Node n)
    {
        if (n == null)
            return false;
        short nodeType = n.getNodeType();
        return nodeType == Node.CDATA_SECTION_NODE ||
                nodeType == Node.TEXT_NODE;
    }

    //a filter ripped from the Xerces sources
    private class NameNodeFilter implements NodeFilter
    {

        String fName;
        boolean fMatch = true;

        /** The name to compare with the node name. If null, all node names
         *  are successfully matched.
         */
        public void setName(String name)
        {
            this.fName = name;
        }

        /** Return the name to compare with node name. If null, all node names
          *  are successfully matched. */
        public String getName()
        {
            return this.fName;
        }

        /**
          *  Controls whether the node name is accepted when it <b>does</b> match
          *  the setName value, or when it <b>does not</b> match the setName value.
          *  If the setName value is null this match value does not matter, and
          *  all names will match.
          *  If match is true, the node name is accepted when it matches.
          *  If match is false, the node name is accepted when does not match.
          */
        public void setMatch(boolean match)
        {
            this.fMatch = match;
        }

        /** Return match value. */
        public boolean getMatch()
        {
            return this.fMatch;
        }

        /** acceptNode determines if this filter accepts a node name or not. */
        public short acceptNode(Node n)
        {

            if (fName == null || fMatch &&
                    n.getNodeName().equals(fName) || !fMatch &&
                    !n.getNodeName().equals(fName))
                return FILTER_ACCEPT;
            else
                return FILTER_REJECT;
        }
    }

}





