- /*
- * $Id: NodeBase.java,v 1.3 2001/05/23 21:39:45 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.Writer;
- import java.io.IOException;
- import java.util.Locale;
-
- import org.w3c.dom.*;
-
-
- /**
- * Base class for DOM parse tree nodes which may appear in XmlDocument nodes.
- * This implements "parented by" and "owning document" relationships. If
- * the parent is not null, this also supports sibling relationships through
- * that parent. Children may be directly accessed through this class,
- * although it is subclasses which implement that access.
- *
- * @author David Brownell
- * @version $Revision: 1.3 $
- */
- // not public ... javadoc looks a bit odd (hidden base class)
- // but it's only subclassable within this package anyway
- abstract class NodeBase
- implements Node, NodeEx, NodeList, XmlWritable
- {
- private ParentNode parent;
- private int parentIndex = -1; // cache
-
- // package private for speed ...
- XmlDocument ownerDocument;
- boolean readonly;
-
- /**
- * Constructs a node which will later have its parent set
- * by some other member of this package.
- */
- // package private
- NodeBase () { }
-
- /* Returns the node's parent; typesafe convenience rtn. */
- // package private ...
- ParentNode getParentImpl () { return parent; }
-
- /* not public yet ... */
- // package private
- public boolean isReadonly ()
- { return readonly; }
-
- /* not public yet ... */
- // package private
- public void setReadonly (boolean deep)
- {
- readonly = true;
- if (deep) {
- TreeWalker walker = new TreeWalker (this);
- Node next;
- while ((next = walker.getNext ()) != null)
- ((NodeBase)next).setReadonly (false);
- }
- }
-
- /**
- * Returns the language id (value of <code>xml:lang</code>
- * attribute) applicable to this node, if known. Traces up
- * through ancestors as needed.
- */
- public String getLanguage () {
- return getInheritedAttribute ("xml:lang");
- }
-
- /**
- * Returns the value of a given attribute, tracing up through
- * ancestors if needed. In the XML standard, two attributes are
- * inherited: <em>xml:lang</em> and <em>xml:space</em>. This
- * mechanism can also be involved with Cascading Style Sheets (CSS).
- * The current version of XML Namespaces also uses inheritance.
- *
- * @param name identifies the attribute; colons may be included,
- * but namespace prefixes are not interpreted
- * @return the value of the inherited attribute, or null if
- * no value was inherited.
- */
- public String getInheritedAttribute (String name)
- {
- NodeBase current = this;
- Attr value = null;
-
- do {
- if (current instanceof ElementNode2) {
- ElementNode2 e = (ElementNode2) current;
-
- if ((value = e.getAttributeNode (name)) != null)
- break;
- }
- current = current.getParentImpl ();
- } while (current != null);
- if (value != null)
- return value.getValue ();
- return null;
- }
-
- /**
- * Does nothing; this type of node has no children.
- */
- public void writeChildrenXml (XmlWriteContext context) throws IOException
- {
- }
-
- // DOM support from W3C recommendation
-
- /**
- * <b>DOM:</b> Returns the node's parent. This will be null in cases such
- * as newly created or removed nodes, and for attributes, fragments,
- * and documents.
- */
- public Node getParentNode () {
- return parent;
- }
-
-
- /*
- * Assigns the node's parent, and remove it from its current parent.
- * The caller is responsible for letting the new parent know about
- * this child by inserting it into the set of children at the
- * appropriate place, if it's not null.
- *
- * <P> Note that this method, of necessity, involves the DOM being in
- * an internally inconsistent state, either with the new parent not yet
- * knowing about its child-to-be after this call, or this node not
- * knowing its true parent before the call. That's why it's not a
- * public API, here or in DOM.
- */
- void setParentNode (ParentNode arg, int index)
- throws DOMException
- {
- if (parent != null && arg != null)
- parent.removeChild (this);
- parent = arg;
- parentIndex = index;
- }
-
-
- // assigns the owner of this document
- protected void setOwnerDocument(XmlDocument doc) {
- ownerDocument = doc;
- }
-
- /**
- * <b>DOM:</b> Returns the document to which this node belongs.
- */
- public Document getOwnerDocument ()
- {
- return ownerDocument;
- }
-
-
- /**
- * <b>DOM:</b> Returns false.
- * Overridden by subclasses which support children.
- */
- public boolean hasChildNodes() { return false; }
-
- /**
- * <b>DOM:</b> does nothing; overridden by subclasses as needed.
- */
- public void setNodeValue (String value)
- {
- if (readonly)
- throw new DomEx (DomEx.NO_MODIFICATION_ALLOWED_ERR);
- }
-
- /**
- * <b>DOM:</b> Returns null; overridden by subclasses as needed.
- */
- public String getNodeValue ()
- { return null; }
-
- /**
- * <b>DOM:</b> Returns null.
- * Overridden by subclasses which support children.
- */
- public Node getFirstChild () { return null; }
-
-
- /**
- * <b>DOM:</b> Returns zero.
- * Overridden by subclasses which support children.
- */
- public int getLength () { return 0; }
-
-
- /**
- * <b>DOM:</b> Returns null.
- * Overridden by subclasses which support children.
- */
- public Node item (int i) { return null; }
-
-
- /**
- * <b>DOM:</b> Returns an object which permits "live" access to all
- * this node's children.
- *
- * <P> In this implementation, nodes provide such access without
- * needing another node as an intermediary; "this" is returned.
- */
- public NodeList getChildNodes ()
- { return this; }
-
- /**
- * <b>DOM:</b> returns null.
- * Overridden by subclasses which support children.
- */
- public Node getLastChild ()
- { return null; }
-
- /**
- * <b>DOM:</b> Throws a HIERARCHY_REQUEST_ERR DOMException.
- * Overridden by subclasses which support children.
- * @exception DOMException thrown always.
- */
- public Node appendChild (Node newChild)
- throws DOMException
- { throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
- /**
- * <b>DOM:</b> Throws a HIERARCHY_REQUEST_ERR DOMException.
- * Overridden by subclasses which support children.
- * @exception DOMException thrown always.
- */
- public Node insertBefore (Node newChild, Node refChild)
- throws DOMException
- { throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
- /**
- * <b>DOM:</b> Throws a HIERARCHY_REQUEST_ERR DOMException.
- * Overridden by subclasses which support children.
- * @exception DOMException thrown always.
- */
- public Node replaceChild (Node newChild, Node refChild)
- throws DOMException
- { throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
- /**
- * <b>DOM:</b> Throws a HIERARCHY_REQUEST_ERR DOMException.
- * Overridden by subclasses which support children.
- * @exception DOMException thrown always.
- */
- public Node removeChild (Node oldChild)
- throws DOMException
- { throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR); }
-
-
- /**
- * <b>DOM:</b> Returns the node immediately following this node in a
- * breadth first traversal of the tree, or null if there is no
- * such sibling. In this implementation, sibling access from a
- * node is slower than indexed access from its parent.
- */
- public Node getNextSibling ()
- {
- if (parent == null)
- return null;
- if (parentIndex < 0 || parent.item (parentIndex) != this)
- parentIndex = parent.getIndexOf (this);
- return parent.item (parentIndex + 1);
- }
-
- /**
- * <b>DOM:</b> Returns the node immediately preceding this node in a
- * breadth first traversal of the tree, or null if there is no
- * such sibling. In this implementation, sibling access from a
- * node is slower than indexed access from its parent.
- */
- public Node getPreviousSibling ()
- {
- if (parent == null)
- return null;
- if (parentIndex < 0 || parent.item (parentIndex) != this)
- parentIndex = parent.getIndexOf (this);
- return parent.item (parentIndex - 1);
- }
-
- /**
- * <b>DOM:</b> returns null.
- * Overridden by the ElementNode2 subclass.
- */
- public NamedNodeMap getAttributes ()
- { return null; }
-
- /**
- * <b>DOM2:</b> noop.
- * @since DOM Level 2
- * Overridden by subclasses that need to support normalization.
- */
- public void normalize() {
- }
-
- /**
- * <b>DOM2:</b>
- * @since DOM Level 2
- */
- public boolean isSupported(String feature, String version) {
- return DOMImplementationImpl.hasFeature0(feature, version);
- }
-
- /**
- * <b>DOM2:</b> returns null.
- * Overridden by subclasses that support namespaces, ie. ElementNode2 and
- * AttributeNode.
- */
- public String getNamespaceURI() {
- return null;
- }
-
- /**
- * <b>DOM2:</b> returns null.
- * Overridden by subclasses that support namespaces.
- */
- public String getPrefix() {
- return null;
- }
-
- /**
- * <b>DOM2:</b> throws DOMException.NAMESPACE_ERR
- * Overridden by subclasses that support namespaces.
- */
- public void setPrefix(String prefix) throws DOMException {
- throw new DomEx(DomEx.NAMESPACE_ERR);
- }
-
- /**
- * <b>DOM2:</b> returns null.
- * Overridden by subclasses that support namespaces.
- */
- public String getLocalName() {
- return null;
- }
-
- /**
- * Returns whether this node (if it is an element) has any attributes.
- * Overridden by Element implementations
- * @since DOM Level 2
- */
- public boolean hasAttributes() {
- return false;
- }
-
- public int getIndexOf (Node maybeChild)
- { return -1; }
-
- /*
- * Gets the messages from the resource bundles for the given messageId.
- */
- String getMessage (String messageId) {
- return getMessage (messageId, null);
- }
-
- /*
- * Gets the messages from the resource bundles for the given messageId
- * after formatting it with the parameters passed to it.
- */
- String getMessage (String messageId, Object[] parameters) {
- Locale locale;
-
- if (this instanceof XmlDocument)
- locale = ((XmlDocument)this).getLocale ();
- else if (ownerDocument == null)
- locale = Locale.getDefault (); // sigh
- else
- locale = ownerDocument.getLocale ();
- return XmlDocument.catalog.getMessage (locale, messageId, parameters);
- }
- }