You are viewing a plain text version of this content. The canonical link for it is here.
Posted to crimson-cvs@xml.apache.org by ed...@apache.org on 2001/02/24 04:23:52 UTC

cvs commit: xml-crimson/src/org/apache/crimson/tree ElementNode2.java AttributeNode1.java XmlDocumentBuilder.java XmlDocument.java NodeBase.java NamespacedNode.java ElementNode.java AttributeSet.java AttributeNode.java

edwingo     01/02/23 19:23:51

  Modified:    src/org/apache/crimson/tree XmlDocumentBuilder.java
                        XmlDocument.java NodeBase.java NamespacedNode.java
                        ElementNode.java AttributeSet.java
                        AttributeNode.java
  Added:       src/org/apache/crimson/tree ElementNode2.java
                        AttributeNode1.java
  Log:
  Fixed DOM implementation so Element and Attr nodes created using DOM Level
  1 methods would return null for localName attribute.
  
  Revision  Changes    Path
  1.4       +16 -10    xml-crimson/src/org/apache/crimson/tree/XmlDocumentBuilder.java
  
  Index: XmlDocumentBuilder.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/XmlDocumentBuilder.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XmlDocumentBuilder.java	2001/01/29 23:45:14	1.3
  +++ XmlDocumentBuilder.java	2001/02/24 03:23:45	1.4
  @@ -1,5 +1,5 @@
   /* 
  - * $Id: XmlDocumentBuilder.java,v 1.3 2001/01/29 23:45:14 edwingo Exp $
  + * $Id: XmlDocumentBuilder.java,v 1.4 2001/02/24 03:23:45 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -127,7 +127,7 @@
    * than matching an XML structure that may not be optimized appropriately.
    *
    * @author David Brownell
  - * @version $Revision: 1.3 $
  + * @version $Revision: 1.4 $
    */
   public class XmlDocumentBuilder implements ContentHandler, LexicalHandler,
       DeclHandler, DTDHandler
  @@ -471,15 +471,21 @@
   	// Then create the element, associate its attributes, and
   	// stack it for later addition.
   	//
  -        ElementNode e = null;
  +        ElementNode2 e = null;
   	try {
  -            if (namespaceURI.equals("")) {
  -                // No namespaceURI.  Enable element factory backward
  -                // compatibility.
  -                e = (ElementNode)document.createElementEx(rawName);
  +            if ("".equals(namespaceURI)) {
  +                // No namespaceURI
  +                if (disableNamespaces) {
  +                    // Enable element factory backward compatibility using
  +                    // DOM Level 1 methods
  +                    e = (ElementNode2)document.createElementEx(rawName);
  +                } else {
  +                    // Use DOM Level 2 method
  +                    e = (ElementNode2)document.createElementNS(null, rawName);
  +                }
               } else {
  -                e = (ElementNode)document.createElementNS(namespaceURI,
  -                                                          rawName);
  +                e = (ElementNode2)document.createElementNS(namespaceURI,
  +                                                           rawName);
               }
   	} catch (DOMException ex) {
   	    throw new SAXParseException(getMessage("XDB-004",
  @@ -513,7 +519,7 @@
                              String rawName)
   	throws SAXException
       {
  -        ElementNode e = (ElementNode) elementStack[topOfStack];
  +        ParentNode e = (ParentNode) elementStack[topOfStack];
   
           elementStack[topOfStack--] = null;
   
  
  
  
  1.3       +26 -29    xml-crimson/src/org/apache/crimson/tree/XmlDocument.java
  
  Index: XmlDocument.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/XmlDocument.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XmlDocument.java	2001/01/24 03:43:19	1.2
  +++ XmlDocument.java	2001/02/24 03:23:45	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: XmlDocument.java,v 1.2 2001/01/24 03:43:19 edwingo Exp $
  + * $Id: XmlDocument.java,v 1.3 2001/02/24 03:23:45 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -129,7 +129,7 @@
    *
    * @author David Brownell
    * @author Rajiv Mordani
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   public class XmlDocument extends ParentNode implements DocumentEx
   {
  @@ -316,25 +316,6 @@
           return builder.getDocument();
       }
   
  -    /*
  -     * Returns the top level document element.
  -     * This is a convenience function in the big picture;
  -     * use the DOM version instead, at least for now.
  -     */
  -    // package private
  -    ElementNode getDocument ()
  -    {
  -        // We ignore comments, PIs, whitespace, etc
  -        // and return the first (only!) element.
  -        for (int i = 0; true; i++) {
  -            Node n = item (i);
  -            if (n == null)
  -                return null;
  -            if (n instanceof ElementNode)
  -                return (ElementNode) n;
  -        }
  -    }
  -
       /**
        * Returns the locale to be used for diagnostic messages.
        */
  @@ -676,7 +657,7 @@
       public Node appendChild (Node n)
       throws DOMException
       {
  -        if (n instanceof Element && getDocument () != null)
  +        if (n instanceof Element && getDocumentElement () != null)
               throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
           if (n instanceof DocumentType && getDoctype () != null)
               throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
  @@ -694,7 +675,7 @@
       throws DOMException
       {
           if (!replaceRootElement && n instanceof Element && 
  -            getDocument () != null)
  +            getDocumentElement () != null)
               throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
           if (!replaceRootElement && n instanceof DocumentType 
               && getDoctype () != null)
  @@ -796,9 +777,22 @@
       }
   
       
  -    /** DOM: Returns the content root element. */
  +    /**
  +     * DOM: Returns the content root element.
  +     */
       public Element getDocumentElement ()
  -	{ return getDocument (); }
  +    {
  +        // We ignore comments, PIs, whitespace, etc
  +        // and return the first (only!) element.
  +        for (int i = 0; true; i++) {
  +            Node n = item (i);
  +            if (n == null)
  +                return null;
  +            if (n instanceof Element) {
  +                return (Element)n;
  +            }
  +        }
  +    }
   
       /**
        * Assigns the element factory to be used by this document.
  @@ -846,7 +840,7 @@
       public Element createElementNS(String namespaceURI, String qualifiedName)
           throws DOMException
       {
  -        ElementNode retval = new ElementNode(namespaceURI, qualifiedName);
  +        ElementNode2 retval = new ElementNode2(namespaceURI, qualifiedName);
           retval.setOwnerDocument(this);
           return retval;
       }
  @@ -995,7 +989,10 @@
        * @param name the name of the attribute.
        */
       public Attr createAttribute(String name) throws DOMException {
  -        AttributeNode retval = new AttributeNode(name, null, true, null);
  +        if (!XmlNames.isName(name)) {
  +            throw new DomEx(DOMException.INVALID_CHARACTER_ERR);
  +        }
  +        AttributeNode1 retval = new AttributeNode1(name, null, true, null);
           retval.setOwnerDocument(this);
           return retval;
       }
  @@ -1171,7 +1168,7 @@
   
               // Elements have associated attributes, which must
               // also have owners changed.
  -            if (n instanceof ElementNode) {
  +            if (n instanceof Element) {
                   NamedNodeMap    list = n.getAttributes ();
                   int             length = list.getLength ();
                   for (int i = 0; i < length; i++)
  @@ -1285,7 +1282,7 @@
   
               // Elements have associated attributes, which must
               // also have owners changed.
  -            if (n instanceof ElementNode) {
  +            if (n instanceof Element) {
                   NamedNodeMap    list = n.getAttributes ();
                   int             length = list.getLength ();
                   for (int i = 0; i < length; i++)
  
  
  
  1.2       +7 -7      xml-crimson/src/org/apache/crimson/tree/NodeBase.java
  
  Index: NodeBase.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/NodeBase.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- NodeBase.java	2000/11/23 01:53:34	1.1
  +++ NodeBase.java	2001/02/24 03:23:46	1.2
  @@ -1,5 +1,5 @@
   /*
  - * $Id: NodeBase.java,v 1.1 2000/11/23 01:53:34 edwingo Exp $
  + * $Id: NodeBase.java,v 1.2 2001/02/24 03:23:46 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -74,7 +74,7 @@
    * although it is subclasses which implement that access.
    *
    * @author David Brownell
  - * @version $Revision: 1.1 $
  + * @version $Revision: 1.2 $
    */
   // not public ... javadoc looks a bit odd (hidden base class)
   // but it's only subclassable within this package anyway
  @@ -144,8 +144,8 @@
   	Attr		value = null;
   
   	do {
  -	    if (current instanceof ElementNode) {
  -		ElementNode	e = (ElementNode) current;
  +	    if (current instanceof ElementNode2) {
  +		ElementNode2 e = (ElementNode2) current;
   
   		if ((value = e.getAttributeNode (name)) != null)
   		    break;
  @@ -341,7 +341,7 @@
   
       /**
        * <b>DOM:</b> returns null.
  -     * Overridden by the ElementNode subclass.
  +     * Overridden by the ElementNode2 subclass.
        */
       public NamedNodeMap       getAttributes ()
   	{ return null; }
  @@ -364,7 +364,7 @@
   
       /**
        * <b>DOM2:</b> returns null.
  -     * Overridden by subclasses that support namespaces, ie. ElementNode and
  +     * Overridden by subclasses that support namespaces, ie. ElementNode2 and
        * AttributeNode.
        */
       public String getNamespaceURI() {
  @@ -397,7 +397,7 @@
   
       /**
        * Returns whether this node (if it is an element) has any attributes.
  -     * Overridden by ElementNode
  +     * Overridden by Element implementations
        * @since DOM Level 2
        */
       public boolean hasAttributes() {
  
  
  
  1.3       +21 -12    xml-crimson/src/org/apache/crimson/tree/NamespacedNode.java
  
  Index: NamespacedNode.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/NamespacedNode.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NamespacedNode.java	2001/01/28 01:00:07	1.2
  +++ NamespacedNode.java	2001/02/24 03:23:46	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: NamespacedNode.java,v 1.2 2001/01/28 01:00:07 edwingo Exp $
  + * $Id: NamespacedNode.java,v 1.3 2001/02/24 03:23:46 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -67,14 +67,14 @@
    * for more info.
    *
    * @author Edwin Goei
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   abstract class NamespacedNode extends ParentNode {
       /**
  -     * Field "name" can be used to hold any XML REC "[5] Name" including a
  +     * Field "qName" can be used to hold any XML REC "[5] Name" including a
        * Namespaces REC "[6] QName".
        */
  -    protected String name;
  +    protected String qName;
   
       protected String namespaceURI;
   
  @@ -95,7 +95,7 @@
        * @since DOM Level 2
        */
       public String getPrefix() {
  -        return XmlNames.getPrefix(name);
  +        return XmlNames.getPrefix(qName);
       }
   
       /**
  @@ -108,12 +108,12 @@
               throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
           }
   
  -	int index = name.indexOf(':');
  +	int index = qName.indexOf(':');
   
           // prefix == null implies reset to no default namespace
   	if (prefix == null) {
   	    if (index >= 0) {
  -	    	name = name.substring(index + 1);
  +	    	qName = qName.substring(index + 1);
               }
   	    return;
   	}
  @@ -133,7 +133,7 @@
           if (getNodeType() == ATTRIBUTE_NODE) {
               if ("xmlns".equals(prefix)
                       && !XmlNames.SPEC_XMLNS_URI.equals(namespaceURI)
  -                || "xmlns".equals(name)) {
  +                || "xmlns".equals(qName)) {
                   throw new DomEx(DomEx.NAMESPACE_ERR);
               }
           }
  @@ -142,11 +142,11 @@
      	StringBuffer tmp = new StringBuffer(prefix);
   	tmp.append(':');
   	if (index < 0 ) {
  -	    tmp.append(name);
  +	    tmp.append(qName);
   	} else {
  -	    tmp.append(name.substring(index + 1));
  +	    tmp.append(qName.substring(index + 1));
           }
  -	name = tmp.toString();
  +	qName = tmp.toString();
       }
   
       /**
  @@ -155,6 +155,15 @@
        * @since DOM Level 2
        */
       public String getLocalName() {
  -        return XmlNames.getLocalPart(name);
  +        return XmlNames.getLocalPart(qName);
  +    }
  +
  +    /**
  +     * Returns the nodeName of this node
  +     *
  +     * @since DOM Level 1
  +     */
  +    public String getNodeName() {
  +        return qName;
       }
   }
  
  
  
  1.7       +21 -495   xml-crimson/src/org/apache/crimson/tree/ElementNode.java
  
  Index: ElementNode.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/ElementNode.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ElementNode.java	2001/01/29 20:52:36	1.6
  +++ ElementNode.java	2001/02/24 03:23:47	1.7
  @@ -1,10 +1,10 @@
   /*
  - * $Id: ElementNode.java,v 1.6 2001/01/29 20:52:36 edwingo Exp $
  + * $Id: ElementNode.java,v 1.7 2001/02/24 03:23:47 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 2000 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2001 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -58,137 +58,32 @@
   
   package org.apache.crimson.tree;
   
  -import java.io.CharArrayWriter;
  -import java.io.IOException;
  -import java.io.Writer;
  -
  -import java.util.Enumeration;
  -
  -import org.apache.crimson.util.XmlNames;
  -
  -import org.w3c.dom.*;
  -
  -
   /**
  - * This class represents XML elements in a parse tree, and is often
  - * subclassed to add custom behaviors.  When an XML Document object
  - * is built using an <em>XmlDocumentBuilder</em> instance, simple
  - * declarative configuration information may be used to control whether
  - * this class, or some specialized subclass (e.g. supporting HTML DOM
  - * methods) is used for elements in the resulting tree.
  - *
  - * <P> As well as defining new methods to provide behaviors which are
  - * specific to application frameworks, such as Servlets or Swing, such
  - * subclasses may also override methods such as <em>doneParse</em>
  - * and <em>appendChild</em> to perform some kinds of processing during
  - * tree construction.  Such processing can include transforming tree
  - * structure to better suit the needs of a given application.  When
  - * such transformation is done, the <em>XmlWritable</em> methods
  - * may need to be overridden to make elements transform themselves back
  - * to XML without losing information.  (One common transformation is
  - * eliminating redundant representations of data; attributes of an XML
  - * element may correspond to defaultable object properties, and so on.)
  - *
  - * <P> Element nodes also support a single <em>userObject</em> property,
  - * which may be used to bind objects to elements where subclassing is
  - * either not possible or is inappropriate.  For example, user interface
  - * objects often derive from <code>java.awt.Component</code>, so that
  - * they can't extend a different class (<em>ElementNode</em>).
  - *
  - * @see XmlDocumentBuilder
  - *
  - * @author David Brownell
  - * @version $Revision: 1.6 $
  + * A DOM Element that was created with a Level 1 create method.  Note that
  + * the name ElementNode is maintained for backwards compatibility with
  + * element factories which may subclass using this name.
    */
  -public class ElementNode extends NamespacedNode implements ElementEx
  +public class ElementNode extends ElementNode2
   {
  -    private AttributeSet	attributes;
  -    private String		idAttributeName;
  -    private Object		userObject;
  -
  -    private static final char	tagStart [] = { '<', '/' };
  -    private static final char	tagEnd [] = { ' ', '/', '>' };
  -    
       /**
        * Partially constructs an element; its tag will be assigned by the
        * element factory (or subclass), while attributes and the parent (and
        * implicitly, siblings) will be assigned when it is joined to a DOM
        * document.
        *
  -     * @deprecated Element factories are deprecated.  For backwards
  -     * compatibility only.
  +     * Element factories are deprecated.  For backwards compatibility only.
        */
       public ElementNode() {
  -        // no-op
  +        super(null, null);
       }
   
       /**
        * Construct an element with a particular XML REC "Name".
        */
       public ElementNode(String name) {
  -        this.name = name;
  +        super(null, name);
       }
   
  -    public ElementNode(String namespaceURI, String qName)
  -        throws DomEx
  -    {
  -        // Check arguments and throw appropriate exceptions
  -        checkArguments(namespaceURI, qName);
  -
  -        name = qName;
  -        this.namespaceURI = namespaceURI;
  -    }
  -
  -    private void checkArguments(String namespaceURI, String qualifiedName)
  -        throws DomEx
  -    {
  -        // [6] QName ::= (Prefix ':')? LocalPart
  -        // [7] Prefix ::= NCName
  -        // [8] LocalPart ::= NCName
  -
  -	if (qualifiedName == null) {
  -            throw new DomEx(DomEx.NAMESPACE_ERR);
  -        }
  -
  -	int first = qualifiedName.indexOf(':');
  -
  -        if (first <= 0) {
  -            // no Prefix, only check LocalPart
  -            if (!XmlNames.isUnqualifiedName(qualifiedName)) {
  -                throw new DomEx(DomEx.INVALID_CHARACTER_ERR);
  -            }
  -            return;
  -        }
  -
  -        // Prefix exists, check everything
  -
  -	int last = qualifiedName.lastIndexOf(':');
  -	if (last != first) {
  -            throw new DomEx(DomEx.NAMESPACE_ERR);
  -        }
  -	
  -        String prefix = qualifiedName.substring(0, first);
  -        String localName = qualifiedName.substring(first + 1);
  -	if (!XmlNames.isUnqualifiedName(prefix)
  -                || !XmlNames.isUnqualifiedName(localName)) {
  -            throw new DomEx(DomEx.INVALID_CHARACTER_ERR);
  -        }
  -
  -        // If we get here then we must have a valid prefix
  -        if (namespaceURI == null || namespaceURI.equals("")
  -                || (prefix.equals("xml") &&
  -                    !XmlNames.SPEC_XML_URI.equals(namespaceURI))) {
  -            throw new DomEx(DomEx.NAMESPACE_ERR);
  -        }
  -    }
  -
  -    public void trimToSize ()
  -    {
  -	super.trimToSize ();
  -	if (attributes != null)
  -	    attributes.trimToSize ();
  -    }
  -
       /**
        * Assigns the element's name, when the element has been
        * constructed using the default constructor.  For use by
  @@ -198,396 +93,27 @@
        * compatibility only.
        */
       protected void setTag(String t) {
  -        name = t;
  -    }
  -
  -    // Assigns the element's attributes.
  -    void setAttributes (AttributeSet a)
  -    {
  -	AttributeSet oldAtts = attributes;
  -
  -	// Check if the current AttributeSet or any attribute is readonly
  -	// isReadonly checks if any of the attributes in the AttributeSet
  -	// is readonly..
  -	if (oldAtts != null && oldAtts.isReadonly()) {
  -	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -        }
  -
  -	if (a != null) {
  -	    a.setOwnerElement(this);
  -        }
  -	attributes = a;
  -	if (oldAtts != null) {
  -	    oldAtts.setOwnerElement(null);
  -        }
  -    }
  -
  -    // package private -- overrides base class method
  -    void checkChildType (int type)
  -    throws DOMException
  -    {
  -	switch (type) {
  -	  case ELEMENT_NODE:
  -	  case TEXT_NODE:
  -	  case COMMENT_NODE:
  -	  case PROCESSING_INSTRUCTION_NODE:
  -	  case CDATA_SECTION_NODE:
  -	  case ENTITY_REFERENCE_NODE:
  -	    return;
  -	  default:
  -	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
  -	}
  +        qName = t;
       }
   
  -    // package private -- overrides base class method
  -    public void setReadonly (boolean deep)
  -    {
  -	if (attributes != null)
  -	    attributes.setReadonly ();
  -	super.setReadonly (deep);
  -    }
  -
  -    /** <b>DOM:</b> Returns the attributes of this element. */
  -    public NamedNodeMap getAttributes ()
  -    {
  -	if (attributes == null)
  -	    attributes = new AttributeSet (this);
  -        return attributes;
  -    }
  -        
  -    /**
  -     * Returns whether this node (if it is an element) has any attributes.
  -     * @since DOM Level 2
  -     */
  -    public boolean hasAttributes() {
  -        return attributes != null;
  -    }
  -
  -    /**
  -     * Returns the element and its content as a string, which includes
  -     * all the markup embedded in this element.  If the element is not
  -     * fully constructed, the content will not be an XML tag.
  -     */
  -    public String toString ()
  -    {
  -	try {
  -	    CharArrayWriter	out = new CharArrayWriter ();
  -	    XmlWriteContext	x = new XmlWriteContext (out);
  -	    writeXml (x);
  -	    return out.toString ();
  -	} catch (Exception e) {
  -	    return super.toString ();
  -	}
  -    }
  -    
  -    
  -    /**
  -     * Writes this element and all of its children out, as well
  -     * formed XML.
  -     */
  -    public void writeXml (XmlWriteContext context) throws IOException
  -    {
  -	Writer	out = context.getWriter ();
  -
  -	if (name == null)
  -	   throw new IllegalStateException ( getMessage ("EN-002"));
  -	   
  -	out.write (tagStart, 0, 1);	// "<"
  -	out.write (name);
  -	
  -        if (attributes != null)
  -	    attributes.writeXml (context);
  -
  -	//
  -	// Write empty nodes as "<EMPTY />" to make sure version 3
  -	// and 4 web browsers can read empty tag output as HTML.
  -	// XML allows "<EMPTY/>" too, of course.
  -	//
  -	if (!hasChildNodes ())
  -	    out.write (tagEnd, 0, 3);	// " />"
  -	else  {
  -	    out.write (tagEnd, 2, 1);	// ">"
  -	    writeChildrenXml (context);
  -	    out.write (tagStart, 0, 2);	// "</"
  -	    out.write (name);
  -	    out.write (tagEnd, 2, 1);	// ">"
  -	}
  -    }
  -
  -    /**
  -     * Assigns the name of the element's ID attribute; only one attribute
  -     * may have the ID type.  XML supports a kind of validatable internal
  -     * linking using ID attributes, with IDREF attributes identifying
  -     * specific nodes (and IDREFS attributes identifying sets of them).
  -     */
  -    public void setIdAttributeName (String attName)
  -    {
  -	if (readonly)
  -	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -	idAttributeName = attName;
  -    }
  -
       /**
  -     * Returns the name of the element's ID attribute, if one is known.
  -     */
  -    public String getIdAttributeName ()
  -	{ return idAttributeName; }
  -
  -    
  -    public void setUserObject (Object userObject)
  -	{ this.userObject = userObject; }
  -
  -    public Object getUserObject ()
  -	{ return userObject; }
  -
  -    // DOM support
  -
  -    /** <b>DOM:</b> Returns the ELEMENT_NODE node type. */
  -    public short getNodeType ()  { return ELEMENT_NODE; }
  -
  -    /** <b>DOM:</b> Returns the name of the XML tag for this element. */
  -    public String getTagName () { return name; }
  -    
  -    /** <b>DOM:</b> Returns the name of the XML tag for this element. */
  -    public String getNodeName () { return name; }
  -
  -    /**
  -     * Returns <code>true</code> when an attribute with a given name is
  -     * specified on this element or has a default value, <code>false</code>
  -     * otherwise.
  -     * @since DOM Level 2
  -     */
  -    public boolean hasAttribute(String name) {
  -        return getAttributeNode(name) != null;
  -    }
  -
  -    /**
  -     * Returns <code>true</code> when an attribute with a given local name
  -     * and namespace URI is specified on this element or has a default
  -     * value, <code>false</code> otherwise.
  -     * @since DOM Level 2
  -     */
  -    public boolean hasAttributeNS(String namespaceURI, String localName) {
  -        return getAttributeNodeNS(namespaceURI, localName) != null;
  -    }
  -
  -    /** <b>DOM:</b> Returns the value of the named attribute, or an empty
  -     * string 
  -     */
  -    public String getAttribute (String name)
  -    {
  -	return (attributes == null)
  -	    ? ""
  -	    : attributes.getValue (name);
  -    }
  -
  -    /**
  -     * Retrieves an attribute value by local name and namespace URI. 
  -     * @since DOM Level 2
  -     */
  -    public String getAttributeNS(String namespaceURI, String localName) {
  -	if (attributes == null) {
  -	    return "";
  -        }
  -	Attr attr = getAttributeNodeNS(namespaceURI, localName);
  -	if (attr == null) {
  -	    return "";
  -        }
  -	return attr.getValue();
  -    }
  -
  -    /**
  -     *  Retrieves an <code>Attr</code> node by local name and namespace URI. 
  -     * @since DOM Level 2
  -     */
  -    public Attr getAttributeNodeNS(String namespaceURI, String localName) {
  -	if (localName == null) {
  -	    return null;
  -        }
  -	if (attributes == null) {
  -            return null;
  -        }
  -        for (int i = 0; ; i++) {
  -            AttributeNode attr = (AttributeNode) attributes.item(i);
  -            if (attr == null) {
  -                return null;
  -            }
  -            if (attr.getLocalName().equals(localName)
  -                && attr.getNamespaceURI().equals(namespaceURI)) {
  -                return attr;
  -            }
  -        }
  -    }
  -    
  -    /**
  -     * <b>DOM:</b> Assigns or modifies the value of the specified attribute.
  -     */
  -    public void setAttribute (String name, String value)
  -    throws DOMException
  -    {
  -	AttributeNode	att;
  -
  -	if (readonly)
  -	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -	if (attributes == null)
  -	    attributes = new AttributeSet (this);
  -	if ((att = (AttributeNode) attributes.getNamedItem (name)) != null)
  -	    att.setNodeValue (value);
  -	else {
  -	    att = new AttributeNode (name, value, true, null);
  -	    att.setOwnerDocument ((XmlDocument) getOwnerDocument ());
  -            /* "ownerElement" should be null before calling "setNamedItem" */
  -	    attributes.setNamedItem (att);
  -	}
  -    }
  -    
  -    /**
  -     * <b>DOM2:</b>
  -     * @since DOM Level 2
  -     */
  -    public void setAttributeNS(String namespaceURI, String qualifiedName, 
  -                               String value)
  -        throws DOMException
  -    {
  -        AttributeNode.checkArguments(namespaceURI, qualifiedName);
  -        String prefix = XmlNames.getPrefix(qualifiedName);
  -
  -        Attr attr = getAttributeNodeNS(namespaceURI,
  -                XmlNames.getLocalPart(qualifiedName));
  -        if (attr == null) {
  -            AttributeNode newAttr = new AttributeNode(namespaceURI,
  -                                                      qualifiedName, value,
  -                                                      true, null);
  -	    newAttr.setOwnerDocument((XmlDocument)getOwnerDocument());
  -            setAttributeNodeNS(newAttr);
  -        } else {
  -            attr.setValue(value);
  -            attr.setPrefix(prefix);
  -        }
  -    }
  -
  -    /**
  -     * <b>DOM2:</b>
  -     * @since DOM Level 2
  -     */
  -    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
  -	if (readonly) {
  -	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -        }
  -        if (newAttr.getOwnerDocument() != getOwnerDocument()) {
  -	    throw new DomEx(DomEx.WRONG_DOCUMENT_ERR);
  -        }
  -
  -	if (attributes == null) {
  -	    attributes = new AttributeSet(this);
  -        }
  -
  -        // Note: ownerElement of newAttr is both checked and set in the
  -        // following call to AttributeSet.setNamedItemNS(Node)
  -	return (Attr)attributes.setNamedItemNS(newAttr);
  -    }
  -
  -    /** <b>DOM:</b> Remove the named attribute. */
  -    public void removeAttribute (String name)
  -    throws DOMException
  -    {
  -	if (readonly)
  -	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -	if (attributes == null)
  -	    throw new DomEx (DomEx.NOT_FOUND_ERR);
  -        attributes.removeNamedItem (name);
  -    }
  -
  -    /**
  -     * <b>DOM2:</b>
  +     * The namespace prefix of this node, or <code>null</code> if it is
  +     * unspecified.
  +     *
        * @since DOM Level 2
  -     */
  -    public void removeAttributeNS(String namespaceURI, String localName)
  -        throws DOMException
  -    {
  -	if (readonly) {
  -	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -        }
  -        attributes.removeNamedItemNS(namespaceURI, localName);
  -    }
  -
  -    /** <b>DOM:</b>  returns the attribute */
  -    public Attr getAttributeNode (String name)
  -    {
  -	if (attributes != null)
  -	    return (Attr) attributes.getNamedItem (name);
  -	else
  -	    return null;
  -    }
  -    
  -    /** <b>DOM:</b> assigns the attribute */
  -    public Attr setAttributeNode (Attr newAttr)
  -    throws DOMException
  -    {
  -	if (readonly)
  -	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -	if (!(newAttr instanceof AttributeNode))
  -	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
  -
  -	if (attributes == null) 
  -	    attributes = new AttributeSet (this);
  -
  -        // Note: ownerElement of newAttr is both checked and set in the
  -        // following call to AttributeSet.setNamedItem(Node)
  -	return (Attr) attributes.setNamedItem(newAttr);
  -    }
  -    
  -    /** <b>DOM:</b> removes the attribute with the same name as this one */
  -    public Attr removeAttributeNode (Attr oldAttr)
  -    throws DOMException
  -    {
  -	if (isReadonly ())
  -	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  -
  -	Attr	attr = getAttributeNode (oldAttr.getNodeName ());
  -	if (attr == null)
  -	    throw new DomEx (DomEx.NOT_FOUND_ERR);
  -	removeAttribute (attr.getNodeName ());
  -	return attr;
  -    }
  -
  -    
  -    /**
  -     * Creates a new unparented node whose attributes are the same as
  -     * this node's attributes; if <em>deep</em> is true, the children
  -     * of this node are cloned as children of the new node.
        */
  -    public Node cloneNode (boolean deep)
  -    {
  -	try {
  -	    ElementNode	retval;
  -
  -	    retval = (ElementNode)getOwnerDocument().createElement(name);
  -	    if (attributes != null)
  -		retval.setAttributes (new AttributeSet (attributes, true));
  -	    if (deep) {
  -		for (int i = 0; true; i++) {
  -		    Node	node = item (i);
  -		    if (node == null)
  -			break;
  -		    retval.appendChild (node.cloneNode (true));
  -		}
  -	    }
  -	    return retval;
  -	} catch (DOMException e) {
  -	    throw new RuntimeException (getMessage ("EN-001"));
  -	}
  +    public String getPrefix() {
  +        // DOM Level 2 specifies this
  +        return null;
       }
   
       /**
  -     * Convenience method to construct a non-prettyprinting XML write
  -     * context and call writeXml with it.  Subclasses may choose to
  -     * to override this method to generate non-XML text, 
  +     * Returns the local part of the qualified name of this node.
        *
  -     * @param out where to emit the XML content of this node
  +     * @since DOM Level 2
        */
  -    public void write (Writer out) throws IOException
  -    {
  -	writeXml (new XmlWriteContext (out));
  +    public String getLocalName() {
  +        // DOM Level 2 specifies this
  +        return null;
       }
   }
  
  
  
  1.9       +6 -6      xml-crimson/src/org/apache/crimson/tree/AttributeSet.java
  
  Index: AttributeSet.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/AttributeSet.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AttributeSet.java	2001/01/28 01:00:06	1.8
  +++ AttributeSet.java	2001/02/24 03:23:48	1.9
  @@ -1,5 +1,5 @@
   /*
  - * $Id: AttributeSet.java,v 1.8 2001/01/28 01:00:06 edwingo Exp $
  + * $Id: AttributeSet.java,v 1.9 2001/02/24 03:23:48 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -80,18 +80,18 @@
    * document or was instead defaulted by attribute processing.
    *
    * @author David Brownell
  - * @version $Revision: 1.8 $
  + * @version $Revision: 1.9 $
    */
   final
   class AttributeSet implements NamedNodeMap, XmlWritable
   {
       private boolean     readonly;
       private Vector      list;
  -    private ElementNode ownerElement;
  +    private Element     ownerElement;
           
       /* Constructs an attribute list, with associated name scope. */
       // package private
  -    AttributeSet(ElementNode ownerElement) {
  +    AttributeSet(Element ownerElement) {
           list = new Vector (5);
           this.ownerElement = ownerElement;
       }
  @@ -187,9 +187,9 @@
       }
   
       // package private
  -    void setOwnerElement(ElementNode e) {
  +    void setOwnerElement(Element e) {
           if (e != null && ownerElement != null) {
  -            throw new IllegalStateException(e.getMessage("A-004"));
  +            throw new IllegalStateException(((NodeBase)e).getMessage("A-004"));
           }
           ownerElement = e;
   
  
  
  
  1.8       +9 -28     xml-crimson/src/org/apache/crimson/tree/AttributeNode.java
  
  Index: AttributeNode.java
  ===================================================================
  RCS file: /home/cvs/xml-crimson/src/org/apache/crimson/tree/AttributeNode.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- AttributeNode.java	2001/01/28 01:00:06	1.7
  +++ AttributeNode.java	2001/02/24 03:23:48	1.8
  @@ -1,5 +1,5 @@
   /*
  - * $Id: AttributeNode.java,v 1.7 2001/01/28 01:00:06 edwingo Exp $
  + * $Id: AttributeNode.java,v 1.8 2001/02/24 03:23:48 edwingo Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -100,40 +100,24 @@
    *
    * @author David Brownell
    * @author Rajiv Mordani
  - * @version $Revision: 1.7 $
  + * @version $Revision: 1.8 $
    */
  -final   // at least for the moment
  -// public
  -class AttributeNode extends NamespacedNode implements Attr
  +public class AttributeNode extends NamespacedNode implements Attr
   {
       private String value;
       private boolean specified;
       private String defaultValue;
   
       /** At construction time ownerElement is null, it gets set whenever an
  -        attribute is set on an ElementNode */
  +        attribute is set on an Element */
       private Element ownerElement;
   
  -    /** Constructs an attribute node. */
  -    public AttributeNode(String name, String value,
  -        boolean specified, String defaultValue)
  -    throws DOMException
  -    {
  -        if (!XmlNames.isName(name))
  -            throw new DomEx (DOMException.INVALID_CHARACTER_ERR);
  -
  -        this.name = name;
  -        this.value = value;
  -        this.specified = specified;
  -        this.defaultValue = defaultValue;
  -    }
  -
       /** Constructs an attribute node. Used for SAX2 and DOM2 */
       public AttributeNode(String namespaceURI, String qName,
                            String value, boolean specified, String defaultValue)
           throws DOMException
       {
  -        name = qName;
  +        this.qName = qName;
           this.namespaceURI = namespaceURI;
           this.value = value;
           this.specified = specified;
  @@ -204,7 +188,7 @@
       }
   
       // package private
  -    void setOwnerElement(ElementNode element) {
  +    void setOwnerElement(Element element) {
           if (element != null && ownerElement != null) {
               throw new IllegalStateException(getMessage("A-000", 
                               new Object[] { element.getTagName() }));
  @@ -216,11 +200,8 @@
       /** DOM:  Returns the ATTRIBUTE_NODE node type constant. */
       public short getNodeType () { return ATTRIBUTE_NODE; }
   
  -    /** DOM:  Returns the attribute name */
  -    public String getName () { return name; }
  -
       /** DOM:  Returns the attribute name */
  -    public String getNodeName () { return name; }
  +    public String getName () { return qName; }
   
       /** DOM:  Returns the attribute value. */
       public String getValue () { return value; }
  @@ -265,7 +246,7 @@
       {
           Writer  out = context.getWriter ();
   
  -        out.write (name);
  +        out.write (qName);
           out.write ("=\"");
           writeChildrenXml (context);
           out.write ('"');
  @@ -310,7 +291,7 @@
           try {
               // XXX should probably use Java Cloneable scheme instead
               AttributeNode attr =
  -                new AttributeNode(namespaceURI, name, value, specified,
  +                new AttributeNode(namespaceURI, qName, value, specified,
                                     defaultValue);
               attr.setOwnerDocument((XmlDocument)getOwnerDocument());
               if (deep) {
  
  
  
  1.1                  xml-crimson/src/org/apache/crimson/tree/ElementNode2.java
  
  Index: ElementNode2.java
  ===================================================================
  /*
   * $Id: ElementNode2.java,v 1.1 2001/02/24 03:23:47 edwingo Exp $
   *
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Crimson" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
   * http://www.sun.com.  For more information on the Apache Software 
   * Foundation, please see <http://www.apache.org/>.
   */
  
  package org.apache.crimson.tree;
  
  import java.io.CharArrayWriter;
  import java.io.IOException;
  import java.io.Writer;
  
  import java.util.Enumeration;
  
  import org.apache.crimson.util.XmlNames;
  
  import org.w3c.dom.*;
  
  
  /**
   * Modified version of ElementNode to support DOM Level 2 methods.
   * 
   * This class represents XML elements in a parse tree, and is often
   * subclassed to add custom behaviors.  When an XML Document object
   * is built using an <em>XmlDocumentBuilder</em> instance, simple
   * declarative configuration information may be used to control whether
   * this class, or some specialized subclass (e.g. supporting HTML DOM
   * methods) is used for elements in the resulting tree.
   *
   * <P> As well as defining new methods to provide behaviors which are
   * specific to application frameworks, such as Servlets or Swing, such
   * subclasses may also override methods such as <em>doneParse</em>
   * and <em>appendChild</em> to perform some kinds of processing during
   * tree construction.  Such processing can include transforming tree
   * structure to better suit the needs of a given application.  When
   * such transformation is done, the <em>XmlWritable</em> methods
   * may need to be overridden to make elements transform themselves back
   * to XML without losing information.  (One common transformation is
   * eliminating redundant representations of data; attributes of an XML
   * element may correspond to defaultable object properties, and so on.)
   *
   * <P> Element nodes also support a single <em>userObject</em> property,
   * which may be used to bind objects to elements where subclassing is
   * either not possible or is inappropriate.  For example, user interface
   * objects often derive from <code>java.awt.Component</code>, so that
   * they can't extend a different class (<em>ElementNode</em>).
   *
   * @see XmlDocumentBuilder
   *
   * @author David Brownell
   * @author Edwin Goei
   */
  public class ElementNode2 extends NamespacedNode implements ElementEx
  {
      private AttributeSet	attributes;
      private String		idAttributeName;
      private Object		userObject;
  
      private static final char	tagStart [] = { '<', '/' };
      private static final char	tagEnd [] = { ' ', '/', '>' };
      
      public ElementNode2(String namespaceURI, String qName)
          throws DomEx
      {
          // Check arguments and throw appropriate exceptions
          checkArguments(namespaceURI, qName);
  
          this.qName = qName;
          this.namespaceURI = namespaceURI;
      }
  
      private void checkArguments(String namespaceURI, String qualifiedName)
          throws DomEx
      {
          // [6] QName ::= (Prefix ':')? LocalPart
          // [7] Prefix ::= NCName
          // [8] LocalPart ::= NCName
  
  	if (qualifiedName == null) {
              throw new DomEx(DomEx.NAMESPACE_ERR);
          }
  
  	int first = qualifiedName.indexOf(':');
  
          if (first <= 0) {
              // no Prefix, only check LocalPart
              if (!XmlNames.isUnqualifiedName(qualifiedName)) {
                  throw new DomEx(DomEx.INVALID_CHARACTER_ERR);
              }
              return;
          }
  
          // Prefix exists, check everything
  
  	int last = qualifiedName.lastIndexOf(':');
  	if (last != first) {
              throw new DomEx(DomEx.NAMESPACE_ERR);
          }
  	
          String prefix = qualifiedName.substring(0, first);
          String localName = qualifiedName.substring(first + 1);
  	if (!XmlNames.isUnqualifiedName(prefix)
                  || !XmlNames.isUnqualifiedName(localName)) {
              throw new DomEx(DomEx.INVALID_CHARACTER_ERR);
          }
  
          // If we get here then we must have a valid prefix
          if (namespaceURI == null || namespaceURI.equals("")
                  || (prefix.equals("xml") &&
                      !XmlNames.SPEC_XML_URI.equals(namespaceURI))) {
              throw new DomEx(DomEx.NAMESPACE_ERR);
          }
      }
  
      public void trimToSize ()
      {
  	super.trimToSize ();
  	if (attributes != null)
  	    attributes.trimToSize ();
      }
  
      // Assigns the element's attributes.
      void setAttributes (AttributeSet a)
      {
  	AttributeSet oldAtts = attributes;
  
  	// Check if the current AttributeSet or any attribute is readonly
  	// isReadonly checks if any of the attributes in the AttributeSet
  	// is readonly..
  	if (oldAtts != null && oldAtts.isReadonly()) {
  	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
          }
  
  	if (a != null) {
  	    a.setOwnerElement(this);
          }
  	attributes = a;
  	if (oldAtts != null) {
  	    oldAtts.setOwnerElement(null);
          }
      }
  
      // package private -- overrides base class method
      void checkChildType (int type)
      throws DOMException
      {
  	switch (type) {
  	  case ELEMENT_NODE:
  	  case TEXT_NODE:
  	  case COMMENT_NODE:
  	  case PROCESSING_INSTRUCTION_NODE:
  	  case CDATA_SECTION_NODE:
  	  case ENTITY_REFERENCE_NODE:
  	    return;
  	  default:
  	    throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR);
  	}
      }
  
      // package private -- overrides base class method
      public void setReadonly (boolean deep)
      {
  	if (attributes != null)
  	    attributes.setReadonly ();
  	super.setReadonly (deep);
      }
  
      /** <b>DOM:</b> Returns the attributes of this element. */
      public NamedNodeMap getAttributes ()
      {
  	if (attributes == null)
  	    attributes = new AttributeSet (this);
          return attributes;
      }
          
      /**
       * Returns whether this node (if it is an element) has any attributes.
       * @since DOM Level 2
       */
      public boolean hasAttributes() {
          return attributes != null;
      }
  
      /**
       * Returns the element and its content as a string, which includes
       * all the markup embedded in this element.  If the element is not
       * fully constructed, the content will not be an XML tag.
       */
      public String toString ()
      {
  	try {
  	    CharArrayWriter	out = new CharArrayWriter ();
  	    XmlWriteContext	x = new XmlWriteContext (out);
  	    writeXml (x);
  	    return out.toString ();
  	} catch (Exception e) {
  	    return super.toString ();
  	}
      }
      
      
      /**
       * Writes this element and all of its children out, as well
       * formed XML.
       */
      public void writeXml (XmlWriteContext context) throws IOException
      {
  	Writer	out = context.getWriter ();
  
  	if (qName == null)
  	   throw new IllegalStateException ( getMessage ("EN-002"));
  	   
  	out.write (tagStart, 0, 1);	// "<"
  	out.write (qName);
  	
          if (attributes != null)
  	    attributes.writeXml (context);
  
  	//
  	// Write empty nodes as "<EMPTY />" to make sure version 3
  	// and 4 web browsers can read empty tag output as HTML.
  	// XML allows "<EMPTY/>" too, of course.
  	//
  	if (!hasChildNodes ())
  	    out.write (tagEnd, 0, 3);	// " />"
  	else  {
  	    out.write (tagEnd, 2, 1);	// ">"
  	    writeChildrenXml (context);
  	    out.write (tagStart, 0, 2);	// "</"
  	    out.write (qName);
  	    out.write (tagEnd, 2, 1);	// ">"
  	}
      }
  
      /**
       * Assigns the name of the element's ID attribute; only one attribute
       * may have the ID type.  XML supports a kind of validatable internal
       * linking using ID attributes, with IDREF attributes identifying
       * specific nodes (and IDREFS attributes identifying sets of them).
       */
      public void setIdAttributeName (String attName)
      {
  	if (readonly)
  	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  	idAttributeName = attName;
      }
  
      /**
       * Returns the name of the element's ID attribute, if one is known.
       */
      public String getIdAttributeName ()
  	{ return idAttributeName; }
  
      
      public void setUserObject (Object userObject)
  	{ this.userObject = userObject; }
  
      public Object getUserObject ()
  	{ return userObject; }
  
      // DOM support
  
      /** <b>DOM:</b> Returns the ELEMENT_NODE node type. */
      public short getNodeType ()  { return ELEMENT_NODE; }
  
      /** <b>DOM:</b> Returns the name of the XML tag for this element. */
      public String getTagName () { return qName; }
      
      /**
       * Returns <code>true</code> when an attribute with a given name is
       * specified on this element or has a default value, <code>false</code>
       * otherwise.
       * @since DOM Level 2
       */
      public boolean hasAttribute(String name) {
          return getAttributeNode(name) != null;
      }
  
      /**
       * Returns <code>true</code> when an attribute with a given local name
       * and namespace URI is specified on this element or has a default
       * value, <code>false</code> otherwise.
       * @since DOM Level 2
       */
      public boolean hasAttributeNS(String namespaceURI, String localName) {
          return getAttributeNodeNS(namespaceURI, localName) != null;
      }
  
      /** <b>DOM:</b> Returns the value of the named attribute, or an empty
       * string 
       */
      public String getAttribute (String name)
      {
  	return (attributes == null)
  	    ? ""
  	    : attributes.getValue (name);
      }
  
      /**
       * Retrieves an attribute value by local name and namespace URI. 
       * @since DOM Level 2
       */
      public String getAttributeNS(String namespaceURI, String localName) {
  	if (attributes == null) {
  	    return "";
          }
  	Attr attr = getAttributeNodeNS(namespaceURI, localName);
  	if (attr == null) {
  	    return "";
          }
  	return attr.getValue();
      }
  
      /**
       *  Retrieves an <code>Attr</code> node by local name and namespace URI. 
       * @since DOM Level 2
       */
      public Attr getAttributeNodeNS(String namespaceURI, String localName) {
  	if (localName == null) {
  	    return null;
          }
  	if (attributes == null) {
              return null;
          }
          for (int i = 0; ; i++) {
              AttributeNode attr = (AttributeNode) attributes.item(i);
              if (attr == null) {
                  return null;
              }
              if (attr.getLocalName().equals(localName)
                  && attr.getNamespaceURI().equals(namespaceURI)) {
                  return attr;
              }
          }
      }
      
      /**
       * <b>DOM:</b> Assigns or modifies the value of the specified attribute.
       */
      public void setAttribute (String name, String value)
      throws DOMException
      {
  	NodeBase att;                   // Common superclass of all Attr nodes
  
  	if (readonly)
  	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
          if (!XmlNames.isName(name)) {
              throw new DomEx(DOMException.INVALID_CHARACTER_ERR);
          }
  	if (attributes == null)
  	    attributes = new AttributeSet (this);
  	if ((att = (NodeBase) attributes.getNamedItem (name)) != null)
  	    att.setNodeValue (value);
  	else {
  	    att = new AttributeNode1(name, value, true, null);
  	    att.setOwnerDocument ((XmlDocument) getOwnerDocument ());
              /* "ownerElement" should be null before calling "setNamedItem" */
  	    attributes.setNamedItem (att);
  	}
      }
      
      /**
       * <b>DOM2:</b>
       * @since DOM Level 2
       */
      public void setAttributeNS(String namespaceURI, String qualifiedName, 
                                 String value)
          throws DOMException
      {
          AttributeNode.checkArguments(namespaceURI, qualifiedName);
  
          Attr attr = getAttributeNodeNS(namespaceURI,
                  XmlNames.getLocalPart(qualifiedName));
          if (attr == null) {
              AttributeNode newAttr = new AttributeNode(namespaceURI,
                                                        qualifiedName, value,
                                                        true, null);
  	    newAttr.setOwnerDocument((XmlDocument)getOwnerDocument());
              setAttributeNodeNS(newAttr);
          } else {
              attr.setValue(value);
              attr.setPrefix(XmlNames.getPrefix(qualifiedName));
          }
      }
  
      /**
       * <b>DOM2:</b>
       * @since DOM Level 2
       */
      public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
  	if (readonly) {
  	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
          }
          if (newAttr.getOwnerDocument() != getOwnerDocument()) {
  	    throw new DomEx(DomEx.WRONG_DOCUMENT_ERR);
          }
  
  	if (attributes == null) {
  	    attributes = new AttributeSet(this);
          }
  
          // Note: ownerElement of newAttr is both checked and set in the
          // following call to AttributeSet.setNamedItemNS(Node)
  	return (Attr)attributes.setNamedItemNS(newAttr);
      }
  
      /** <b>DOM:</b> Remove the named attribute. */
      public void removeAttribute (String name)
      throws DOMException
      {
  	if (readonly)
  	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  	if (attributes == null)
  	    throw new DomEx (DomEx.NOT_FOUND_ERR);
          attributes.removeNamedItem (name);
      }
  
      /**
       * <b>DOM2:</b>
       * @since DOM Level 2
       */
      public void removeAttributeNS(String namespaceURI, String localName)
          throws DOMException
      {
  	if (readonly) {
  	    throw new DomEx(DomEx.NO_MODIFICATION_ALLOWED_ERR);
          }
          attributes.removeNamedItemNS(namespaceURI, localName);
      }
  
      /** <b>DOM:</b>  returns the attribute */
      public Attr getAttributeNode (String name)
      {
  	if (attributes != null)
  	    return (Attr) attributes.getNamedItem (name);
  	else
  	    return null;
      }
      
      /** <b>DOM:</b> assigns the attribute */
      public Attr setAttributeNode (Attr newAttr)
      throws DOMException
      {
  	if (readonly)
  	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  	if (!(newAttr instanceof AttributeNode))
  	    throw new DomEx (DomEx.WRONG_DOCUMENT_ERR);
  
  	if (attributes == null) 
  	    attributes = new AttributeSet (this);
  
          // Note: ownerElement of newAttr is both checked and set in the
          // following call to AttributeSet.setNamedItem(Node)
  	return (Attr) attributes.setNamedItem(newAttr);
      }
      
      /** <b>DOM:</b> removes the attribute with the same name as this one */
      public Attr removeAttributeNode (Attr oldAttr)
      throws DOMException
      {
  	if (isReadonly ())
  	    throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
  
  	Attr	attr = getAttributeNode (oldAttr.getNodeName ());
  	if (attr == null)
  	    throw new DomEx (DomEx.NOT_FOUND_ERR);
  	removeAttribute (attr.getNodeName ());
  	return attr;
      }
  
      
      /**
       * Creates a new unparented node whose attributes are the same as
       * this node's attributes; if <em>deep</em> is true, the children
       * of this node are cloned as children of the new node.
       */
      public Node cloneNode (boolean deep)
      {
  	try {
  	    ElementNode2 retval;
  
  	    retval = (ElementNode2)getOwnerDocument().createElement(qName);
  	    if (attributes != null)
  		retval.setAttributes (new AttributeSet (attributes, true));
  	    if (deep) {
  		for (int i = 0; true; i++) {
  		    Node	node = item (i);
  		    if (node == null)
  			break;
  		    retval.appendChild (node.cloneNode (true));
  		}
  	    }
  	    return retval;
  	} catch (DOMException e) {
  	    throw new RuntimeException (getMessage ("EN-001"));
  	}
      }
  
      /**
       * Convenience method to construct a non-prettyprinting XML write
       * context and call writeXml with it.  Subclasses may choose to
       * to override this method to generate non-XML text, 
       *
       * @param out where to emit the XML content of this node
       */
      public void write (Writer out) throws IOException
      {
  	writeXml (new XmlWriteContext (out));
      }
  }
  
  
  
  1.1                  xml-crimson/src/org/apache/crimson/tree/AttributeNode1.java
  
  Index: AttributeNode1.java
  ===================================================================
  /*
   * $Id: AttributeNode1.java,v 1.1 2001/02/24 03:23:48 edwingo Exp $
   *
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Crimson" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
   * http://www.sun.com.  For more information on the Apache Software 
   * Foundation, please see <http://www.apache.org/>.
   */
  
  package org.apache.crimson.tree;
  
  /**
   * A DOM Attr that was created with a Level 1 create method.
   */
  public class AttributeNode1 extends AttributeNode
  {
      public AttributeNode1(String name, String value, boolean specified,
                            String defaultValue)
      {
          super(null, name, value, specified, defaultValue);
      }
  
      /**
       * The namespace prefix of this node, or <code>null</code> if it is
       * unspecified.
       *
       * @since DOM Level 2
       */
      public String getPrefix() {
          // DOM Level 2 specifies this
          return null;
      }
  
      /**
       * Returns the local part of the qualified name of this node.
       *
       * @since DOM Level 2
       */
      public String getLocalName() {
          // DOM Level 2 specifies this
          return null;
      }
  }