diff NGSrich_0.5.5/src/org/jdom/Document.java @ 0:89ad0a9cca52 default tip

Uploaded
author pfrommolt
date Mon, 21 Nov 2011 08:12:19 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NGSrich_0.5.5/src/org/jdom/Document.java	Mon Nov 21 08:12:19 2011 -0500
@@ -0,0 +1,767 @@
+/*--
+
+ $Id: Document.java,v 1.85 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ 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 disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ 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 JDOM AUTHORS OR THE PROJECT
+ 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 JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.util.*;
+import org.jdom.filter.*;
+
+/**
+ * An XML document. Methods allow access to the root element as well as the
+ * {@link DocType} and other document-level information.
+ *
+ * @version $Revision: 1.85 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Jools Enticknap
+ * @author  Bradley S. Huffman
+ */
+public class Document implements Parent {
+
+    private static final String CVS_ID =
+      "@(#) $RCSfile: Document.java,v $ $Revision: 1.85 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1_1 $";
+
+    /**
+     * This document's content including comments, PIs, a possible
+     * DocType, and a root element.
+     * Subclassers have to track content using their own
+     * mechanism.
+     */
+    ContentList content = new ContentList(this);
+
+    /**
+     *  See http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/core.html#baseURIs-Considerations
+     */
+    protected String baseURI = null;
+
+    // Supports the setProperty/getProperty calls
+    private HashMap propertyMap = null;
+
+    /**
+     * Creates a new empty document.  A document must have a root element,
+     * so this document will not be well-formed and accessor methods will
+     * throw an IllegalStateException if this document is accessed before a
+     * root element is added.  This method is most useful for build tools.
+     */
+    public Document() {}
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied <code>{@link Element}</code>
+     * as the root element, the supplied
+     * <code>{@link DocType}</code> declaration, and the specified
+     * base URI.
+     *
+     * @param rootElement <code>Element</code> for document root.
+     * @param docType <code>DocType</code> declaration.
+     * @param baseURI the URI from which this doucment was loaded.
+     * @throws IllegalAddException if the given docType object
+     *         is already attached to a document or the given
+     *         rootElement already has a parent
+     */
+    public Document(Element rootElement, DocType docType, String baseURI) {
+        if (rootElement != null) {
+            setRootElement(rootElement);
+        }
+        if (docType != null) {
+            setDocType(docType);
+        }
+        if (baseURI != null) {
+            setBaseURI(baseURI);
+        }
+    }
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied <code>{@link Element}</code>
+     * as the root element and the supplied
+     * <code>{@link DocType}</code> declaration.
+     *
+     * @param rootElement <code>Element</code> for document root.
+     * @param docType <code>DocType</code> declaration.
+     * @throws IllegalAddException if the given DocType object
+     *         is already attached to a document or the given
+     *         rootElement already has a parent
+     */
+    public Document(Element rootElement, DocType docType) {
+        this(rootElement, docType, null);
+    }
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied <code>{@link Element}</code>
+     * as the root element, and no <code>{@link DocType}</code>
+     * declaration.
+     *
+     * @param rootElement <code>Element</code> for document root
+     * @throws IllegalAddException if the given rootElement already has
+     *         a parent.
+     */
+    public Document(Element rootElement) {
+        this(rootElement, null, null);
+    }
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied list of content, and a
+     * <code>{@link DocType}</code> declaration only if the content
+     * contains a DocType instance.  A null list is treated the
+     * same as the no-arg constructor.
+     *
+     * @param content <code>List</code> of starter content
+     * @throws IllegalAddException if the List contains more than
+     *         one Element or objects of illegal types.
+     */
+    public Document(List content) {
+        setContent(content);
+    }
+
+    public int getContentSize() {
+        return content.size();
+    }
+
+    public int indexOf(Content child) {
+        return content.indexOf(child);
+    }
+
+//    /**
+//     * Starting at the given index (inclusive), return the index of
+//     * the first child matching the supplied filter, or -1
+//     * if none is found.
+//     *
+//     * @return index of child, or -1 if none found.
+//     */
+//    private int indexOf(int start, Filter filter) {
+//        int size = getContentSize();
+//        for (int i = start; i < size; i++) {
+//            if (filter.matches(getContent(i))) {
+//                return i;
+//            }
+//        }
+//        return -1;
+//    }
+
+    /**
+     * This will return <code>true</code> if this document has a
+     * root element, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if this document has a root element,
+     *         <code>false</code> otherwise.
+     */
+    public boolean hasRootElement() {
+        return (content.indexOfFirstElement() < 0) ? false : true;
+    }
+
+    /**
+     * This will return the root <code>Element</code>
+     * for this <code>Document</code>
+     *
+     * @return <code>Element</code> - the document's root element
+     * @throws IllegalStateException if the root element hasn't been set
+     */
+    public Element getRootElement() {
+        int index = content.indexOfFirstElement();
+        if (index < 0) {
+            throw new IllegalStateException("Root element not set");
+        }
+        return (Element) content.get(index);
+    }
+
+    /**
+     * This sets the root <code>{@link Element}</code> for the
+     * <code>Document</code>. If the document already has a root
+     * element, it is replaced.
+     *
+     * @param rootElement <code>Element</code> to be new root.
+     * @return <code>Document</code> - modified Document.
+     * @throws IllegalAddException if the given rootElement already has
+     *         a parent.
+     */
+    public Document setRootElement(Element rootElement) {
+        int index = content.indexOfFirstElement();
+        if (index < 0) {
+            content.add(rootElement);
+        }
+        else {
+            content.set(index, rootElement);
+        }
+        return this;
+    }
+
+    /**
+     * Detach the root <code>{@link Element}</code> from this document.
+     *
+     * @return removed root <code>Element</code>
+     */
+    public Element detachRootElement() {
+        int index = content.indexOfFirstElement();
+        if (index < 0)
+            return null;
+        return (Element) removeContent(index);
+    }
+
+    /**
+     * This will return the <code>{@link DocType}</code>
+     * declaration for this <code>Document</code>, or
+     * <code>null</code> if none exists.
+     *
+     * @return <code>DocType</code> - the DOCTYPE declaration.
+     */
+    public DocType getDocType() {
+        int index = content.indexOfDocType();
+        if (index < 0) {
+            return null;
+        }
+        else {
+            return (DocType) content.get(index);
+        }
+    }
+
+    /**
+     * This will set the <code>{@link DocType}</code>
+     * declaration for this <code>Document</code>. Note
+     * that a DocType can only be attached to one Document.
+     * Attempting to set the DocType to a DocType object
+     * that already belongs to a Document will result in an
+     * IllegalAddException being thrown.
+     *
+     * @param docType <code>DocType</code> declaration.
+     * @return object on which the method was invoked
+     * @throws IllegalAddException if the given docType is
+     *   already attached to a Document.
+     */
+    public Document setDocType(DocType docType) {
+        if (docType == null) {
+            // Remove any existing doctype
+            int docTypeIndex = content.indexOfDocType();
+            if (docTypeIndex >= 0) content.remove(docTypeIndex);
+            return this;
+        }
+
+        if (docType.getParent() != null) {
+            throw new IllegalAddException(docType,
+                              "The DocType already is attached to a document");
+        }
+
+        // Add DocType to head if new, replace old otherwise
+        int docTypeIndex = content.indexOfDocType();
+        if (docTypeIndex < 0) {
+            content.add(0, docType);
+        }
+        else {
+            content.set(docTypeIndex, docType);
+        }
+
+        return this;
+    }
+
+    /**
+     * Appends the child to the end of the content list.
+     *
+     * @param child   child to append to end of content list
+     * @return        the document on which the method was called
+     * @throws IllegalAddException if the given child already has a parent.
+     */
+    public Document addContent(Content child) {
+        content.add(child);
+        return this;
+    }
+
+    /**
+     * Appends all children in the given collection to the end of
+     * the content list.  In event of an exception during add the
+     * original content will be unchanged and the objects in the supplied
+     * collection will be unaltered.
+     *
+     * @param c   collection to append
+     * @return    the document on which the method was called
+     * @throws IllegalAddException if any item in the collection
+     *         already has a parent or is of an illegal type.
+     */
+    public Document addContent(Collection c) {
+        content.addAll(c);
+        return this;
+    }
+
+    /**
+     * Inserts the child into the content list at the given index.
+     *
+     * @param index location for adding the collection
+     * @param child      child to insert
+     * @return           the parent on which the method was called
+     * @throws IndexOutOfBoundsException if index is negative or beyond
+     *         the current number of children
+     * @throws IllegalAddException if the given child already has a parent.
+     */
+    public Document addContent(int index, Content child) {
+        content.add(index, child);
+        return this;
+    }
+
+    /**
+     * Inserts the content in a collection into the content list
+     * at the given index.  In event of an exception the original content
+     * will be unchanged and the objects in the supplied collection will be
+     * unaltered.
+     *
+     * @param index location for adding the collection
+     * @param c  collection to insert
+     * @return            the parent on which the method was called
+     * @throws IndexOutOfBoundsException if index is negative or beyond
+     *         the current number of children
+     * @throws IllegalAddException if any item in the collection
+     *         already has a parent or is of an illegal type.
+     */
+    public Document addContent(int index, Collection c) {
+        content.addAll(index, c);
+        return this;
+    }
+
+    public List cloneContent() {
+        int size = getContentSize();
+        List list = new ArrayList(size);
+        for (int i = 0; i < size; i++) {
+            Content child = getContent(i);
+            list.add(child.clone());
+        }
+        return list;
+    }
+
+    public Content getContent(int index) {
+        return (Content) content.get(index);
+    }
+
+//    public Content getChild(Filter filter) {
+//        int i = indexOf(0, filter);
+//        return (i < 0) ? null : getContent(i);
+//    }
+
+    /**
+     * This will return all content for the <code>Document</code>.
+     * The returned list is "live" in document order and changes to it
+     * affect the document's actual content.
+     *
+     * <p>
+     * Sequential traversal through the List is best done with a Iterator
+     * since the underlying implement of List.size() may require walking the
+     * entire list.
+     * </p>
+     *
+     * @return <code>List</code> - all Document content
+     * @throws IllegalStateException if the root element hasn't been set
+     */
+    public List getContent() {
+        if (!hasRootElement())
+            throw new IllegalStateException("Root element not set");
+        return content;
+    }
+
+    /**
+     * Return a filtered view of this <code>Document</code>'s content.
+     *
+     * <p>
+     * Sequential traversal through the List is best done with a Iterator
+     * since the underlying implement of List.size() may require walking the
+     * entire list.
+     * </p>
+     *
+     * @param filter <code>Filter</code> to apply
+     * @return <code>List</code> - filtered Document content
+     * @throws IllegalStateException if the root element hasn't been set
+     */
+    public List getContent(Filter filter) {
+        if (!hasRootElement())
+            throw new IllegalStateException("Root element not set");
+        return content.getView(filter);
+    }
+
+    /**
+     * Removes all child content from this parent.
+     *
+     * @return list of the old children detached from this parent
+     */
+    public List removeContent() {
+        List old = new ArrayList(content);
+        content.clear();
+        return old;
+    }
+
+    /**
+     * Remove all child content from this parent matching the supplied filter.
+     *
+     * @param filter filter to select which content to remove
+     * @return list of the old children detached from this parent
+     */
+    public List removeContent(Filter filter) {
+        List old = new ArrayList();
+        Iterator itr = content.getView(filter).iterator();
+        while (itr.hasNext()) {
+            Content child = (Content) itr.next();
+            old.add(child);
+            itr.remove();
+        }
+        return old;
+    }
+
+    /**
+     * This sets the content of the <code>Document</code>.  The supplied
+     * List should contain only objects of type <code>Element</code>,
+     * <code>Comment</code>, and <code>ProcessingInstruction</code>.
+     *
+     * <p>
+     * When all objects in the supplied List are legal and before the new
+     * content is added, all objects in the old content will have their
+     * parentage set to null (no parent) and the old content list will be
+     * cleared. This has the effect that any active list (previously obtained
+     * with a call to {@link #getContent}) will also
+     * change to reflect the new content.  In addition, all objects in the
+     * supplied List will have their parentage set to this document, but the
+     * List itself will not be "live" and further removals and additions will
+     * have no effect on this document content. If the user wants to continue
+     * working with a "live" list, then a call to setContent should be
+     * followed by a call to {@link #getContent} to
+     * obtain a "live" version of the content.
+     * </p>
+     *
+     * <p>
+     * Passing a null or empty List clears the existing content.
+     * </p>
+     *
+     * <p>
+     * In event of an exception the original content will be unchanged and
+     * the objects in the supplied content will be unaltered.
+     * </p>
+     *
+     * @param newContent <code>List</code> of content to set
+     * @return this document modified
+     * @throws IllegalAddException if the List contains objects of
+     *         illegal types or with existing parentage.
+     */
+    public Document setContent(Collection newContent) {
+        content.clearAndSet(newContent);
+        return this;
+    }
+
+    /**
+     *
+     * <p>
+     * Sets the effective URI from which this document was loaded,
+     * and against which relative URLs in this document will be resolved.
+     * </p>
+     *
+     * @param uri the base URI of this document
+     */
+    public final void setBaseURI(String uri) {
+        this.baseURI = uri;  // XXX We don't check the URI
+    }
+
+    /**
+     * <p>
+     *   Returns the URI from which this document was loaded,
+     *   or null if this is not known.
+     * </p>
+     *
+     * @return the base URI of this document
+     */
+    public final String getBaseURI() {
+        return baseURI;
+    }
+
+    /*
+     * Replace the current child the given index with the supplied child.
+     * <p>
+     * In event of an exception the original content will be unchanged and
+     * the supplied child will be unaltered.
+     * </p>
+     *
+     * @param index - index of child to replace.
+     * @param child - child to add.
+     * @throws IllegalAddException if the supplied child is already attached
+     *                             or not legal content for this parent.
+     * @throws IndexOutOfBoundsException if index is negative or greater
+     *         than the current number of children.
+     */
+    public Document setContent(int index, Content child) {
+        content.set(index, child);
+        return this;
+    }
+
+    /**
+     * Replace the child at the given index whith the supplied
+     * collection.
+     * <p>
+     * In event of an exception the original content will be unchanged and
+     * the content in the supplied collection will be unaltered.
+     * </p>
+     *
+     * @param index - index of child to replace.
+     * @param collection - collection of content to add.
+     * @return object on which the method was invoked
+     * @throws IllegalAddException if the collection contains objects of
+     *         illegal types.
+     * @throws IndexOutOfBoundsException if index is negative or greater
+     *         than the current number of children.
+     */
+    public Document setContent(int index, Collection collection) {
+        content.remove(index);
+        content.addAll(index, collection);
+        return this;
+    }
+
+    public boolean removeContent(Content child) {
+        return content.remove(child);
+    }
+
+    public Content removeContent(int index) {
+        return (Content) content.remove(index);
+    }
+
+    /**
+     * Set this document's content to be the supplied child.
+     * <p>
+     * If the supplied child is legal content for a Document and before
+     * it is added, all content in the current content list will
+     * be cleared and all current children will have their parentage set to
+     * null.
+     * <p>
+     * This has the effect that any active list (previously obtained with
+     * a call to one of the {@link #getContent} methods will also change
+     * to reflect the new content.  In addition, all content in the supplied
+     * collection will have their parentage set to this Document.  If the user
+     * wants to continue working with a <b>"live"</b> list of this Document's
+     * child, then a call to setContent should be followed by a call to one
+     * of the {@link #getContent} methods to obtain a <b>"live"</b>
+     * version of the children.
+     * <p>
+     * Passing a null child clears the existing content.
+     * <p>
+     * In event of an exception the original content will be unchanged and
+     * the supplied child will be unaltered.
+     *
+     * @param child new content to replace existing content
+     * @return           the parent on which the method was called
+     * @throws IllegalAddException if the supplied child is already attached
+     *                             or not legal content for this parent
+     */
+    public Document setContent(Content child) {
+        content.clear();
+        content.add(child);
+        return this;
+    }
+
+    /**
+     * This returns a <code>String</code> representation of the
+     * <code>Document</code>, suitable for debugging. If the XML
+     * representation of the <code>Document</code> is desired,
+     * {@link org.jdom.output.XMLOutputter#outputString(Document)}
+     * should be used.
+     *
+     * @return <code>String</code> - information about the
+     *         <code>Document</code>
+     */
+    public String toString() {
+        StringBuffer stringForm = new StringBuffer()
+            .append("[Document: ");
+
+        DocType docType = getDocType();
+        if (docType != null) {
+            stringForm.append(docType.toString())
+                      .append(", ");
+        } else {
+            stringForm.append(" No DOCTYPE declaration, ");
+        }
+
+        Element rootElement = getRootElement();
+        if (rootElement != null) {
+            stringForm.append("Root is ")
+                      .append(rootElement.toString());
+        } else {
+            stringForm.append(" No root element"); // shouldn't happen
+        }
+
+        stringForm.append("]");
+
+        return stringForm.toString();
+    }
+
+    /**
+     * This tests for equality of this <code>Document</code> to the supplied
+     * <code>Object</code>.
+     *
+     * @param ob <code>Object</code> to compare to
+     * @return <code>boolean</code> whether the <code>Document</code> is
+     *         equal to the supplied <code>Object</code>
+     */
+    public final boolean equals(Object ob) {
+        return (ob == this);
+    }
+
+    /**
+     * This returns the hash code for this <code>Document</code>.
+     *
+     * @return <code>int</code> hash code
+     */
+    public final int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * This will return a deep clone of this <code>Document</code>.
+     *
+     * @return <code>Object</code> clone of this <code>Document</code>
+     */
+    public Object clone() {
+        Document doc = null;
+
+        try {
+            doc = (Document) super.clone();
+        } catch (CloneNotSupportedException ce) {
+            // Can't happen
+        }
+
+        // The clone has a reference to this object's content list, so
+        // owerwrite with a empty list
+        doc.content = new ContentList(doc);
+
+        // Add the cloned content to clone
+
+        for (int i = 0; i < content.size(); i++) {
+            Object obj = content.get(i);
+            if (obj instanceof Element) {
+                Element element = (Element)((Element)obj).clone();
+                doc.content.add(element);
+            }
+            else if (obj instanceof Comment) {
+                Comment comment = (Comment)((Comment)obj).clone();
+                doc.content.add(comment);
+            }
+            else if (obj instanceof ProcessingInstruction) {
+                ProcessingInstruction pi = (ProcessingInstruction)
+                           ((ProcessingInstruction)obj).clone();
+                doc.content.add(pi);
+            }
+            else if (obj instanceof DocType) {
+                DocType dt = (DocType) ((DocType)obj).clone();
+                doc.content.add(dt);
+            }
+        }
+
+        return doc;
+    }
+
+    /**
+     * Returns an iterator that walks over all descendants in document order.
+     *
+     * @return an iterator to walk descendants
+     */
+    public Iterator getDescendants() {
+        return new DescendantIterator(this);
+    }
+
+    /**
+     * Returns an iterator that walks over all descendants in document order
+     * applying the Filter to return only elements that match the filter rule.
+     * With filters you can match only Elements, only Comments, Elements or
+     * Comments, only Elements with a given name and/or prefix, and so on.
+     *
+     * @param filter filter to select which descendants to see
+     * @return an iterator to walk descendants within a filter
+     */
+    public Iterator getDescendants(Filter filter) {
+        return new FilterIterator(new DescendantIterator(this), filter);
+    }
+
+    public Parent getParent() {
+        return null;  // documents never have parents
+    }
+
+
+
+    /**
+     * @see org.jdom.Parent#getDocument()
+     */
+    public Document getDocument() {
+        return this;
+    }
+
+    /**
+     * Assigns an arbitrary object to be associated with this document under
+     * the given "id" string.  Null values are permitted.  Strings beginning
+     * with "http://www.jdom.org/ are reserved for JDOM use.
+     *
+     * @param id     the id of the stored object
+     * @param value  the object to store
+     */
+    public void setProperty(String id, Object value) {
+        if (propertyMap == null) {
+            propertyMap = new HashMap();
+        }
+        propertyMap.put(id, value);
+    }
+
+    /**
+     * Returns the object associated with this document under the given "id"
+     * string, or null if there is no binding or if the binding explicitly
+     * stored a null value.
+     *
+     * @param id   the id of the stored object to return
+     * @return     the object associated with the given id
+     */
+    public Object getProperty(String id) {
+        if (propertyMap == null) return null;
+        return propertyMap.get(id);
+    }
+}