/* DomLSParser.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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.dom.ls;

import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMStringList;
import org.w3c.dom.Node;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSException;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.LSParserFilter;
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.SAXParseException;
import org.xml.sax.XMLReader;
import gnu.xml.dom.DomDocument;
import gnu.xml.dom.DomDOMException;

/**
 * Parser implementation for GNU DOM.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class DomLSParser
  implements LSParser, DOMConfiguration, DOMStringList, ErrorHandler
{

  private static final List SUPPORTED_PARAMETERS
    = Arrays.asList(new String[] { "cdata-sections",
                    "comments",
                    "element-content-whitespace",
                    "namespaces",
                    "expand-entity-references",
                    "coalescing",
                    "validating",
                    "xinclude-aware",
                    "entity-resolver",
                    "error-handler" });

  private LSParserFilter filter;
  private final boolean async;
  private String schemaType;
  private SAXEventSink eventSink;
  private SAXParserFactory factory;
  private XMLReader reader;

  private boolean namespaceAware = true;
  private boolean ignoreWhitespace;
  private boolean expandEntityReferences;
  private boolean ignoreComments;
  private boolean coalescing;
  private boolean validating;
  private boolean xIncludeAware;
  private EntityResolver entityResolver;
  private ErrorHandler errorHandler;

  public DomLSParser(short mode, String schemaType)
    throws DOMException
  {
    switch (mode)
      {
      case DOMImplementationLS.MODE_ASYNCHRONOUS:
        async = true;
        break;
      case DOMImplementationLS.MODE_SYNCHRONOUS:
        async = false;
        break;
      default:
        throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
      }
    // TODO schemaType
    this.schemaType = schemaType;
    factory = SAXParserFactory.newInstance();
  }

  // -- LSParser --
  
  public DOMConfiguration getDomConfig()
  {
    return this;
  }
  
  public LSParserFilter getFilter()
  {
    return filter;
  }

  public void setFilter(LSParserFilter filter)
  {
    this.filter = filter;
  }

  public boolean getAsync()
  {
    return async;
  }

  public boolean getBusy()
  {
    return eventSink != null;
  }

  public Document parse(LSInput input)
    throws DOMException, LSException
  {
    if (async)
      {
        return doParse(input);
      }
    else
      {
        synchronized (this)
          {
            return doParse(input);
          }
      }
  }

  public Document parseURI(String uri)
    throws DOMException, LSException
  {
    LSInput input = new DomLSInput();
    input.setSystemId(uri);
    return parse(input);
  }

  public Node parseWithContext(LSInput input, Node context, short action)
    throws DOMException, LSException
  {
    Document doc = (context.getNodeType() == Node.DOCUMENT_NODE) ?
      (Document) context : context.getOwnerDocument();
    input.setBaseURI(doc.getDocumentURI());
    // TODO use namespaces defined on context node
    Document ret = parse(input);
    Node root = ret.getDocumentElement();
    root = doc.adoptNode(root);
    switch (action)
      {
      case ACTION_APPEND_AS_CHILDREN:
        context.appendChild(root);
        break;
      case ACTION_REPLACE_CHILDREN:
        Node c1 = context.getFirstChild();
        while (c1 != null)
          {
            Node next = c1.getNextSibling();
            context.removeChild(c1);
            c1 = next;
          }
        context.appendChild(root);
        break;
      case ACTION_INSERT_BEFORE:
        Node p1 = context.getParentNode();
        p1.insertBefore(root, context);
        break;
      case ACTION_INSERT_AFTER:
        Node p2 = context.getParentNode();
        Node r1 = context.getNextSibling();
        if (r1 == null)
          {
            p2.appendChild(root);
          }
        else
          {
            p2.insertBefore(root, r1);
          }
        break;
      case ACTION_REPLACE:
        Node p3 = context.getParentNode();
        Node r2 = context.getNextSibling();
        p3.removeChild(context);
        if (r2 == null)
          {
            p3.appendChild(root);
          }
        else
          {
            p3.insertBefore(root, r2);
          }
        break;
      }
    return root;
  }

  public void abort()
  {
    if (eventSink != null)
      {
        eventSink.interrupt();
      }
  }

  private Document doParse(LSInput input)
    throws DOMException, LSException
  {
    // create event sink
    if (eventSink != null)
      {
        throw new LSException(LSException.PARSE_ERR, "parse in progress");
      }
    InputSource source = getInputSource(input);
    eventSink = (filter == null) ? new SAXEventSink() :
      new FilteredSAXEventSink(filter);
    // configure sink
    eventSink.namespaceAware = namespaceAware;
    eventSink.ignoreWhitespace = ignoreWhitespace;
    eventSink.expandEntityReferences = expandEntityReferences;
    eventSink.ignoreComments = ignoreComments;
    eventSink.coalescing = coalescing;
    // get and configure reader
    XMLReader reader = getXMLReader();
    try
      {
        reader.setContentHandler(eventSink);
        reader.setDTDHandler(eventSink);
        reader.setProperty("http://xml.org/sax/properties/lexical-handler",
                           eventSink);
        reader.setProperty("http://xml.org/sax/properties/declaration-handler",
                           eventSink);
        reader.setFeature("http://xml.org/sax/features/namespaces",
                          namespaceAware);
        reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
                          true);
        reader.setFeature("http://xml.org/sax/features/validation",
                          validating);
        try
          {
            reader.setFeature("http://xml.org/sax/features/use-attributes2",
                              true);
          }
        catch (SAXNotRecognizedException e)
          {
            // ignore
          }
        try
          {
            reader.setFeature("http://xml.org/sax/features/external-general-entities",
                              true);
          }
        catch (SAXNotRecognizedException e)
          {
            // ignore
          }
        reader.setEntityResolver(entityResolver);
        reader.setErrorHandler(errorHandler);
        // parse
        reader.parse(source);
      }
    catch (DOMException e)
      {
        reader = null;
        eventSink = null;
        throw e;
      }
    catch (SAXException e)
      {
        reader = null;
        eventSink = null;
        throw new DomLSException(LSException.PARSE_ERR, e);
      }
    catch (IOException e)
      {
        reader = null;
        eventSink = null;
        throw new DomLSException(LSException.PARSE_ERR, e);
      }
    // return document
    Document ret = eventSink.doc;
    String systemId = input.getSystemId();
    if (systemId != null && ret instanceof DomDocument)
      {
        ((DomDocument) ret).setDocumentURI(systemId);
      }
    eventSink = null;
    return ret;
  }

  private XMLReader getXMLReader()
    throws LSException
  {
    if (reader == null)
      {
        factory.setNamespaceAware(namespaceAware);
        factory.setValidating(validating);
        factory.setXIncludeAware(xIncludeAware);
        try
          {
            SAXParser parser = factory.newSAXParser();
            reader = parser.getXMLReader();
          }
        catch (ParserConfigurationException e)
          {
            throw new DomLSException(LSException.PARSE_ERR, e);
          }
        catch (SAXException e)
          {
            throw new DomLSException(LSException.PARSE_ERR, e);
          }
      }
    return reader;
  }

  private InputSource getInputSource(LSInput input)
    throws LSException
  {
    InputSource source = null;
    String systemId = input.getSystemId();
    InputStream in = input.getByteStream();
    if (in != null)
      {
        source = new InputSource(in);
        source.setSystemId(systemId);
      }
    if (source == null && entityResolver != null)
      {
        String publicId = input.getPublicId();
        try
          {
            source = entityResolver.resolveEntity(publicId, systemId);
          }
        catch (SAXException e)
          {
            throw new DomLSException(LSException.PARSE_ERR, e);
          } 
        catch (IOException e)
          {
            throw new DomLSException(LSException.PARSE_ERR, e);
          } 
      }
    if (source == null)
      {
        URL url = null;
        String base = input.getBaseURI();
        try
          {
            try
              {
                URL baseURL = (base == null) ? null : new URL(base);
                url = (baseURL == null) ? new URL(systemId) :
                  new URL(baseURL, systemId);
              }
            catch (MalformedURLException e)
              {
                File baseFile = (base == null) ? null : new File(base);
                url = (baseFile == null) ? new File(systemId).toURL() :
                  new File(baseFile, systemId).toURL();
              }
            in = url.openStream();
            systemId = url.toString();
            source = new InputSource(in);
            source.setSystemId(systemId);
          }
        catch (IOException e)
          {
            throw new DomLSException(LSException.PARSE_ERR, e);
          }
      }
    return source;
  }

  // -- DOMConfiguration --

  public void setParameter(String name, Object value)
    throws DOMException
  {
    name = name.toLowerCase();
    if ("cdata-sections".equals(name))
      {
        coalescing = !((Boolean) value).booleanValue();
      }
    else if ("comments".equals(name))
      {
        ignoreComments = !((Boolean) value).booleanValue();
      }
    else if ("element-content-whitespace".equals(name))
      {
        ignoreWhitespace = !((Boolean) value).booleanValue();
      }
    else if ("namespaces".equals(name))
      {
        namespaceAware = ((Boolean) value).booleanValue();
      }
    else if ("expand-entity-references".equals(name))
      {
        expandEntityReferences = ((Boolean) value).booleanValue();
      }
    else if ("coalescing".equals(name))
      {
        coalescing = ((Boolean) value).booleanValue();
      }
    else if ("validating".equals(name))
      {
        validating = ((Boolean) value).booleanValue();
      }
    else if ("xinclude-aware".equals(name))
      {
        xIncludeAware = ((Boolean) value).booleanValue();
      }
    else if ("entity-resolver".equals(name))
      {
        entityResolver = (EntityResolver) value;
      }
    else if ("error-handler".equals(name))
      {
        errorHandler = (ErrorHandler) value;
      }
    else
      {
        throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
      }
    // invalidate reader, a new one will be created
    reader = null;
  }

  public Object getParameter(String name)
    throws DOMException
  {
    name = name.toLowerCase();
    if ("cdata-sections".equals(name))
      {
        return coalescing ? Boolean.FALSE : Boolean.TRUE;
      }
    else if ("comments".equals(name))
      {
        return ignoreComments ? Boolean.FALSE : Boolean.TRUE;
      }
    else if ("element-content-whitespace".equals(name))
      {
        return ignoreWhitespace ? Boolean.FALSE : Boolean.TRUE;
      }
    else if ("namespaces".equals(name))
      {
        return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("expand-entity-references".equals(name))
      {
        return expandEntityReferences ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("coalescing".equals(name))
      {
        return coalescing ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("validating".equals(name))
      {
        return validating ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("xinclude-aware".equals(name))
      {
        return xIncludeAware ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("entity-resolver".equals(name))
      {
        return entityResolver;
      }
    else if ("error-handler".equals(name))
      {
        return errorHandler;
      }
    else
      {
        throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
      }
  }

  public boolean canSetParameter(String name, Object value)
  {
    return contains(name);
  }

  public DOMStringList getParameterNames()
  {
    return this;
  }

  // -- DOMStringList --

  public String item(int i)
  {
    return (String) SUPPORTED_PARAMETERS.get(i);
  }

  public int getLength()
  {
    return SUPPORTED_PARAMETERS.size();
  }

  public boolean contains(String str)
  {
    return SUPPORTED_PARAMETERS.contains(str);
  }

  // -- ErrorHandler --

  public void warning(SAXParseException e)
    throws SAXException
  {
    if (errorHandler != null)
      {
        errorHandler.warning(e);
      }
  }

  public void error(SAXParseException e)
    throws SAXException
  {
    if (errorHandler != null)
      {
        errorHandler.error(e);
      }
  }

  public void fatalError(SAXParseException e)
    throws SAXException
  {
    if (errorHandler != null)
      {
        errorHandler.fatalError(e);
      }
    abort();
  }
  
}

