/* DomElement.java -- 
   Copyright (C) 1999,2000,2001,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., 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;

import java.util.HashSet;
import java.util.Set;
import javax.xml.XMLConstants;

import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.TypeInfo;

/**
 * <p> "Element" implementation.
 *
 * @author David Brownell 
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class DomElement
  extends DomNsNode
  implements Element
{

  /**
   * User-defined ID attributes.
   * Used by DomAttr.isId and DomDocument.getElementById
   */
  Set userIdAttrs;

  // Attributes are VERY expensive in DOM, and not just for
  // this implementation.  Avoid creating them.
  private DomNamedNodeMap attributes;

  // xml:space cache
  String xmlSpace = "";

  /**
   * Constructs an Element node associated with the specified document.
   *
   * <p>This constructor should only be invoked by a Document as part
   * of its createElement functionality, or through a subclass which is
   * similarly used in a "Sub-DOM" style layer.
   *
   * @param owner The document with which this node is associated
   * @param namespaceURI Combined with the local part of the name,
   *	this is used to uniquely identify a type of element
   * @param name Name of this element, which may include a prefix
   */
  protected DomElement(DomDocument owner, String namespaceURI, String name)
  {
    super(ELEMENT_NODE, owner, namespaceURI, name);
  }

  /**
   * <p>
   * Constructs an Element node associated with the specified document.
   * This constructor should only be invoked by a Document as part
   * of its createElement functionality, or through a subclass which is
   * similarly used in a "Sub-DOM" style layer.
   * </p>
   * <p>
   * With this constructor, the prefix and local part are given explicitly
   * rather than being computed.  This allows them to be explicitly set to
   * {@code null} as required by {@link Document#createElement(String)}.   
   * </p>
   *
   * @param owner The document with which this node is associated
   * @param namespaceURI Combined with the local part of the name,
   *	this is used to uniquely identify a type of element
   * @param name Name of this element, which may include a prefix
   * @param prefix the namespace prefix of the name.  May be {@code null}.
   * @param localName the local part of the name.  May be {@code null}.
   */
  protected DomElement(DomDocument owner, String namespaceURI, String name,
		       String prefix, String localName)
  {
    super(ELEMENT_NODE, owner, namespaceURI, name, prefix, localName);
  }

  /**
   * <b>DOM L1</b>
   * Returns the element's attributes
   */
  public NamedNodeMap getAttributes()
  {
    if (attributes == null)
      {
        attributes = new DomNamedNodeMap(this, Node.ATTRIBUTE_NODE);
      }
    return attributes;
  }

  /**
   * <b>DOM L2></b>
   * Returns true iff this is an element node with attributes.
   */
  public boolean hasAttributes()
  {
    return attributes != null && attributes.length != 0;
  }

  /**
   * Shallow clone of the element, except that associated
   * attributes are (deep) cloned.
   */
  public Object clone()
  {
    DomElement node = (DomElement) super.clone();

    if (attributes != null)
      {
        node.attributes = new DomNamedNodeMap(node, Node.ATTRIBUTE_NODE);
        for (DomNode ctx = attributes.first; ctx != null; ctx = ctx.next)
          {
            node.attributes.setNamedItem(ctx.cloneNode(true), true, true);
          }
      }
    return node;
  }

  void setOwner(DomDocument doc)
  {
    if (attributes != null)
      {
        for (DomNode ctx = attributes.first; ctx != null; ctx = ctx.next)
          {
            ctx.setOwner(doc);
          }
      }
    super.setOwner(doc);
  }

  /**
   * Marks this element, its children, and its associated attributes as
   * readonly.
   */
  public void makeReadonly()
  {
    super.makeReadonly();
    if (attributes != null)
      {
        attributes.makeReadonly();
      }
  }

  /**
   * <b>DOM L1</b>
   * Returns the element name (same as getNodeName).
   */
  final public String getTagName()
  {
    return getNodeName();
  }

  /**
   * <b>DOM L1</b>
   * Returns the value of the specified attribute, or an
   * empty string.
   */
  public String getAttribute(String name)
  {
    if ("xml:space" == name) // NB only works on interned string
      {
        // Use cached value
        return xmlSpace;
      }
    Attr attr = getAttributeNode(name);
    return (attr == null) ? "" : attr.getValue();
  }

  /**
   * <b>DOM L2</b>
   * Returns true if the element has an attribute with the
   * specified name (specified or DTD defaulted).
   */
  public boolean hasAttribute(String name)
  {
    return getAttributeNode(name) != null;
  }

  /**
   * <b>DOM L2</b>
   * Returns true if the element has an attribute with the
   * specified name (specified or DTD defaulted).
   */
  public boolean hasAttributeNS(String namespaceURI, String local)
  {
    return getAttributeNodeNS(namespaceURI, local) != null;
  }

  /**
   * <b>DOM L2</b>
   * Returns the value of the specified attribute, or an
   * empty string.
   */
  public String getAttributeNS(String namespaceURI, String local)
  {
    Attr attr = getAttributeNodeNS(namespaceURI, local);
    return (attr == null) ? "" : attr.getValue();
  }

  /**
   * <b>DOM L1</b>
   * Returns the appropriate attribute node; the name is the
   * nodeName property of the attribute.
   */
  public Attr getAttributeNode(String name)
  {
    return (attributes == null) ? null :
      (Attr) attributes.getNamedItem(name);
  }

  /**
   * <b>DOM L2</b>
   * Returns the appropriate attribute node; the name combines
   * the namespace name and the local part.
   */
  public Attr getAttributeNodeNS(String namespace, String localPart)
  {
    return (attributes == null) ? null :
      (Attr) attributes.getNamedItemNS(namespace, localPart);
  }

  /**
   * <b>DOM L1</b>
   * Modifies an existing attribute to have the specified value,
   * or creates a new one with that value.  The name used is the
   * nodeName value. 
   */
  public void setAttribute(String name, String value)
  {
    Attr attr = getAttributeNode(name);
    if (attr != null)
      {
        attr.setNodeValue(value);
        ((DomAttr) attr).setSpecified(true);
        return;
      }
    attr = owner.createAttribute(name);
    attr.setNodeValue(value);
    setAttributeNode(attr);
  }

  /**
   * <b>DOM L2</b>
   * Modifies an existing attribute to have the specified value,
   * or creates a new one with that value.
   */
  public void setAttributeNS(String uri, String aname, String value)
  {
    if (("xmlns".equals (aname) || aname.startsWith ("xmlns:"))
        && !XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals (uri))
      {
        throw new DomDOMException(DOMException.NAMESPACE_ERR,
                        "setting xmlns attribute to illegal value", this, 0);
      }

    Attr attr = getAttributeNodeNS(uri, aname);
    if (attr != null)
      {
        attr.setNodeValue(value);
        return;
      }
    attr = owner.createAttributeNS(uri, aname);
    attr.setNodeValue(value);
    setAttributeNodeNS(attr);
  }

  /**
   * <b>DOM L1</b>
   * Stores the specified attribute, optionally overwriting any
   * existing one with that name.
   */
  public Attr setAttributeNode(Attr attr)
  {
    return (Attr) getAttributes().setNamedItem(attr);
  }

  /**
   * <b>DOM L2</b>
   * Stores the specified attribute, optionally overwriting any
   * existing one with that name.
   */
  public Attr setAttributeNodeNS(Attr attr)
  {
    return (Attr) getAttributes().setNamedItemNS(attr);
  }

  /**
   * <b>DOM L1</b>
   * Removes the appropriate attribute node.
   * If there is no such node, this is (bizarrely enough) a NOP so you
   * won't see exceptions if your code deletes non-existent attributes.
   *
   * <p>Note that since there is no portable way for DOM to record
   * DTD information, default values for attributes will never be
   * provided automatically.
   */
  public void removeAttribute(String name)
  {
    if (attributes == null)
      {
        return;
      }

    try
      {
        attributes.removeNamedItem(name);
      }
    catch (DomDOMException e)
      {
        if (e.code != DOMException.NOT_FOUND_ERR)
          {
            throw e;
          }
      }
  }

  /**
   * <b>DOM L1</b>
   * Removes the appropriate attribute node; the name is the
   * nodeName property of the attribute.
   *
   * <p>Note that since there is no portable way for DOM to record
   * DTD information, default values for attributes will never be
   * provided automatically.
   */
  public Attr removeAttributeNode(Attr node)
  {
    if (attributes == null)
      {
        throw new DomDOMException(DOMException.NOT_FOUND_ERR, null, node, 0);
      }
    return (Attr) attributes.removeNamedItem(node.getNodeName());
  }

  /**
   * <b>DOM L2</b>
   * Removes the appropriate attribute node; the name combines
   * the namespace name and the local part.
   *
   * <p>Note that since there is no portable way for DOM to record
   * DTD information, default values for attributes will never be
   * provided automatically.
   */
  public void removeAttributeNS(String namespace, String localPart)
  {
    if (attributes == null)
      {
        throw new DomDOMException(DOMException.NOT_FOUND_ERR, localPart, null, 0);
      }
    attributes.removeNamedItemNS (namespace, localPart);
  }

  // DOM Level 3 methods

  public String lookupPrefix(String namespaceURI)
  {
    if (namespaceURI == null)
      {
        return null;
      }
    String namespace = getNamespaceURI();
    if (namespace != null && namespace.equals(namespaceURI))
      {
        return getPrefix();
      }
    if (attributes != null)
      {
        for (DomNode ctx = attributes.first; ctx != null; ctx = ctx.next)
          {
            if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
                .equals(ctx.getNamespaceURI()))
              {
                String value = ctx.getNodeValue();
                if (value.equals(namespaceURI))
                  {
                    return ctx.getLocalName();
                  }
              }
          }
      }
    return super.lookupPrefix(namespaceURI);
  }

  public boolean isDefaultNamespace(String namespaceURI)
  {
    String namespace = getNamespaceURI();
    if (namespace != null && namespace.equals(namespaceURI))
      {
        return getPrefix() == null;
      }
    if (attributes != null)
      {
        for (DomNode ctx = attributes.first; ctx != null; ctx = ctx.next)
          {
            if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
                .equals(ctx.getNamespaceURI()))
              {
                String qName = ctx.getNodeName();
                return (XMLConstants.XMLNS_ATTRIBUTE.equals(qName));
              }
          }
      }
    return super.isDefaultNamespace(namespaceURI);
  }

  public String lookupNamespaceURI(String prefix)
  {
    String namespace = getNamespaceURI();
    if (namespace != null && equal(prefix, getPrefix()))
      {
        return namespace;
      }
    if (attributes != null)
      {
        for (DomNode ctx = attributes.first; ctx != null; ctx = ctx.next)
          {
            if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
                .equals(ctx.getNamespaceURI()))
              {
                if (prefix == null)
                  {
                    if (XMLConstants.XMLNS_ATTRIBUTE.equals(ctx.getNodeName()))
                      {
                        return ctx.getNodeValue();
                      }
                  }
                else
                  {
                    if (prefix.equals(ctx.getLocalName()))
                      {
                        return ctx.getNodeValue();
                      }
                  }
              }
          }
      }
    return super.lookupNamespaceURI(prefix);
  }
  
  public String getBaseURI()
  {
    if (attributes != null)
      {
        Node xmlBase =
          attributes.getNamedItemNS(XMLConstants.XML_NS_URI, "base");
        if (xmlBase != null)
          {
            return xmlBase.getNodeValue();
          }
      }
    return super.getBaseURI();
  }
  
  public TypeInfo getSchemaTypeInfo()
  {
    // DTD implementation
    DomDoctype doctype = (DomDoctype) owner.getDoctype();
    if (doctype != null)
      {
        return doctype.getElementTypeInfo(getNodeName());
      }
    // TODO XML Schema implementation
    return null;
  }

  public void setIdAttribute(String name, boolean isId)
  {
    NamedNodeMap attrs = getAttributes();
    Attr attr = (Attr) attrs.getNamedItem(name);
    setIdAttributeNode(attr, isId);
  }
  
  public void setIdAttributeNode(Attr attr, boolean isId)
  {
    if (readonly)
      {
        throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
      }
    if (attr == null || attr.getOwnerElement() != this)
      {
        throw new DomDOMException(DOMException.NOT_FOUND_ERR);
      }
    if (isId)
      {
        if (userIdAttrs == null)
          {
            userIdAttrs = new HashSet();
          }
        userIdAttrs.add(attr);
      }
    else if (userIdAttrs != null)
      {
        userIdAttrs.remove(attr);
        if (userIdAttrs.isEmpty())
          {
            userIdAttrs = null;
          }
      }
  }

  public void setIdAttributeNS(String namespaceURI, String localName,
                               boolean isId)
  {
    NamedNodeMap attrs = getAttributes();
    Attr attr = (Attr) attrs.getNamedItemNS(namespaceURI, localName);
    setIdAttributeNode(attr, isId);
  }

  public boolean isEqualNode(Node arg)
  {
    if (!super.isEqualNode(arg))
      return false;
    getAttributes();
    NamedNodeMap argAttrs = arg.getAttributes();
    int len = argAttrs.getLength();
    if (argAttrs == null || (len != attributes.length))
      return false;
    for (int i = 0; i < len; i++)
      {
        Node argCtx = argAttrs.item(i);
        // Don't compare namespace nodes
        if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
            .equals(argCtx.getNamespaceURI()))
          continue;
        // Find corresponding attribute node
        DomNode ctx = attributes.first;
        for (; ctx != null; ctx = ctx.next)
          {
            if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
                .equals(ctx.getNamespaceURI()))
              continue;
            if (!ctx.isEqualNode(argCtx))
              continue;
            break;
          }
        if (ctx == null)
          return false; // not found
      }
    return true;
  }
  
}
