/* 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., 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 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;
  }

}

