/* DomDocumentConfiguration.java -- 
   Copyright (C) 2004 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;

import java.util.Arrays;
import java.util.List;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMStringList;

/**
 * Document configuration, used to store normalization and other parameters.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class DomDocumentConfiguration
  implements DOMConfiguration, DOMStringList
{

  private static final List SUPPORTED_PARAMETERS =
    Arrays.asList(new String[] { "cdata-sections",
                  "comments",
                  "element-content-whitespace",
                  "entities",
                  "error-handler",
                  "namespace-declarations",
                  "split-cdata-sections",
                  "infoset"});

  boolean cdataSections = true;
  boolean comments = true;
  boolean elementContentWhitespace = true;
  boolean entities = true;
  DOMErrorHandler errorHandler;
  boolean namespaceDeclarations = true;
  boolean splitCdataSections = true;

  public void setParameter(String name, Object value)
    throws DOMException
  {
    name = name.toLowerCase();
    if ("cdata-sections".equals(name))
      {
        cdataSections = "true".equals(value.toString());
      }
    else if ("comments".equals(name))
      {
        comments = "true".equals(value.toString());
      }
    else if ("element-content-whitespace".equals(name))
      {
        elementContentWhitespace = "true".equals(value.toString());
      }
    else if ("entities".equals(name))
      {
        entities = "true".equals(value.toString());
      }
    else if ("error-handler".equals(name))
      {
        try
          {
            errorHandler = (DOMErrorHandler) value;
          }
        catch (ClassCastException e)
          {
            throw new DomDOMException(DOMException.TYPE_MISMATCH_ERR,
                                      value.getClass().getName(), null, 0);
          }
      }
    else if ("namespace-declarations".equals(name))
      {
        namespaceDeclarations = "true".equals(value.toString());
      }
    else if ("split-cdata-sections".equals(name))
      {
        comments = "true".equals(value.toString());
      }
    else if ("infoset".equals(name))
      {
        if ("true".equals(value.toString()))
          {
            entities = false;
            cdataSections = false;
            namespaceDeclarations = true;
            elementContentWhitespace = true;
            comments = true;
          }
      }
    else if (("canonical-form".equals(name) ||
              "check-character-normalization".equals(name) ||
              "datatype-normalization".equals(name) ||
              "normalize-characters".equals(name) ||
              "validate".equals(name) ||
              "validate-if-schema".equals(name)) &&
             "false".equals(value.toString()))
      {
        // NOOP
      }
    else if (("namespaces".equals(name) ||
              "well-formed".equals(name)) &&
             "true".equals(value.toString()))
      {
        // NOOP
      }
    else
      {
        throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR,
                                  name, null, 0);
      }
  }

  public Object getParameter(String name)
    throws DOMException
  {
    name = name.toLowerCase();
    if ("cdata-sections".equals(name))
      {
        return cdataSections ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("comments".equals(name))
      {
        return comments ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("element-content-whitespace".equals(name))
      {
        return elementContentWhitespace ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("entities".equals(name))
      {
        return entities ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("error-handler".equals(name))
      {
        return errorHandler;
      }
    else if ("namespace-declarations".equals(name))
      {
        return namespaceDeclarations ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("split-cdata-sections".equals(name))
      {
        return comments ? Boolean.TRUE : Boolean.FALSE;
      }
    else if ("canonical-form".equals(name) ||
             "check-character-normalization".equals(name) ||
             "datatype-normalization".equals(name) ||
             "normalize-characters".equals(name) ||
             "validate".equals(name) ||
             "validate-if-schema".equals(name))
      {
        return Boolean.FALSE;
      }
    else if ("namespaces".equals(name) ||
             "well-formed".equals(name))
      {
        return Boolean.TRUE;
      }
    else if ("infoset".equals(name))
      {
        return (entities == false &&
            cdataSections == false &&
            namespaceDeclarations == true &&
            comments == true) ? Boolean.TRUE : Boolean.FALSE;
      }
    throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR, name, null, 0);
  }

  public boolean canSetParameter(String name, Object value)
  {
    name = name.toLowerCase();
    if ("error-handler".equals(name))
      {
        return (value == null || value instanceof DOMErrorHandler);
      }
    else if (contains(name))
      {
        return true;
      }
    else if ("canonical-form".equals(name) ||
             "check-character-normalization".equals(name) ||
             "datatype-normalization".equals(name) ||
             "normalize-characters".equals(name) ||
             "validate".equals(name) ||
             "validate-if-schema".equals(name))
      {
        return "false".equals(value.toString());
      }
    else if ("namespaces".equals(name) ||
             "well-formed".equals(name))
      {
        return "true".equals(value.toString());
      }
    return false;
  }

  public DOMStringList getParameterNames()
  {
    return this;
  }

  public String item(int i)
  {
    try
      {
        return (String) SUPPORTED_PARAMETERS.get(i);
      }
    catch (IndexOutOfBoundsException e)
      {
        return null;
      }
  }
  
  public int getLength()
  {
    return SUPPORTED_PARAMETERS.size();
  }
  
  public boolean contains(String str)
  {
    str = str.toLowerCase();
    return SUPPORTED_PARAMETERS.contains(str);
  }

}
