/* DomAttr.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 org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.TypeInfo;
import org.w3c.dom.events.MutationEvent;


/**
 * <p> "Attr" implementation.  In DOM, attributes cost quite a lot of
 * memory because their values are complex structures rather than just
 * simple strings.  To reduce your costs, avoid having more than one
 * child of an attribute; stick to a single Text node child, and ignore
 * even that by using the attribute's "nodeValue" property.</p>
 *
 * <p> As a bit of general advice, only look at attribute modification
 * events through the DOMAttrModified event (sent to the associated
 * element).  Implementations are not guaranteed to report other events
 * in the same order, so you're very likely to write nonportable code if
 * you monitor events at the "children of Attr" level.</p>
 *
 * <p> At this writing, not all attribute modifications will cause the
 * DOMAttrModified event to be triggered ... only the ones using the string
 * methods (setNodeValue, setValue, and Element.setAttribute) to modify
 * those values.  That is, if you manipulate those children directly,
 * elements won't get notified that attribute values have changed.
 * The natural fix for that will report other modifications, but won't 
 * be able to expose "previous" attribute value; it'll need to be cached
 * or something (at which point why bother using child nodes). </p>
 *
 * <p><em>You are strongly advised not to use "children" of any attribute
 * nodes you work with.</em> </p>
 *
 * @author David Brownell
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class DomAttr
  extends DomNsNode
  implements Attr
{
  
  private boolean specified;
  private String value; // string value cache
  
  /**
   * Constructs an Attr node associated with the specified document.
   * The "specified" flag is initialized to true, since this DOM has
   * no current "back door" mechanisms to manage default values so
   * that every value must effectively be "specified".
   *
   * <p>This constructor should only be invoked by a Document as part of
   * its createAttribute 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 attribute
   * @param name Name of this attribute, which may include a prefix
   */
  protected DomAttr(DomDocument owner, String namespaceURI, String name)
  {
    super(ATTRIBUTE_NODE, owner, namespaceURI, name);
    specified = true;
    length = 1;
    
    // XXX register self to get insertion/removal events
    // and character data change events and when they happen,
    // report self-mutation
  }
  
  /**
   * <b>DOM L1</b>
   * Returns the attribute name (same as getNodeName)
   */
  public final String getName()
  {
    return getNodeName();
  }
  
  /**
   * <b>DOM L1</b>
   * Returns true if a parser reported this was in the source text.
   */
  public final boolean getSpecified()
  {
    return specified;
  }
  
  /**
   * Records whether this attribute was in the source text.
   */
  public final void setSpecified(boolean value)
  {
    specified = value;
  }

  /**
   * <b>DOM L1</b>
   * Returns the attribute value, with character and entity
   * references substituted.
   * <em>NOTE:  entity refs as children aren't currently handled.</em>
   */
  public String getNodeValue()
  {
    // If we have a simple node-value, use that
    if (first == null)
      {
        return (value == null) ? "" : value;
      }
    // Otherwise collect child node-values
    StringBuffer buf = new StringBuffer();
    for (DomNode ctx = first; ctx != null; ctx = ctx.next)
      {
        switch (ctx.nodeType)
          {
          case Node.TEXT_NODE:
            buf.append(ctx.getNodeValue());
            break;
          case Node.ENTITY_REFERENCE_NODE:
            // TODO
            break;
          }
      }
    return buf.toString();
  }
  
  /**
   * <b>DOM L1</b>
   * Assigns the value of the attribute; it will have one child,
   * which is a text node with the specified value (same as
   * setNodeValue).
   */
  public final void setValue(String value)
  {
    setNodeValue(value);
  }
  
  /**
   * <b>DOM L1</b>
   * Returns the value of the attribute as a non-null string; same
   * as getNodeValue.
   * <em>NOTE:  entity refs as children aren't currently handled.</em>
   */
  public final String getValue()
  {
    return getNodeValue();
  }
  
  /**
   * <b>DOM L1</b>
   * Assigns the attribute value; using this API, no entity or
   * character references will exist.
   * Causes a DOMAttrModified mutation event to be sent.
   */
  public void setNodeValue(String value)
  {
    if (readonly)
      {
        throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
      }
    if (value == null)
      {
        value = "";
      }
    String oldValue = getNodeValue();
    while (last != null)
      {
        removeChild(last);
      }
    // don't create a new node just for this...
    /*
     Node text = owner.createTextNode(value);
     appendChild(text);
     */
    this.value = value;
    length = 1;
    specified = true;
    
    mutating(oldValue, value, MutationEvent.MODIFICATION);
  }

  public final Node getFirstChild()
  {
    // Create a child text node if necessary
    if (first == null)
      {
        length = 0;
        Node text = owner.createTextNode((value == null) ? "" : value);
        appendChild(text);
      }
    return first;
  }

  public final Node getLastChild()
  {
    // Create a child text node if necessary
    if (last == null)
      {
        length = 0;
        Node text = owner.createTextNode((value == null) ? "" : value);
        appendChild(text);
      }
    return last;
  }

  public Node item(int index)
  {
    // Create a child text node if necessary
    if (first == null)
      {
        length = 0;
        Node text = owner.createTextNode((value == null) ? "" : value);
        appendChild(text);
      }
    return super.item(index);
  }

  /**
   * <b>DOM L2</b>
   * Returns the element with which this attribute is associated.
   */
  public final Element getOwnerElement()
  {
    return (Element) parent;
  }

  public final Node getNextSibling()
  {
    return null;
  }

  public final Node getPreviousSibling()
  {
    return null;
  }

  public Node getParentNode()
  {
    return null;
  }

  /**
   * Records the element with which this attribute is associated.
   */
  public final void setOwnerElement(Element e)
  {
    if (parent != null)
      {
        throw new DomDOMException(DOMException.HIERARCHY_REQUEST_ERR);
      }
    if (!(e instanceof DomElement))
      {
        throw new DomDOMException(DOMException.WRONG_DOCUMENT_ERR);
      }
    parent = (DomElement) e;
    depth = parent.depth + 1;
  }

  /**
   * The base URI of an Attr is always <code>null</code>.
   */
  public final String getBaseURI()
  {
    return null;
  }
    
  /**
   * Shallow clone of the attribute, breaking all ties with any
   * elements.
   */
  public Object clone()
  {
    DomAttr retval = (DomAttr) super.clone();
    retval.specified = true;
    return retval;
  }
    
  private void mutating(String oldValue, String newValue, short why)
  {
    if (!reportMutations || parent == null)
      {
        return;
      }
    
    // EVENT:  DOMAttrModified, target = parent,
    //	prev/new values provided, also attr name
    MutationEvent	event;
    
    event = (MutationEvent) createEvent ("MutationEvents");
    event.initMutationEvent ("DOMAttrModified",
                             true /* bubbles */, false /* nocancel */,
                             null, oldValue, newValue, getNodeName (), why);
    parent.dispatchEvent (event);
  }

  // DOM Level 3 methods
  
  public TypeInfo getSchemaTypeInfo()
  {
    if (parent != null)
      {
        // DTD implementation
        DomDoctype doctype = (DomDoctype) parent.owner.getDoctype();
        if (doctype != null)
          {
            return doctype.getAttributeTypeInfo(parent.getNodeName(),
                                                getNodeName());
          }
        // TODO XML Schema implementation
      }
    return null;
  }

  public boolean isId()
  {
    if (parent != null)
      {
        DomDoctype doctype = (DomDoctype) parent.owner.getDoctype();
        if (doctype != null)
          {
            DTDAttributeTypeInfo info =
              doctype.getAttributeTypeInfo(parent.getNodeName(),
                                           getNodeName());
            if (info != null && "ID".equals(info.type))
              {
                return true;
              }
          }
        DomElement element = (DomElement) parent;
        if (element.userIdAttrs != null &&
            element.userIdAttrs.contains(this))
          {
            return true;
          }
        // TODO XML Schema implementation
      }
    return false;
  }

}

