/* 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., 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.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();
    eventSink.reader = reader;
    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();
  }
  
}

