Index: 3rdParty_sources/jdom/org/jdom/Attribute.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Attribute.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Attribute.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,717 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.io.*; + +/** + * An XML attribute. Methods allow the user to obtain the value of the attribute + * as well as namespace and type information. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Elliotte Rusty Harold + * @author Wesley Biggs + * @author Victor Toni + */ +public class Attribute implements Serializable, Cloneable { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Attribute type: the attribute has not been declared or type + * is unknown. + * + * @see #getAttributeType + */ + public final static int UNDECLARED_TYPE = 0; + + /** + * Attribute type: the attribute value is a string. + * + * @see #getAttributeType + */ + public final static int CDATA_TYPE = 1; + + /** + * Attribute type: the attribute value is a unique identifier. + * + * @see #getAttributeType + */ + public final static int ID_TYPE = 2; + + /** + * Attribute type: the attribute value is a reference to a + * unique identifier. + * + * @see #getAttributeType + */ + public final static int IDREF_TYPE = 3; + + /** + * Attribute type: the attribute value is a list of references to + * unique identifiers. + * + * @see #getAttributeType + */ + public final static int IDREFS_TYPE = 4; + + /** + * Attribute type: the attribute value is the name of an entity. + * + * @see #getAttributeType + */ + public final static int ENTITY_TYPE = 5; + + /** + *

+ * Attribute type: the attribute value is a list of entity names. + *

+ * + * @see #getAttributeType + */ + public final static int ENTITIES_TYPE = 6; + + /** + * Attribute type: the attribute value is a name token. + *

+ * According to SAX 2.0 specification, attributes of enumerated + * types should be reported as "NMTOKEN" by SAX parsers. But the + * major parsers (Xerces and Crimson) provide specific values + * that permit to recognize them as {@link #ENUMERATED_TYPE}. + * + * @see #getAttributeType + */ + public final static int NMTOKEN_TYPE = 7; + + /** + * Attribute type: the attribute value is a list of name tokens. + * + * @see #getAttributeType + */ + public final static int NMTOKENS_TYPE = 8; + + /** + * Attribute type: the attribute value is the name of a notation. + * + * @see #getAttributeType + */ + public final static int NOTATION_TYPE = 9; + + /** + * Attribute type: the attribute value is a name token from an + * enumeration. + * + * @see #getAttributeType + */ + public final static int ENUMERATED_TYPE = 10; + + // Keep the old constant names for one beta cycle to help migration + + + + /** The local name of the Attribute */ + protected String name; + + /** The {@link Namespace} of the Attribute */ + protected transient Namespace namespace; + + /** The value of the Attribute */ + protected String value; + + /** The type of the Attribute */ + protected int type = UNDECLARED_TYPE; + + /** Parent element, or null if none */ + protected Element parent; + + /** + * Default, no-args constructor for implementations to use if needed. + */ + protected Attribute() {} + + /** + * This will create a new Attribute with the + * specified (local) name and value, and in the provided + * {@link Namespace}. + * + * @param name String name of Attribute. + * @param value String value for new attribute. + * @param namespace Namespace namespace for new attribute. + * @throws IllegalNameException if the given name is illegal as an + * attribute name or if if the new namespace is the default + * namespace. Attributes cannot be in a default namespace. + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}). + */ + public Attribute(final String name, final String value, final Namespace namespace) { + this(name, value, UNDECLARED_TYPE, namespace); + } + + /** + * This will create a new Attribute with the + * specified (local) name, value, and type, and in the provided + * {@link Namespace}. + * + * @param name String name of Attribute. + * @param value String value for new attribute. + * @param type int type for new attribute. + * @param namespace Namespace namespace for new attribute. + * @throws IllegalNameException if the given name is illegal as an + * attribute name or if if the new namespace is the default + * namespace. Attributes cannot be in a default namespace. + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}) or + * if the given attribute type is not one of the + * supported types. + */ + public Attribute(final String name, final String value, final int type, final Namespace namespace) { + setName(name); + setValue(value); + setAttributeType(type); + setNamespace(namespace); + } + + /** + * This will create a new Attribute with the + * specified (local) name and value, and does not place + * the attribute in a {@link Namespace}. + *

+ * Note: This actually explicitly puts the + * Attribute in the "empty" Namespace + * ({@link Namespace#NO_NAMESPACE}). + * + * @param name String name of Attribute. + * @param value String value for new attribute. + * @throws IllegalNameException if the given name is illegal as an + * attribute name. + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}). + */ + public Attribute(final String name, final String value) { + this(name, value, UNDECLARED_TYPE, Namespace.NO_NAMESPACE); + } + + /** + * This will create a new Attribute with the + * specified (local) name, value and type, and does not place + * the attribute in a {@link Namespace}. + *

+ * Note: This actually explicitly puts the + * Attribute in the "empty" Namespace + * ({@link Namespace#NO_NAMESPACE}). + * + * @param name String name of Attribute. + * @param value String value for new attribute. + * @param type int type for new attribute. + * @throws IllegalNameException if the given name is illegal as an + * attribute name. + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}) or + * if the given attribute type is not one of the + * supported types. + */ + public Attribute(final String name, final String value, final int type) { + this(name, value, type, Namespace.NO_NAMESPACE); + } + + /** + * This will return the parent of this Attribute. + * If there is no parent, then this returns null. + * + * @return parent of this Attribute + */ + public Element getParent() { + return parent; + } + + /** + * This retrieves the owning {@link Document} for + * this Attribute, or null if not a currently a member of a + * {@link Document}. + * + * @return Document owning this Attribute, or null. + */ + public Document getDocument() { + final Element parentElement = getParent(); + if (parentElement != null) { + return parentElement.getDocument(); + } + + return null; + } + + /** + * This will set the parent of this Attribute. + * + * @param parent Element to be new parent. + * @return this Attribute modified. + */ + protected Attribute setParent(final Element parent) { + this.parent = parent; + return this; + } + + /** + * This detaches the Attribute from its parent, or does + * nothing if the Attribute has no parent. + * + * @return Attribute - this Attribute modified. + */ + public Attribute detach() { + final Element parentElement = getParent(); + if (parentElement != null) { + parentElement.removeAttribute(getName(),getNamespace()); + } + + return this; + } + + /** + * This will retrieve the local name of the + * Attribute. For any XML attribute + * which appears as + * [namespacePrefix]:[attributeName], + * the local name of the attribute would be + * [attributeName]. When the attribute + * has no namespace, the local name is simply the attribute + * name. + *

+ * To obtain the namespace prefix for this + * attribute, the + * {@link #getNamespacePrefix()} + * method should be used. + * + * @return String - name of this attribute, + * without any namespace prefix. + */ + public String getName() { + return name; + } + + /** + * This sets the local name of the Attribute. + * + * @param name the new local name to set + * @return Attribute - the attribute modified. + * @throws IllegalNameException if the given name is illegal as an + * attribute name. + */ + public Attribute setName(final String name) { + final String reason = Verifier.checkAttributeName(name); + if (reason != null) { + throw new IllegalNameException(name, "attribute", reason); + } + this.name = name; + return this; + } + + /** + * This will retrieve the qualified name of the Attribute. + * For any XML attribute whose name is + * [namespacePrefix]:[elementName], + * the qualified name of the attribute would be + * everything (both namespace prefix and + * element name). When the attribute has no + * namespace, the qualified name is simply the attribute's + * local name. + *

+ * To obtain the local name of the attribute, the + * {@link #getName()} method should be used. + *

+ * To obtain the namespace prefix for this attribute, + * the {@link #getNamespacePrefix()} + * method should be used. + * + * @return String - full name for this element. + */ + public String getQualifiedName() { + // Note: Any changes here should be reflected in + // XMLOutputter.printQualifiedName() + final String prefix = namespace.getPrefix(); + + // no prefix found + if ((prefix == null) || ("".equals(prefix))) { + return getName(); + } else { + return new StringBuffer(prefix) + .append(':') + .append(getName()) + .toString(); + } + } + + /** + * This will retrieve the namespace prefix of the + * Attribute. For any XML attribute + * which appears as + * [namespacePrefix]:[attributeName], + * the namespace prefix of the attribute would be + * [namespacePrefix]. When the attribute + * has no namespace, an empty String is returned. + * + * @return String - namespace prefix of this + * attribute. + */ + public String getNamespacePrefix() { + return namespace.getPrefix(); + } + + /** + * This returns the URI mapped to this Attribute's + * prefix. If no mapping is found, an empty String is + * returned. + * + * @return String - namespace URI for this Attribute. + */ + public String getNamespaceURI() { + return namespace.getURI(); + } + + /** + * This will return this Attribute's + * {@link Namespace}. + * + * @return Namespace - Namespace object for this Attribute + */ + public Namespace getNamespace() { + return namespace; + } + + /** + * This sets this Attribute's {@link Namespace}. + * If the provided namespace is null, the attribute will have no namespace. + * The namespace must have a prefix. + * + * @param namespace the new namespace + * @return Element - the element modified. + * @throws IllegalNameException if the new namespace is the default + * namespace. Attributes cannot be in a default namespace. + */ + public Attribute setNamespace(Namespace namespace) { + if (namespace == null) { + namespace = Namespace.NO_NAMESPACE; + } + + // Verify the attribute isn't trying to be in a default namespace + // Attributes can't be in a default namespace + if (namespace != Namespace.NO_NAMESPACE && + "".equals(namespace.getPrefix())) { + throw new IllegalNameException("", "attribute namespace", + "An attribute namespace without a prefix can only be the " + + "NO_NAMESPACE namespace"); + } + this.namespace = namespace; + return this; + } + + /** + * This will return the actual textual value of this + * Attribute. This will include all text + * within the quotation marks. + * + * @return String - value for this attribute. + */ + public String getValue() { + return value; + } + + /** + * This will set the value of the Attribute. + * + * @param value String value for the attribute. + * @return Attribute - this Attribute modified. + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}). + */ + public Attribute setValue(final String value) { + final String reason = Verifier.checkCharacterData(value); + if (reason != null) { + throw new IllegalDataException(value, "attribute", reason); + } + this.value = value; + return this; + } + + /** + * This will return the actual declared type of this + * Attribute. + * + * @return int - type for this attribute. + */ + public int getAttributeType() { + return type; + } + + /** + * This will set the type of the Attribute. + * + * @param type int type for the attribute. + * @return Attribute - this Attribute modified. + * @throws IllegalDataException if the given attribute type is + * not one of the supported types. + */ + public Attribute setAttributeType(final int type) { + if ((type < UNDECLARED_TYPE) || (type > ENUMERATED_TYPE)) { + throw new IllegalDataException(String.valueOf(type), + "attribute", "Illegal attribute type"); + } + this.type = type; + return this; + } + + /** + * This returns a String representation of the + * Attribute, suitable for debugging. + * + * @return String - information about the + * Attribute + */ + public String toString() { + return new StringBuffer() + .append("[Attribute: ") + .append(getQualifiedName()) + .append("=\"") + .append(value) + .append("\"") + .append("]") + .toString(); + } + + /** + * This tests for equality of this Attribute to the supplied + * Object. + * + * @param ob Object to compare to. + * @return boolean - whether the Attribute is + * equal to the supplied Object. + */ + public final boolean equals(final Object ob) { + return (ob == this); + } + + /** + * This returns the hash code for this Attribute. + * + * @return int - hash code. + */ + public final int hashCode() { + return super.hashCode(); + } + + /** + * This will return a clone of this Attribute. + * + * @return Object - clone of this Attribute. + */ + public Object clone() { + Attribute attribute = null; + try { + attribute = (Attribute) super.clone(); + } + catch (final CloneNotSupportedException ignore) { + // Won't happen + } + + // Name, namespace, and value are references to imutable objects + // and are copied by super.clone() (aka Object.clone()) + + // super.clone() copies reference to set parent to null + attribute.parent = null; + return attribute; + } + + ///////////////////////////////////////////////////////////////// + // Convenience Methods below here + ///////////////////////////////////////////////////////////////// + + /** + * This gets the value of the attribute, in + * int form, and if no conversion + * can occur, throws a + * {@link DataConversionException} + * + * @return int value of attribute. + * @throws DataConversionException when conversion fails. + */ + public int getIntValue() throws DataConversionException { + try { + return Integer.parseInt(value.trim()); + } catch (final NumberFormatException e) { + throw new DataConversionException(name, "int"); + } + } + + /** + * This gets the value of the attribute, in + * long form, and if no conversion + * can occur, throws a + * {@link DataConversionException} + * + * @return long value of attribute. + * @throws DataConversionException when conversion fails. + */ + public long getLongValue() throws DataConversionException { + try { + return Long.parseLong(value.trim()); + } catch (final NumberFormatException e) { + throw new DataConversionException(name, "long"); + } + } + + /** + * This gets the value of the attribute, in + * float form, and if no conversion + * can occur, throws a + * {@link DataConversionException} + * + * @return float value of attribute. + * @throws DataConversionException when conversion fails. + */ + public float getFloatValue() throws DataConversionException { + try { + // Avoid Float.parseFloat() to support JDK 1.1 + return Float.valueOf(value.trim()).floatValue(); + } catch (final NumberFormatException e) { + throw new DataConversionException(name, "float"); + } + } + + /** + * This gets the value of the attribute, in + * double form, and if no conversion + * can occur, throws a + * {@link DataConversionException} + * + * @return double value of attribute. + * @throws DataConversionException when conversion fails. + */ + public double getDoubleValue() throws DataConversionException { + try { + // Avoid Double.parseDouble() to support JDK 1.1 + return Double.valueOf(value.trim()).doubleValue(); + } catch (final NumberFormatException e) { + // Specially handle INF and -INF that Double.valueOf doesn't do + String v = value.trim(); + if ("INF".equals(v)) { + return Double.POSITIVE_INFINITY; + } + if ("-INF".equals(v)) { + return Double.NEGATIVE_INFINITY; + } + throw new DataConversionException(name, "double"); + } + } + + /** + * This gets the effective boolean value of the attribute, or throws a + * {@link DataConversionException} if a conversion can't be + * performed. True values are: "true", "on", "1", and "yes". False + * values are: "false", "off", "0", and "no". Values are trimmed before + * comparison. Values other than those listed here throw the exception. + * + * @return boolean value of attribute. + * @throws DataConversionException when conversion fails. + */ + public boolean getBooleanValue() throws DataConversionException { + final String valueTrim = value.trim(); + if ( + (valueTrim.equalsIgnoreCase("true")) || + (valueTrim.equalsIgnoreCase("on")) || + (valueTrim.equalsIgnoreCase("1")) || + (valueTrim.equalsIgnoreCase("yes"))) { + return true; + } else if ( + (valueTrim.equalsIgnoreCase("false")) || + (valueTrim.equalsIgnoreCase("off")) || + (valueTrim.equalsIgnoreCase("0")) || + (valueTrim.equalsIgnoreCase("no")) + ) { + return false; + } else { + throw new DataConversionException(name, "boolean"); + } + } + + // Support a custom Namespace serialization so no two namespace + // object instances may exist for the same prefix/uri pair + private void writeObject(final ObjectOutputStream out) throws IOException { + + out.defaultWriteObject(); + + // We use writeObject() and not writeUTF() to minimize space + // This allows for writing pointers to already written strings + out.writeObject(namespace.getPrefix()); + out.writeObject(namespace.getURI()); + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + + in.defaultReadObject(); + + namespace = Namespace.getNamespace( + (String) in.readObject(), (String) in.readObject()); + } +} Index: 3rdParty_sources/jdom/org/jdom/AttributeList.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/AttributeList.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/AttributeList.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,518 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * AttributeList represents legal JDOM Attribute + * content. This class is NOT PUBLIC; users should see it as a simple List + * implementation. + * + * @author Alex Rosen + * @author Philippe Riand + * @author Bradley S. Huffman + * @version $Revision$, $Date$ + * @see CDATA + * @see Comment + * @see Element + * @see EntityRef + * @see ProcessingInstruction + * @see Text + */ +class AttributeList extends AbstractList + implements List, java.io.Serializable { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + private static final int INITIAL_ARRAY_SIZE = 5; + + /** The backing list */ + private Attribute elementData[]; + private int size; + + /** The parent Element */ + private Element parent; + + /** Force an Element parent */ + private AttributeList() {} + + /** + * Create a new instance of the AttributeList representing + * Element content + * + * @param parent element whose attributes are to be held + */ + AttributeList(Element parent) { + this.parent = parent; + } + + /** + * Package internal method to support building from sources that are + * 100% trusted. + * + * @param a attribute to add without any checks + */ + final void uncheckedAddAttribute(Attribute a) { + a.parent = parent; + ensureCapacity(size + 1); + elementData[size++] = a; + modCount++; + } + + /** + * Add a attribute to the end of the list or replace a existing + * attribute with the same name and Namespace. + * + * @param obj The object to insert into the list. + * @return true (as per the general contract of Collection.add). + * @throws IndexOutOfBoundsException if index < 0 || index > size() + */ + public boolean add(Object obj) { + if (obj instanceof Attribute) { + Attribute attribute = (Attribute) obj; + int duplicate = indexOfDuplicate(attribute); + if (duplicate < 0) { + add(size(), attribute); + } + else { + set(duplicate, attribute); + } + } + else if (obj == null) { + throw new IllegalAddException("Cannot add null attribute"); + } + else { + throw new IllegalAddException("Class " + + obj.getClass().getName() + + " is not an attribute"); + } + return true; + } + + /** + * Inserts the specified attribute at the specified position in this list. + * Shifts the attribute currently at that position (if any) and any + * subsequent attributes to the right (adds one to their indices). + * + * @param index The location to set the value to. + * @param obj The object to insert into the list. + * throws IndexOutOfBoundsException if index < 0 || index > size() + */ + public void add(int index, Object obj) { + if (obj instanceof Attribute) { + Attribute attribute = (Attribute) obj; + int duplicate = indexOfDuplicate(attribute); + if (duplicate >= 0) { + throw new IllegalAddException("Cannot add duplicate attribute"); + } + add(index, attribute); + } + else if (obj == null) { + throw new IllegalAddException("Cannot add null attribute"); + } + else { + throw new IllegalAddException("Class " + + obj.getClass().getName() + + " is not an attribute"); + } + modCount++; + } + + /** + * Check and add the Attribute to this list at + * the given index. Note: does not check for duplicate + * attributes. + * + * @param index index where to add Attribute + * @param attribute Attribute to add + */ + void add(int index, Attribute attribute) { + if (attribute.getParent() != null) { + throw new IllegalAddException( + "The attribute already has an existing parent \"" + + attribute.getParent().getQualifiedName() + "\""); + } + + String reason = Verifier.checkNamespaceCollision(attribute, parent); + if (reason != null) { + throw new IllegalAddException(parent, attribute, reason); + } + + if (index<0 || index>size) { + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + } + + attribute.setParent(parent); + + ensureCapacity(size+1); + if( index==size ) { + elementData[size++] = attribute; + } else { + System.arraycopy(elementData, index, elementData, index + 1, size - index); + elementData[index] = attribute; + size++; + } + modCount++; + } + + /** + * Add all the objects in the specified collection. + * + * @param collection The collection containing all the objects to add. + * @return true if the list was modified as a result of + * the add. + */ + public boolean addAll(Collection collection) { + return addAll(size(), collection); + } + + /** + * Inserts the specified collecton at the specified position in this list. + * Shifts the attribute currently at that position (if any) and any + * subsequent attributes to the right (adds one to their indices). + * + * @param index The offset to start adding the data in the collection + * @param collection The collection to insert into the list. + * @return true if the list was modified as a result of + * the add. + * throws IndexOutOfBoundsException if index < 0 || index > size() + */ + public boolean addAll(int index, Collection collection) { + if (index<0 || index>size) { + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + } + + if ((collection == null) || (collection.size() == 0)) { + return false; + } + ensureCapacity(size() + collection.size()); + + int count = 0; + + try { + Iterator i = collection.iterator(); + while (i.hasNext()) { + Object obj = i.next(); + add(index + count, obj); + count++; + } + } + catch (RuntimeException exception) { + for (int i = 0; i < count; i++) { + remove(index); + } + throw exception; + } + + return true; + } + + /** + * Clear the current list. + */ + public void clear() { + if (elementData != null) { + for (int i = 0; i < size; i++) { + Attribute attribute = elementData[i]; + attribute.setParent(null); + } + elementData = null; + size = 0; + } + modCount++; + } + + /** + * Clear the current list and set it to the contents + * of the Collection. + * object. + * + * @param collection The collection to use. + */ + void clearAndSet(Collection collection) { + Attribute[] old = elementData; + int oldSize = size; + + elementData = null; + size = 0; + + if ((collection != null) && (collection.size() != 0)) { + ensureCapacity(collection.size()); + try { + addAll(0, collection); + } + catch (RuntimeException exception) { + elementData = old; + size = oldSize; + throw exception; + } + } + + if (old != null) { + for (int i = 0; i < oldSize; i++) { + Attribute attribute = old[i]; + attribute.setParent(null); + } + } + modCount++; + } + + /** + * Increases the capacity of this AttributeList instance, + * if necessary, to ensure that it can hold at least the number of + * items specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity. + */ + private void ensureCapacity(int minCapacity) { + if (elementData == null) { + elementData = new Attribute[Math.max(minCapacity, INITIAL_ARRAY_SIZE)]; + } + else { + int oldCapacity = elementData.length; + if (minCapacity > oldCapacity) { + Attribute oldData[] = elementData; + int newCapacity = (oldCapacity * 3)/2 + 1; + if (newCapacity < minCapacity) + newCapacity = minCapacity; + elementData = new Attribute[newCapacity]; + System.arraycopy(oldData, 0, elementData, 0, size); + } + } + } + + /** + * Return the object at the specified offset. + * + * @param index The offset of the object. + * @return The Object which was returned. + */ + public Object get(int index) { + if (index<0 || index>=size) { + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + } + + return elementData[index]; + } + + /** + * Return the Attribute with the + * given name and Namespace. + * + * @param name name of attribute to return + * @param namespace Namespace to match + * @return the Attribute, or null if one doesn't exist. + */ + Object get(String name, Namespace namespace) { + int index = indexOf(name, namespace); + if (index < 0) { + return null; + } + return elementData[index]; + } + + /** + * Return index of the Attribute with the + * given name and uri. + */ + int indexOf(String name, Namespace namespace) { + String uri = namespace.getURI(); + if (elementData != null) { + for (int i = 0; i < size; i++) { + Attribute old = elementData[i]; + String oldURI = old.getNamespaceURI(); + String oldName = old.getName(); + if (oldURI.equals(uri) && oldName.equals(name)) { + return i; + } + } + } + return -1; + } + + /** + * Remove the object at the specified offset. + * + * @param index The offset of the object. + * @return The Object which was removed. + */ + public Object remove(int index) { + if (index<0 || index>=size) + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + + Attribute old = elementData[index]; + old.setParent(null); + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index,numMoved); + elementData[--size] = null; // Let gc do its work + modCount++; + return old; + } + + /** + * Remove the Attribute with the + * given name and Namespace. + * + * @param namespace Namespace to match + * @return the true if attribute was removed, + * false otherwise + */ + boolean remove(String name, Namespace namespace) { + int index = indexOf(name, namespace); + if (index < 0) { + return false; + } + remove(index); + return true; + } + + /** + * Set the object at the specified location to the supplied + * object. + * + * @param index The location to set the value to. + * @param obj The location to set the value to. + * @return The object which was replaced. + * throws IndexOutOfBoundsException if index < 0 || index >= size() + */ + public Object set(int index, Object obj) { + if (obj instanceof Attribute) { + Attribute attribute = (Attribute) obj; + int duplicate = indexOfDuplicate(attribute); + if ((duplicate >= 0) && (duplicate != index)) { + throw new IllegalAddException("Cannot set duplicate attribute"); + } + return set(index, attribute); + } + else if (obj == null) { + throw new IllegalAddException("Cannot add null attribute"); + } + else { + throw new IllegalAddException("Class " + + obj.getClass().getName() + + " is not an attribute"); + } + } + + /** + * Set the object at the specified location to the supplied + * object. Note: does not check for duplicate attributes. + * + * @param index The location to set the value to. + * @param attribute The attribute to set. + * @return The object which was replaced. + * throws IndexOutOfBoundsException if index < 0 || index >= size() + */ + Object set(int index, Attribute attribute) { + if (index < 0 || index >= size) + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + + if (attribute.getParent() != null) { + throw new IllegalAddException( + "The attribute already has an existing parent \"" + + attribute.getParent().getQualifiedName() + "\""); + } + + String reason = Verifier.checkNamespaceCollision(attribute, parent); + if (reason != null) { + throw new IllegalAddException(parent, attribute, reason); + } + + Attribute old = (Attribute) elementData[index]; + old.setParent(null); + + elementData[index] = attribute; + attribute.setParent(parent); + return old; + } + + /** + * Return index of attribute with same name and Namespace, or + * -1 if one doesn't exist + */ + private int indexOfDuplicate(Attribute attribute) { + int duplicate = -1; + String name = attribute.getName(); + Namespace namespace = attribute.getNamespace(); + duplicate = indexOf(name, namespace); + return duplicate; + } + + /** + * Return the number of items in this list + * + * @return The number of items in this list. + */ + public int size() { + return size; + } + + /** + * Return this list as a String + */ + public String toString() { + return super.toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/CDATA.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/CDATA.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/CDATA.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,205 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * An XML CDATA section. Represents character-based content within an XML + * document that should be output within special CDATA tags. Semantically it's + * identical to a simple {@link Text} object, but output behavior is different. + * CDATA makes no guarantees about the underlying textual representation of + * character data, but does expose that data as a Java String. + * + * @version $Revision$, $Date$ + * @author Dan Schaffer + * @author Brett McLaughlin + * @author Jason Hunter + * @author Bradley S. Huffman + * @author Victor Toni + */ +public class CDATA extends Text { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This is the protected, no-args constructor standard in all JDOM + * classes. It allows subclassers to get a raw instance with no + * initialization. + */ + protected CDATA() { } + + /** + * This constructor creates a new CDATA node, with the + * supplied string value as it's character content. + * + * @param string the node's character content. + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + * or the CDATA end delimiter ]]>. + */ + public CDATA(final String string) { + setText(string); + } + + /** + * This will set the value of this CDATA node. + * + * @param str value for node's content. + * @return the object on which the method was invoked + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + * or the CDATA end delimiter ]]>. + */ + public Text setText(final String str) { + // Overrides Text.setText() because this needs to check that CDATA rules + // are enforced. We could have a separate Verifier check for CDATA + // beyond Text and call that alone before super.setText(). + + if (str == null || "".equals(str)) { + value = EMPTY_STRING; + return this; + } + + final String reason = Verifier.checkCDATASection(str); + if (reason != null) { + throw new IllegalDataException(str, "CDATA section", reason); + } + + value = str; + + return this; + } + + /** + * This will append character content to whatever content already + * exists within this CDATA node. + * + * @param str character content to append. + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + * or the CDATA end delimiter ]]>. + */ + public void append(final String str) { + // Overrides Text.append(String) because this needs to check that CDATA + // rules are enforced. We could have a separate Verifier check for CDATA + // beyond Text and call that alone before super.setText(). + + if (str == null || "".equals(str)) { + return; + } + + // we need a temp value to ensure that the value is changed _after_ + // validation + final String tmpValue; + if (value == EMPTY_STRING) { + tmpValue = str; + } else { + tmpValue = value + str; + } + + // we have to do late checking since the end of a CDATA section could + // have been created by concating both strings: + // "]" + "]>" + // or + // "]]" + ">" + // TODO: maybe this could be optimized for this two cases + final String reason = Verifier.checkCDATASection(tmpValue); + if (reason != null) { + throw new IllegalDataException(str, "CDATA section", reason); + } + + value = tmpValue; + } + + /** + * This will append the content of another Text node + * to this node. + * + * @param text Text node to append. + */ + public void append(final Text text) { + // Overrides Text.append(Text) because this needs to check that CDATA + // rules are enforced. We could have a separate Verifier check for CDATA + // beyond Text and call that alone before super.setText(). + + if (text == null) { + return; + } + append(text.getText()); + } + + /** + * This returns a String representation of the + * CDATA node, suitable for debugging. If the XML + * representation of the CDATA node is desired, + * either {@link #getText} or + * {@link org.jdom.output.XMLOutputter#output(CDATA, java.io.Writer)} + * should be used. + * + * @return String - information about this node. + */ + public String toString() { + return new StringBuffer(64) + .append("[CDATA: ") + .append(getText()) + .append("]") + .toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/Comment.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Comment.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Comment.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,145 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * An XML comment. Methods allow the user to get and set the text of the + * comment. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class Comment extends Content { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** Text of the Comment */ + protected String text; + + /** + * Default, no-args constructor for implementations to use if needed. + */ + protected Comment() {} + + /** + * This creates the comment with the supplied text. + * + * @param text String content of comment. + */ + public Comment(String text) { + setText(text); + } + + + /** + * Returns the XPath 1.0 string value of this element, which is the + * text of this comment. + * + * @return the text of this comment + */ + public String getValue() { + return text; + } + + /** + * This returns the textual data within the Comment. + * + * @return String - text of comment. + */ + public String getText() { + return text; + } + + /** + * This will set the value of the Comment. + * + * @param text String text for comment. + * @return Comment - this Comment modified. + * @throws IllegalDataException if the given text is illegal for a + * Comment. + */ + public Comment setText(String text) { + String reason; + if ((reason = Verifier.checkCommentData(text)) != null) { + throw new IllegalDataException(text, "comment", reason); + } + + this.text = text; + return this; + } + + /** + * This returns a String representation of the + * Comment, suitable for debugging. If the XML + * representation of the Comment is desired, + * {@link org.jdom.output.XMLOutputter#outputString(Comment)} + * should be used. + * + * @return String - information about the + * Attribute + */ + public String toString() { + return new StringBuffer() + .append("[Comment: ") + .append(new org.jdom.output.XMLOutputter().outputString(this)) + .append("]") + .toString(); + } + +} Index: 3rdParty_sources/jdom/org/jdom/Content.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Content.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Content.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,192 @@ +/*-- + + $Id$ + + Copyright (C) 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.io.*; + +/** + * Superclass for JDOM objects which can be legal child content + * of {@link org.jdom.Parent} nodes. + * + * @see org.jdom.Comment + * @see org.jdom.DocType + * @see org.jdom.Element + * @see org.jdom.EntityRef + * @see org.jdom.Parent + * @see org.jdom.ProcessingInstruction + * @see org.jdom.Text + * + * @author Bradley S. Huffman + * @author Jason Hunter + * @version $Revision$, $Date$ + */ +public abstract class Content implements Cloneable, Serializable { + + protected Parent parent = null; + + protected Content() {} + + /** + * Detaches this child from its parent or does nothing if the child + * has no parent. + * + * @return this child detached + */ + public Content detach() { + if (parent != null) { + parent.removeContent(this); + } + return this; + } + + /** + * Return this child's parent, or null if this child is currently + * not attached. The parent can be either an {@link Element} + * or a {@link Document}. + * + * @return this child's parent or null if none + */ + public Parent getParent() { + return parent; + } + + /** + * A convenience method that returns any parent element for this element, + * or null if the element is unattached or is a root element. This was the + * original behavior of getParent() in JDOM Beta 9 which began returning + * Parent in Beta 10. This method provides a convenient upgrade path for + * JDOM Beta 10 and 1.0 users. + * + * @return the containing Element or null if unattached or a root element + */ + public Element getParentElement() { + Parent parent = getParent(); + return (Element) ((parent instanceof Element) ? parent : null); + } + + /** + * Sets the parent of this Content. The caller is responsible for removing + * any pre-existing parentage. + * + * @param parent new parent element + * @return the target element + */ + protected Content setParent(Parent parent) { + this.parent = parent; + return this; + } + + /** + * Return this child's owning document or null if the branch containing + * this child is currently not attached to a document. + * + * @return this child's owning document or null if none + */ + public Document getDocument() { + if (parent == null) return null; + return parent.getDocument(); + } + + + /** + * Returns the XPath 1.0 string value of this child. + * + * @return xpath string value of this child. + */ + public abstract String getValue(); + + /** + * Returns a deep, unattached copy of this child and its descendants + * detached from any parent or document. + * + * @return a detached deep copy of this child and descendants + */ + public Object clone() { + try { + Content c = (Content)super.clone(); + c.parent = null; + return c; + } catch (CloneNotSupportedException e) { + //Can not happen .... + //e.printStackTrace(); + return null; + } + } + + /** + * This tests for equality of this Content object to the supplied object. + * Content items are considered equal only if they are referentially equal + * (i.e. the same object). User code may choose to compare objects + * based on their properties instead. + * + * @param ob Object to compare to. + * @return boolean - whether the Content is + * equal to the supplied Object. + */ + public final boolean equals(Object ob) { + return (ob == this); + } + + /** + * This returns the hash code for this Content item. + * + * @return int - hash code. + */ + public final int hashCode() { + return super.hashCode(); + } +} Index: 3rdParty_sources/jdom/org/jdom/ContentList.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/ContentList.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/ContentList.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,965 @@ +/*-- + + $Id$ + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +import org.jdom.filter.*; + +/** + * A non-public list implementation holding only legal JDOM content, including + * content for Document or Element nodes. Users see this class as a simple List + * implementation. + * + * @see CDATA + * @see Comment + * @see Element + * @see EntityRef + * @see ProcessingInstruction + * @see Text + * + * @version $Revision$, $Date$ + * @author Alex Rosen + * @author Philippe Riand + * @author Bradley S. Huffman + */ +final class ContentList extends AbstractList implements java.io.Serializable { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + private static final long serialVersionUID = 1L; + + private static final int INITIAL_ARRAY_SIZE = 5; + + /** Our backing list */ + private Content elementData[]; + private int size; + + /** Document or Element this list belongs to */ + private Parent parent; + + /** Force either a Document or Element parent */ + ContentList(Parent parent) { + this.parent = parent; + } + + /** + * Package internal method to support building from sources that are + * 100% trusted. + * + * @param c content to add without any checks + */ + final void uncheckedAddContent(Content c) { + c.parent = parent; + ensureCapacity(size + 1); + elementData[size++] = c; + modCount++; + } + + /** + * Inserts the specified object at the specified position in this list. + * Shifts the object currently at that position (if any) and any + * subsequent objects to the right (adds one to their indices). + * + * @param index The location to set the value to. + * @param obj The object to insert into the list. + * throws IndexOutOfBoundsException if index < 0 || index > size() + */ + public void add(int index, Object obj) { + if (obj == null) { + throw new IllegalAddException("Cannot add null object"); + } + if (obj instanceof String) { // String is OK to add as special case + obj = new Text(obj.toString()); // wrap it as a Content + } + if ((obj instanceof Content)) { + add(index, (Content) obj); + } else { + throw new IllegalAddException("Class " + + obj.getClass().getName() + + " is of unrecognized type and cannot be added"); + } + } + + /** + * @see org.jdom.ContentList#add(int, org.jdom.Content) + */ + private void documentCanContain(int index, Content child) throws IllegalAddException { + if (child instanceof Element) { + if (indexOfFirstElement() >= 0) { + throw new IllegalAddException( + "Cannot add a second root element, only one is allowed"); + } + if (indexOfDocType() >= index) { + throw new IllegalAddException( + "A root element cannot be added before the DocType"); + } + } + if (child instanceof DocType) { + if (indexOfDocType() >= 0) { + throw new IllegalAddException( + "Cannot add a second doctype, only one is allowed"); + } + int firstElt = indexOfFirstElement(); + if (firstElt != -1 && firstElt < index) { + throw new IllegalAddException( + "A DocType cannot be added after the root element"); + } + } + if (child instanceof CDATA) { + throw new IllegalAddException("A CDATA is not allowed at the document root"); + } + + if (child instanceof Text) { + throw new IllegalAddException("A Text is not allowed at the document root"); + } + + if (child instanceof EntityRef) { + throw new IllegalAddException("An EntityRef is not allowed at the document root"); + } + } + + private static void elementCanContain(int index, Content child) throws IllegalAddException { + if (child instanceof DocType) { + throw new IllegalAddException( + "A DocType is not allowed except at the document level"); + } + } + + /** + * Check and add the Element to this list at + * the given index. + * + * @param index index where to add Element + * @param child Element to add + */ + void add(int index, Content child) { + if (child == null) { + throw new IllegalAddException("Cannot add null object"); + } + if (parent instanceof Document) { + documentCanContain(index, child); + } + else { + elementCanContain(index, child); + } + + if (child.getParent() != null) { + Parent p = child.getParent(); + if (p instanceof Document) { + throw new IllegalAddException((Element)child, + "The Content already has an existing parent document"); + } + else { + throw new IllegalAddException( + "The Content already has an existing parent \"" + + ((Element)p).getQualifiedName() + "\""); + } + } + + if (child == parent) { + throw new IllegalAddException( + "The Element cannot be added to itself"); + } + + // Detect if we have and c.add(a) + if ((parent instanceof Element && child instanceof Element) && + ((Element) child).isAncestor((Element)parent)) { + throw new IllegalAddException( + "The Element cannot be added as a descendent of itself"); + } + + if (index<0 || index>size) { + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + } + + child.setParent(parent); + + ensureCapacity(size+1); + if( index==size ) { + elementData[size++] = child; + } else { + System.arraycopy(elementData, index, elementData, index + 1, size - index); + elementData[index] = child; + size++; + } + modCount++; + } + + /** + * Add the specified collecton to the end of this list. + * + * @param collection The collection to add to the list. + * @return true if the list was modified as a result of + * the add. + */ + public boolean addAll(Collection collection) { + return addAll(size(), collection); + } + + /** + * Inserts the specified collecton at the specified position in this list. + * Shifts the object currently at that position (if any) and any + * subsequent objects to the right (adds one to their indices). + * + * @param index The offset to start adding the data in the collection + * @param collection The collection to insert into the list. + * @return true if the list was modified as a result of + * the add. + * throws IndexOutOfBoundsException if index < 0 || index > size() + */ + public boolean addAll(int index, Collection collection) { + if (index<0 || index>size) { + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + } + + if ((collection == null) || (collection.size() == 0)) { + return false; + } + ensureCapacity(size() + collection.size()); + + int count = 0; + try { + Iterator i = collection.iterator(); + while (i.hasNext()) { + Object obj = i.next(); + add(index + count, obj); + count++; + } + } + catch (RuntimeException exception) { + for (int i = 0; i < count; i++) { + remove(index); + } + throw exception; + } + + return true; + } + + /** + * Clear the current list. + */ + public void clear() { + if (elementData != null) { + for (int i = 0; i < size; i++) { + Content obj = elementData[i]; + removeParent(obj); + } + elementData = null; + size = 0; + } + modCount++; + } + + /** + * Clear the current list and set it to the contents + * of the Collection. + * object. + * + * @param collection The collection to use. + */ + void clearAndSet(Collection collection) { + Content[] old = elementData; + int oldSize = size; + + elementData = null; + size = 0; + + if ((collection != null) && (collection.size() != 0)) { + ensureCapacity(collection.size()); + try { + addAll(0, collection); + } + catch (RuntimeException exception) { + elementData = old; + size = oldSize; + throw exception; + } + } + + if (old != null) { + for (int i = 0; i < oldSize; i++) { + removeParent(old[i]); + } + } + modCount++; + } + + /** + * Increases the capacity of this ContentList instance, + * if necessary, to ensure that it can hold at least the number of + * items specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity. + */ + void ensureCapacity(int minCapacity) { + if( elementData==null ) { + elementData = new Content[Math.max(minCapacity, INITIAL_ARRAY_SIZE)]; + } else { + int oldCapacity = elementData.length; + if (minCapacity > oldCapacity) { + Object oldData[] = elementData; + int newCapacity = (oldCapacity * 3)/2 + 1; + if (newCapacity < minCapacity) + newCapacity = minCapacity; + elementData = new Content[newCapacity]; + System.arraycopy(oldData, 0, elementData, 0, size); + } + } + } + + /** + * Return the object at the specified offset. + * + * @param index The offset of the object. + * @return The Object which was returned. + */ + public Object get(int index) { + if (index<0 || index>=size) { + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + } + return elementData[index]; + } + + /** + * Return a view of this list based on the given filter. + * + * @param filter Filter for this view. + * @return a list representing the rules of the Filter. + */ + List getView(Filter filter) { + return new FilterList(filter); + } + + /** + * Return the index of the first Element in the list. If the parent + * is a Document then the element is the root element. + * If the list contains no Elements, it returns -1. + * + * @return index of first element, or -1 if one doesn't exist + */ + int indexOfFirstElement() { + if( elementData!=null ) { + for (int i = 0; i < size; i++) { + if (elementData[i] instanceof Element) { + return i; + } + } + } + return -1; + } + + /** + * Return the index of the DocType element in the list. If the list contains + * no DocType, it returns -1. + * + * @return index of the DocType, or -1 if it doesn't + * exist + */ + int indexOfDocType() { + if (elementData != null) { + for (int i = 0; i < size; i++) { + if (elementData[i] instanceof DocType) { + return i; + } + } + } + return -1; + } + + /** + * Remove the object at the specified offset. + * + * @param index The offset of the object. + * @return The Object which was removed. + */ + public Object remove(int index) { + if (index<0 || index>=size) + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + + Content old = elementData[index]; + removeParent(old); + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index,numMoved); + elementData[--size] = null; // Let gc do its work + modCount++; + return old; + } + + + /** Remove the parent of a Object */ + private static void removeParent(Content c) { + c.setParent(null); + } + + /** + * Set the object at the specified location to the supplied + * object. + * + * @param index The location to set the value to. + * @param obj The location to set the value to. + * @return The object which was replaced. + * throws IndexOutOfBoundsException if index < 0 || index >= size() + */ + public Object set(int index, Object obj) { + if (index<0 || index>=size) + throw new IndexOutOfBoundsException("Index: " + index + + " Size: " + size()); + + if ((obj instanceof Element) && (parent instanceof Document)) { + int root = indexOfFirstElement(); + if ((root >= 0) && (root != index)) { + throw new IllegalAddException( + "Cannot add a second root element, only one is allowed"); + } + } + + if ((obj instanceof DocType) && (parent instanceof Document)) { + int docTypeIndex = indexOfDocType(); + if ((docTypeIndex >= 0) && (docTypeIndex != index)) { + throw new IllegalAddException( + "Cannot add a second doctype, only one is allowed"); + } + } + + Object old = remove(index); + try { + add(index, obj); + } + catch (RuntimeException exception) { + add(index, old); + throw exception; + } + return old; + } + + /** + * Return the number of items in this list + * + * @return The number of items in this list. + */ + public int size() { + return size; + } + + /** + * Return this list as a String + * + * @return The number of items in this list. + */ + public String toString() { + return super.toString(); + } + + /** Give access of ContentList.modCount to FilterList */ + private int getModCount() { + return modCount; + } + + /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */ + /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */ + + /** + * FilterList represents legal JDOM content, including content + * for Documents or Elements. + */ + + class FilterList extends AbstractList implements java.io.Serializable { + + /** The Filter */ + Filter filter; + + /** Current number of items in this view */ + int count = 0; + + /** Expected modCount in our backing list */ + int expected = -1; + + // Implementation Note: Directly after size() is called, expected + // is sync'd with ContentList.modCount and count provides + // the true size of this view. Before the first call to + // size() or if the backing list is modified outside this + // FilterList, both might contain bogus values and should + // not be used without first calling size(); + + /** + * Create a new instance of the FilterList with the specified Filter. + */ + FilterList(Filter filter) { + this.filter = filter; + } + + /** + * Inserts the specified object at the specified position in this list. + * Shifts the object currently at that position (if any) and any + * subsequent objects to the right (adds one to their indices). + * + * @param index The location to set the value to. + * @param obj The object to insert into the list. + * throws IndexOutOfBoundsException if index < 0 || index > size() + */ + public void add(int index, Object obj) { + if (filter.matches(obj)) { + int adjusted = getAdjustedIndex(index); + ContentList.this.add(adjusted, obj); + expected++; + count++; + } + else throw new IllegalAddException("Filter won't allow the " + + obj.getClass().getName() + + " '" + obj + "' to be added to the list"); + } + + /** + * Return the object at the specified offset. + * + * @param index The offset of the object. + * @return The Object which was returned. + */ + public Object get(int index) { + int adjusted = getAdjustedIndex(index); + return ContentList.this.get(adjusted); + } + + public Iterator iterator() { + return new FilterListIterator(filter, 0); + } + + public ListIterator listIterator() { + return new FilterListIterator(filter, 0); + } + + public ListIterator listIterator(int index) { + return new FilterListIterator(filter, index); + } + + /** + * Remove the object at the specified offset. + * + * @param index The offset of the object. + * @return The Object which was removed. + */ + public Object remove(int index) { + int adjusted = getAdjustedIndex(index); + Object old = ContentList.this.get(adjusted); + if (filter.matches(old)) { + old = ContentList.this.remove(adjusted); + expected++; + count--; + } + else { + throw new IllegalAddException("Filter won't allow the " + + (old.getClass()).getName() + + " '" + old + "' (index " + index + + ") to be removed"); + } + return old; + } + + /** + * Set the object at the specified location to the supplied + * object. + * + * @param index The location to set the value to. + * @param obj The location to set the value to. + * @return The object which was replaced. + * throws IndexOutOfBoundsException if index < 0 || index >= size() + */ + public Object set(int index, Object obj) { + Object old = null; + if (filter.matches(obj)) { + int adjusted = getAdjustedIndex(index); + old = ContentList.this.get(adjusted); + if (!filter.matches(old)) { + throw new IllegalAddException("Filter won't allow the " + + (old.getClass()).getName() + + " '" + old + "' (index " + index + + ") to be removed"); + } + old = ContentList.this.set(adjusted, obj); + expected += 2; + } + else { + throw new IllegalAddException("Filter won't allow index " + + index + " to be set to " + + (obj.getClass()).getName()); + } + return old; + } + + /** + * Return the number of items in this list + * + * @return The number of items in this list. + */ + public int size() { + // Implementation Note: Directly after size() is called, expected + // is sync'd with ContentList.modCount and count provides + // the true size of this view. Before the first call to + // size() or if the backing list is modified outside this + // FilterList, both might contain bogus values and should + // not be used without first calling size(); + + if (expected == ContentList.this.getModCount()) { + return count; + } + + count = 0; + for (int i = 0; i < ContentList.this.size(); i++) { + Object obj = ContentList.this.elementData[i]; + if (filter.matches(obj)) { + count++; + } + } + expected = ContentList.this.getModCount(); + return count; + } + + /** + * Return the adjusted index + * + * @param index Index of in this view. + * @return True index in backing list + */ + final private int getAdjustedIndex(int index) { + int adjusted = 0; + for (int i = 0; i < ContentList.this.size; i++) { + Object obj = ContentList.this.elementData[i]; + if (filter.matches(obj)) { + if (index == adjusted) { + return i; + } + adjusted++; + } + } + + if (index == adjusted) { + return ContentList.this.size; + } + + return ContentList.this.size + 1; + } + } + + /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */ + /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */ + + class FilterListIterator implements ListIterator { + + /** The Filter that applies */ + Filter filter; + + /** Whether this iterator is in forward or reverse. */ + private boolean forward = false; + /** Whether a call to remove() is valid */ + private boolean canremove = false; + /** Whether a call to set() is valid */ + private boolean canset = false; + + /** Index in backing list of next object */ + private int cursor = -1; + /** the backing index to use if we actually DO move */ + private int tmpcursor = -1; + /** Index in ListIterator */ + private int index = -1; + + /** Expected modCount in our backing list */ + private int expected = -1; + + /** Number of elements matching the filter. */ + private int fsize = 0; + + /** + * Default constructor + */ + FilterListIterator(Filter filter, int start) { + this.filter = filter; + expected = ContentList.this.getModCount(); + // always start list iterators in backward mode .... + // it makes sense... really. + forward = false; + + if (start < 0) { + throw new IndexOutOfBoundsException("Index: " + start); + } + + // the number of matching elements.... + fsize = 0; + + // go through the list, count the matching elements... + for (int i = 0; i < ContentList.this.size(); i++) { + if (filter.matches(ContentList.this.get(i))) { + if (start == fsize) { + // set the back-end cursor to the matching element.... + cursor = i; + // set the front-end cursor too. + index = fsize; + } + fsize++; + } + } + + if (start > fsize) { + throw new IndexOutOfBoundsException("Index: " + start + " Size: " + fsize); + } + if (cursor == -1) { + // implies that start == fsize (i.e. after the last element + // put the insertion point at the end of the Underlying + // content list .... + // i.e. an add() at this point may potentially end up with + // filtered content between previous() and next() + // the alternative is to put the cursor on the Content after + // the last Content that the filter passed + // The implications are ambiguous. + cursor = ContentList.this.size(); + index = fsize; + } + + } + + /** + * Returns true if this list iterator has a next element. + */ + public boolean hasNext() { + return nextIndex() < fsize; + } + + /** + * Returns the next element in the list. + */ + public Object next() { + if (!hasNext()) + throw new NoSuchElementException("next() is beyond the end of the Iterator"); + index = nextIndex(); + cursor = tmpcursor; + forward = true; + canremove = true; + canset = true; + return ContentList.this.get(cursor); + } + + /** + * Returns true if this list iterator has more elements + * when traversing the list in the reverse direction. + */ + public boolean hasPrevious() { + return previousIndex() >= 0; + } + + /** + * Returns the previous element in the list. + */ + public Object previous() { + if (!hasPrevious()) + throw new NoSuchElementException("previous() is before the start of the Iterator"); + index = previousIndex(); + cursor = tmpcursor; + forward = false; + canremove = true; + canset = true; + return ContentList.this.get(cursor); + } + + /** + * Returns the index of the element that would be returned by a + * subsequent call to next. + */ + public int nextIndex() { + checkConcurrentModification(); + if (forward) { + // Starting with next possibility .... + for (int i = cursor + 1; i < ContentList.this.size(); i++) { + if (filter.matches(ContentList.this.get(i))) { + tmpcursor = i; + return index + 1; + } + } + // Never found another match.... put the insertion point at + // the end of the list.... + tmpcursor = ContentList.this.size(); + return index + 1; + } + + // We've been going back... so nextIndex() returns the same + // element. + tmpcursor = cursor; + return index; + } + + /** + * Returns the index of the element that would be returned by a + * subsequent call to previous. (Returns -1 if the + * list iterator is at the beginning of the list.) + */ + public int previousIndex() { + checkConcurrentModification(); + if (!forward) { + // starting with next possibility .... + for (int i = cursor - 1; i >= 0; i--) { + if (filter.matches(ContentList.this.get(i))) { + tmpcursor = i; + return index - 1; + } + } + // Never found another match.... put the insertion point at + // the start of the list.... + tmpcursor = -1; + return index - 1; + } + + // We've been going forwards... so previousIndex() returns same + // element. + tmpcursor = cursor; + return index; + } + + /** + * Inserts the specified element into the list. + */ + public void add(Object obj) { + if (!filter.matches(obj)) { + throw new IllegalAddException("Filter won't allow the " + + obj.getClass().getName() + + " '" + obj + "' to be added to the list"); + } + + // Call to nextIndex() will check concurrent. + nextIndex(); + // tmpcursor is the backing cursor of the next element + // Remember that List.add(index,obj) is really an insert.... + ContentList.this.add(tmpcursor, obj); + expected = ContentList.this.getModCount(); + canremove = canset = false; + + if (forward) { + index++; + } else { + forward = true; + } + fsize++; + cursor = tmpcursor; + } + + /** + * Removes from the list the last element that was returned by + * the last call to next or previous. + */ + public void remove() { + if (!canremove) + throw new IllegalStateException("Can not remove an " + + "element unless either next() or previous() has been called " + + "since the last remove()"); + // we are removing the last entry reuned by either next() or previous(). + // the idea is to remove it, and pretend that we used to be at the + // entry that happened *after* the removed entry. + // so, get what would be the next entry (set at tmpcursor). + // so call nextIndex to set tmpcursor to what would come after. + boolean dir = forward; + forward = true; + try { + nextIndex(); + ContentList.this.remove(cursor); + } finally { + forward = dir; + } + cursor = tmpcursor - 1; + expected = ContentList.this.getModCount(); + + forward = false; + canremove = false; + canset = false; + fsize--; + } + + /** + * Replaces the last element returned by next or + * previous with the specified element. + */ + public void set(Object obj) { + if (!canset) + throw new IllegalStateException("Can not set an element " + + "unless either next() or previous() has been called since the " + + "last remove() or set()"); + checkConcurrentModification(); + + if (!filter.matches(obj)) { + throw new IllegalAddException("Filter won't allow index " + index + " to be set to " + + (obj.getClass()).getName()); + } + + ContentList.this.set(cursor, obj); + expected = ContentList.this.getModCount(); + + } + + /** + * Check if are backing list is being modified by someone else. + */ + private void checkConcurrentModification() { + if (expected != ContentList.this.getModCount()) { + throw new ConcurrentModificationException(); + } + } + } +} Index: 3rdParty_sources/jdom/org/jdom/DataConversionException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/DataConversionException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/DataConversionException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,87 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * Thrown when a data conversion from a string to value type fails, such as + * can happen with the {@link Attribute} convenience getter functions. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class DataConversionException extends JDOMException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Constructs an exception where the named construct couldn't be converted + * to the named data type. + * + * @param name name of the construct whose value failed conversion + * @param dataType type the conversion was attempting to create + */ + public DataConversionException(String name, String dataType) { + super(new StringBuffer() + .append("The XML construct ") + .append(name) + .append(" could not be converted to a ") + .append(dataType) + .toString()); + } +} Index: 3rdParty_sources/jdom/org/jdom/DefaultJDOMFactory.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/DefaultJDOMFactory.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/DefaultJDOMFactory.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,191 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * Creates the standard top-level JDOM classes (Element, Document, Comment, + * etc). A subclass of this factory might construct custom classes. + * + * @version $Revision$, $Date$ + * @author Ken Rune Holland + * @author Phil Nelson + * @author Bradley S. Huffman + */ +public class DefaultJDOMFactory implements JDOMFactory { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + public DefaultJDOMFactory() { } + + // Allow Javadocs to inherit from JDOMFactory + + public Attribute attribute(String name, String value, Namespace namespace) { + return new Attribute(name, value, namespace); + } + + public Attribute attribute(String name, String value, + int type, Namespace namespace) { + return new Attribute(name, value, type, namespace); + } + + public Attribute attribute(String name, String value) { + return new Attribute(name, value); + } + + public Attribute attribute(String name, String value, int type) { + return new Attribute(name, value, type); + } + + public CDATA cdata(String text) { + return new CDATA(text); + } + + public Text text(String text) { + return new Text(text); + } + + public Comment comment(String text) { + return new Comment(text); + } + + public DocType docType(String elementName, + String publicID, String systemID) { + return new DocType(elementName, publicID, systemID); + } + + public DocType docType(String elementName, String systemID) { + return new DocType(elementName, systemID); + } + + public DocType docType(String elementName) { + return new DocType(elementName); + } + + public Document document(Element rootElement, DocType docType) { + return new Document(rootElement, docType); + } + + public Document document(Element rootElement, DocType docType, String baseURI) { + return new Document(rootElement, docType, baseURI); + } + + public Document document(Element rootElement) { + return new Document(rootElement); + } + + public Element element(String name, Namespace namespace) { + return new Element(name, namespace); + } + + public Element element(String name) { + return new Element(name); + } + + public Element element(String name, String uri) { + return new Element(name, uri); + } + + public Element element(String name, String prefix, String uri) { + return new Element(name, prefix, uri); + } + + public ProcessingInstruction processingInstruction(String target, + Map data) { + return new ProcessingInstruction(target, data); + } + + public ProcessingInstruction processingInstruction(String target, + String data) { + return new ProcessingInstruction(target, data); + } + + public EntityRef entityRef(String name) { + return new EntityRef(name); + } + + public EntityRef entityRef(String name, String publicID, String systemID) { + return new EntityRef(name, publicID, systemID); + } + + public EntityRef entityRef(String name, String systemID) { + return new EntityRef(name, systemID); + } + + // ===================================================================== + // List manipulation + // ===================================================================== + + public void addContent(Parent parent, Content child) { + if (parent instanceof Document) { + ((Document) parent).addContent(child); + } + else { + ((Element) parent).addContent(child); + } + } + + public void setAttribute(Element parent, Attribute a) { + parent.setAttribute(a); + } + + public void addNamespaceDeclaration(Element parent, Namespace additional) { + parent.addNamespaceDeclaration(additional); + } +} Index: 3rdParty_sources/jdom/org/jdom/DescendantIterator.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/DescendantIterator.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/DescendantIterator.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,173 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; +import org.jdom.Content; +import org.jdom.Element; +import org.jdom.Parent; + +/** + * Traverse all a parent's descendants (all children at any level below + * the parent). + * + * @author Bradley S. Huffman + * @author Jason Hunter + * @version $Revision$, $Date$ + */ +class DescendantIterator implements Iterator { + + private Iterator iterator; + private Iterator nextIterator; + private List stack = new ArrayList(); + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Iterator for the descendants of the supplied object. + * + * @param parent document or element whose descendants will be iterated + */ + DescendantIterator(Parent parent) { + if (parent == null) { + throw new IllegalArgumentException("parent parameter was null"); + } + this.iterator = parent.getContent().iterator(); + } + + /** + * Returns true> if the iteration has more {@link Content} descendants. + * + * @return true is the iterator has more descendants + */ + public boolean hasNext() { + if (iterator != null && iterator.hasNext()) return true; + if (nextIterator != null && nextIterator.hasNext()) return true; + if (stackHasAnyNext()) return true; + return false; + } + + /** + * Returns the next {@link Content} descendant. + * + * @return the next descendant + */ + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + // If we need to descend, go for it and record where we are. + // We do the shuffle here on the next next() call so remove() is easy + // to code up. + if (nextIterator != null) { + push(iterator); + iterator = nextIterator; + nextIterator = null; + } + + // If this iterator is finished, try moving up the stack + while (!iterator.hasNext()) { + if (stack.size() > 0) { + iterator = pop(); + } + else { + throw new NoSuchElementException("Somehow we lost our iterator"); + } + } + + Content child = (Content) iterator.next(); + if (child instanceof Element) { + nextIterator = ((Element)child).getContent().iterator(); + } + return child; + } + + /** + * Detaches the last {@link org.jdom.Content} returned by the last call to + * next from it's parent. Note: this does not affect + * iteration and all children, siblings, and any node following the + * removed node (in document order) will be visited. + */ + public void remove() { + iterator.remove(); + } + + private Iterator pop() { + int stackSize = stack.size(); + if (stackSize == 0) { + throw new NoSuchElementException("empty stack"); + } + return (Iterator) stack.remove(stackSize - 1); + } + + private void push(Iterator itr) { + stack.add(itr); + } + + private boolean stackHasAnyNext() { + int size = stack.size(); + for (int i = 0; i < size; i++) { + Iterator itr = (Iterator) stack.get(i); + if (itr.hasNext()) { + return true; + } + } + return false; + } +} Index: 3rdParty_sources/jdom/org/jdom/DocType.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/DocType.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/DocType.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,280 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * An XML DOCTYPE declaration. Method allow the user to get and set the + * root element name, public id, and system id. + * + * @author Brett McLaughlin + * @author Jason Hunter + * @version $Revision$, $Date$ + */ +public class DocType extends Content { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The element being constrained */ + protected String elementName; + + /** The public ID of the DOCTYPE */ + protected String publicID; + + /** The system ID of the DOCTYPE */ + protected String systemID; + + /** The internal subset of the DOCTYPE */ + protected String internalSubset; + + /** + * Default, no-args constructor for implementations to use if needed. + */ + protected DocType() {} + + /* + * XXX: + * We need to take care of entities and notations here. + */ + + /** + * This will create the DocType with + * the specified element name and a reference to an + * external DTD. + * + * @param elementName String name of + * element being constrained. + * @param publicID String public ID of + * referenced DTD + * @param systemID String system ID of + * referenced DTD + * @throws IllegalDataException if the given system ID is not a legal + * system literal or the public ID is not a legal public ID. + * @throws IllegalNameException if the given root element name is not a + * legal XML element name. + */ + public DocType(String elementName, String publicID, String systemID) { + setElementName(elementName); + setPublicID(publicID); + setSystemID(systemID); + } + + /** + * This will create the DocType with + * the specified element name and reference to an + * external DTD. + * + * @param elementName String name of + * element being constrained. + * @param systemID String system ID of + * referenced DTD + * @throws IllegalDataException if the given system ID is not a legal + * system literal. + * @throws IllegalNameException if the given root element name is not a + * legal XML element name. + */ + public DocType(String elementName, String systemID) { + this(elementName, null, systemID); + } + + /** + * This will create the DocType with + * the specified element name + * + * @param elementName String name of + * element being constrained. + * @throws IllegalNameException if the given root element name is not a + * legal XML element name. + */ + public DocType(String elementName) { + this(elementName, null, null); + } + + /** + * This will retrieve the element name being constrained. + * + * @return String - element name for DOCTYPE + */ + public String getElementName() { + return elementName; + } + + /** + * This will set the root element name declared by this + * DOCTYPE declaration. + * + * @return DocType DocType this DocType object + * @param elementName String name of + * root element being constrained. + * @throws IllegalNameException if the given root element name is not a + * legal XML element name. + */ + public DocType setElementName(String elementName) { + // This can contain a colon so we use checkXMLName() + // instead of checkElementName() + String reason = Verifier.checkXMLName(elementName); + if (reason != null) { + throw new IllegalNameException(elementName, "DocType", reason); + } + this.elementName = elementName; + return this; + } + + /** + * This will retrieve the public ID of an externally + * referenced DTD, or an empty String if + * none is referenced. + * + * @return String - public ID of referenced DTD. + */ + public String getPublicID() { + return publicID; + } + + /** + * This will set the public ID of an externally + * referenced DTD. + * + * @param publicID id to set + * @return DocType DocType this DocType object + * @throws IllegalDataException if the given public ID is not a legal + * public ID. + */ + public DocType setPublicID(String publicID) { + String reason = Verifier.checkPublicID(publicID); + if (reason != null) { + throw new IllegalDataException(publicID, "DocType", reason); + } + this.publicID = publicID; + + return this; + } + + /** + * This will retrieve the system ID of an externally + * referenced DTD, or an empty String if + * none is referenced. + * + * @return String - system ID of referenced DTD. + */ + public String getSystemID() { + return systemID; + } + + /** + * This will set the system ID of an externally + * referenced DTD. + * + * @param systemID id to set + * @return systemID String system ID of + * referenced DTD. + * @throws IllegalDataException if the given system ID is not a legal + * system literal. + */ + public DocType setSystemID(String systemID) { + String reason = Verifier.checkSystemLiteral(systemID); + if (reason != null) { + throw new IllegalDataException(systemID, "DocType", reason); + } + this.systemID = systemID; + + return this; + } + + /** + * Returns the empty string since doctypes don't have an XPath + * 1.0 string value. + * @return the empty string + */ + public String getValue() { + return ""; // doctypes don't have an XPath string value + } + + /** + * This sets the data for the internal subset. + * + * @param newData data for the internal subset, as a + * String. + */ + public void setInternalSubset(String newData) { + internalSubset = newData; + } + + /** + * This returns the data for the internal subset. + * + * @return String - the internal subset + */ + public String getInternalSubset() { + return internalSubset; + } + + /** + * This returns a String representation of the + * DocType, suitable for debugging. + * + * @return String - information about the + * DocType + */ + public String toString() { + return new StringBuffer() + .append("[DocType: ") + .append(new org.jdom.output.XMLOutputter().outputString(this)) + .append("]") + .toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/Document.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Document.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Document.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,766 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +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$, $Date$ + * @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$ $Revision$ $Date$ $Name$"; + + /** + * 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 Document, + * with the supplied {@link Element} + * as the root element, the supplied + * {@link DocType} declaration, and the specified + * base URI. + * + * @param rootElement Element for document root. + * @param docType DocType 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 Document, + * with the supplied {@link Element} + * as the root element and the supplied + * {@link DocType} declaration. + * + * @param rootElement Element for document root. + * @param docType DocType 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 Document, + * with the supplied {@link Element} + * as the root element, and no {@link DocType} + * declaration. + * + * @param rootElement Element 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 Document, + * with the supplied list of content, and a + * {@link DocType} declaration only if the content + * contains a DocType instance. A null list is treated the + * same as the no-arg constructor. + * + * @param content List 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 true if this document has a + * root element, false otherwise. + * + * @return true if this document has a root element, + * false otherwise. + */ + public boolean hasRootElement() { + return (content.indexOfFirstElement() < 0) ? false : true; + } + + /** + * This will return the root Element + * for this Document + * + * @return Element - 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 {@link Element} for the + * Document. If the document already has a root + * element, it is replaced. + * + * @param rootElement Element to be new root. + * @return Document - 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 {@link Element} from this document. + * + * @return removed root Element + */ + public Element detachRootElement() { + int index = content.indexOfFirstElement(); + if (index < 0) + return null; + return (Element) removeContent(index); + } + + /** + * This will return the {@link DocType} + * declaration for this Document, or + * null if none exists. + * + * @return DocType - 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 {@link DocType} + * declaration for this Document. 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 DocType 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 Document. + * The returned list is "live" in document order and changes to it + * affect the document's actual content. + * + *

+ * Sequential traversal through the List is best done with a Iterator + * since the underlying implement of List.size() may require walking the + * entire list. + *

+ * + * @return List - 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 Document's content. + * + *

+ * Sequential traversal through the List is best done with a Iterator + * since the underlying implement of List.size() may require walking the + * entire list. + *

+ * + * @param filter Filter to apply + * @return List - 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 Document. The supplied + * List should contain only objects of type Element, + * Comment, and ProcessingInstruction. + * + *

+ * 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. + *

+ * + *

+ * Passing a null or empty List clears the existing content. + *

+ * + *

+ * In event of an exception the original content will be unchanged and + * the objects in the supplied content will be unaltered. + *

+ * + * @param newContent List 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; + } + + /** + * + *

+ * Sets the effective URI from which this document was loaded, + * and against which relative URLs in this document will be resolved. + *

+ * + * @param uri the base URI of this document + */ + public final void setBaseURI(String uri) { + this.baseURI = uri; // XXX We don't check the URI + } + + /** + *

+ * Returns the URI from which this document was loaded, + * or null if this is not known. + *

+ * + * @return the base URI of this document + */ + public final String getBaseURI() { + return baseURI; + } + + /* + * Replace the current child the given index with the supplied child. + *

+ * In event of an exception the original content will be unchanged and + * the supplied child will be unaltered. + *

+ * + * @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. + *

+ * In event of an exception the original content will be unchanged and + * the content in the supplied collection will be unaltered. + *

+ * + * @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. + *

+ * 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. + *

+ * 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 "live" 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 "live" + * version of the children. + *

+ * Passing a null child clears the existing content. + *

+ * 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 String representation of the + * Document, suitable for debugging. If the XML + * representation of the Document is desired, + * {@link org.jdom.output.XMLOutputter#outputString(Document)} + * should be used. + * + * @return String - information about the + * Document + */ + 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, "); + } + + if (hasRootElement()) { + stringForm.append("Root is ") + .append(getRootElement().toString()); + } else { + stringForm.append(" No root element"); // shouldn't happen + } + + stringForm.append("]"); + + return stringForm.toString(); + } + + /** + * This tests for equality of this Document to the supplied + * Object. + * + * @param ob Object to compare to + * @return boolean whether the Document is + * equal to the supplied Object + */ + public final boolean equals(Object ob) { + return (ob == this); + } + + /** + * This returns the hash code for this Document. + * + * @return int hash code + */ + public final int hashCode() { + return super.hashCode(); + } + + /** + * This will return a deep clone of this Document. + * + * @return Object clone of this Document + */ + 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); + } +} Index: 3rdParty_sources/jdom/org/jdom/Element.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Element.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Element.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,1585 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.io.*; +import java.util.*; + +import org.jdom.filter.*; + +/** + * An XML element. Methods allow the user to get and manipulate its child + * elements and content, directly access the element's textual content, + * manipulate its attributes, and manage namespaces. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Lucas Gonze + * @author Kevin Regan + * @author Dan Schaffer + * @author Yusuf Goolamabbas + * @author Kent C. Johnson + * @author Jools Enticknap + * @author Alex Rosen + * @author Bradley S. Huffman + * @author Victor Toni + */ +public class Element extends Content implements Parent { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + private static final int INITIAL_ARRAY_SIZE = 5; + + /** The local name of the element */ + protected String name; + + /** The namespace of the element */ + protected transient Namespace namespace; + + /** Additional namespace declarations to store on this element; useful + * during output */ + protected transient List additionalNamespaces; + + // See http://lists.denveronline.net/lists/jdom-interest/2000-September/003030.html + // for a possible memory optimization here (using a RootElement subclass) + + /** + * The attributes of the element. Subclassers have to + * track attributes using their own mechanism. + */ + AttributeList attributes = new AttributeList(this); + + /** + * The content of the element. Subclassers have to + * track content using their own mechanism. + */ + ContentList content = new ContentList(this); + + /** + * This protected constructor is provided in order to support an Element + * subclass that wants full control over variable initialization. It + * intentionally leaves all instance variables null, allowing a lightweight + * subclass implementation. The subclass is responsible for ensuring all the + * get and set methods on Element behave as documented. + *

+ * When implementing an Element subclass which doesn't require full control + * over variable initialization, be aware that simply calling super() (or + * letting the compiler add the implicit super() call) will not initialize + * the instance variables which will cause many of the methods to throw a + * NullPointerException. Therefore, the constructor for these subclasses + * should call one of the public constructors so variable initialization is + * handled automatically. + */ + protected Element() { } + + /** + * Creates a new element with the supplied (local) name and namespace. If + * the provided namespace is null, the element will have no namespace. + * + * @param name local name of the element + * @param namespace namespace for the element + * @throws IllegalNameException if the given name is illegal as an element + * name + */ + public Element(final String name, final Namespace namespace) { + setName(name); + setNamespace(namespace); + } + + /** + * Create a new element with the supplied (local) name and no namespace. + * + * @param name local name of the element + * @throws IllegalNameException if the given name is illegal as an element + * name. + */ + public Element(final String name) { + this(name, (Namespace) null); + } + + /** + * Creates a new element with the supplied (local) name and a namespace + * given by a URI. The element will be put into the unprefixed (default) + * namespace. + * + * @param name name of the element + * @param uri namespace URI for the element + * @throws IllegalNameException if the given name is illegal as an element + * name or the given URI is illegal as a + * namespace URI + */ + public Element(final String name, final String uri) { + this(name, Namespace.getNamespace("", uri)); + } + + /** + * Creates a new element with the supplied (local) name and a namespace + * given by the supplied prefix and URI combination. + * + * @param name local name of the element + * @param prefix namespace prefix + * @param uri namespace URI for the element + * @throws IllegalNameException if the given name is illegal as an element + * name, the given prefix is illegal as a + * namespace prefix, or the given URI is + * illegal as a namespace URI + */ + public Element(final String name, final String prefix, final String uri) { + this(name, Namespace.getNamespace(prefix, uri)); + } + + /** + * Returns the (local) name of the element (without any namespace prefix). + * + * @return local element name + */ + public String getName() { + return name; + } + + /** + * Sets the (local) name of the element. + * + * @param name the new (local) name of the element + * @return the target element + * @throws IllegalNameException if the given name is illegal as an Element + * name + */ + public Element setName(final String name) { + final String reason = Verifier.checkElementName(name); + if (reason != null) { + throw new IllegalNameException(name, "element", reason); + } + this.name = name; + return this; + } + + /** + * Returns the element's {@link Namespace}. + * + * @return the element's namespace + */ + public Namespace getNamespace() { + return namespace; + } + + /** + * Sets the element's {@link Namespace}. If the provided namespace is null, + * the element will have no namespace. + * + * @param namespace the new namespace + * @return the target element + */ + public Element setNamespace(Namespace namespace) { + if (namespace == null) { + namespace = Namespace.NO_NAMESPACE; + } + String reason = Verifier.checkNamespaceCollision(namespace, + getAdditionalNamespaces()); + if (reason != null) { + throw new IllegalAddException(this, namespace, reason); + } + for (Iterator it = getAttributes().iterator(); it.hasNext();) { + Attribute a = (Attribute)it.next(); + reason = Verifier.checkNamespaceCollision(namespace, a); + if (reason != null) { + throw new IllegalAddException(this, namespace, reason); + } + } + + this.namespace = namespace; + return this; + } + + /** + * Returns the namespace prefix of the element or an empty string if none + * exists. + * + * @return the namespace prefix + */ + public String getNamespacePrefix() { + return namespace.getPrefix(); + } + + /** + * Returns the namespace URI mapped to this element's prefix (or the + * in-scope default namespace URI if no prefix). If no mapping is found, an + * empty string is returned. + * + * @return the namespace URI for this element + */ + public String getNamespaceURI() { + return namespace.getURI(); + } + + /** + * Returns the {@link Namespace} corresponding to the given prefix in scope + * for this element. This involves searching up the tree, so the results + * depend on the current location of the element. Returns null if there is + * no namespace in scope with the given prefix at this point in the + * document. + * + * @param prefix namespace prefix to look up + * @return the Namespace for this prefix at this + * location, or null if none + */ + public Namespace getNamespace(final String prefix) { + if (prefix == null) { + return null; + } + + if ("xml".equals(prefix)) { + // Namespace "xml" is always bound. + return Namespace.XML_NAMESPACE; + } + + // Check if the prefix is the prefix for this element + if (prefix.equals(getNamespacePrefix())) { + return getNamespace(); + } + + // Scan the additional namespaces + if (additionalNamespaces != null) { + for (int i = 0; i < additionalNamespaces.size(); i++) { + final Namespace ns = (Namespace) additionalNamespaces.get(i); + if (prefix.equals(ns.getPrefix())) { + return ns; + } + } + } + + if (attributes != null) { + for (Iterator it = attributes.iterator(); it.hasNext();) { + Attribute a = (Attribute)it.next(); + if (prefix.equals(a.getNamespacePrefix())) { + return a.getNamespace(); + } + } + } + + // If we still don't have a match, ask the parent + if (parent instanceof Element) { + return ((Element)parent).getNamespace(prefix); + } + + return null; + } + + /** + * Returns the full name of the element, in the form + * [namespacePrefix]:[localName]. If the element does not have a namespace + * prefix, then the local name is returned. + * + * @return qualified name of the element (including + * namespace prefix) + */ + public String getQualifiedName() { + // Note: Any changes here should be reflected in + // XMLOutputter.printQualifiedName() + if ("".equals(namespace.getPrefix())) { + return getName(); + } + + return new StringBuffer(namespace.getPrefix()) + .append(':') + .append(name) + .toString(); + } + + /** + * Adds a namespace declarations to this element. This should not be + * used to add the declaration for this element itself; that should be + * assigned in the construction of the element. Instead, this is for adding + * namespace declarations on the element not relating directly to itself. + * It's used during output to for stylistic reasons move namespace + * declarations higher in the tree than they would have to be. + * + * @param additionalNamespace namespace to add + * @throws IllegalAddException if the namespace prefix collides with another + * namespace prefix on the element + */ + public void addNamespaceDeclaration(final Namespace additionalNamespace) { + + // Verify the new namespace prefix doesn't collide with another + // declared namespace, an attribute prefix, or this element's prefix + final String reason = Verifier.checkNamespaceCollision(additionalNamespace, this); + if (reason != null) { + throw new IllegalAddException(this, additionalNamespace, reason); + } + + if (additionalNamespaces == null) { + additionalNamespaces = new ArrayList(INITIAL_ARRAY_SIZE); + } + + additionalNamespaces.add(additionalNamespace); + } + + /** + * Removes an additional namespace declarations from this element. This + * should not be used to remove the declaration for this element + * itself; that should be handled in the construction of the element. + * Instead, this is for removing namespace declarations on the element not + * relating directly to itself. If the declaration is not present, this + * method does nothing. + * + * @param additionalNamespace namespace to remove + */ + public void removeNamespaceDeclaration(final Namespace additionalNamespace) { + if (additionalNamespaces == null) { + return; + } + additionalNamespaces.remove(additionalNamespace); + } + + /** + * Returns a list of the additional namespace declarations on this element. + * This includes only additional namespace, not the namespace of the element + * itself, which can be obtained through {@link #getNamespace()}. If there + * are no additional declarations, this returns an empty list. Note, the + * returned list is unmodifiable. + * + * @return a List of the additional namespace + * declarations + */ + public List getAdditionalNamespaces() { + // Not having the returned list be live allows us to avoid creating a + // new list object when XMLOutputter calls this method on an element + // with an empty list. + if (additionalNamespaces == null) { + return Collections.EMPTY_LIST; + } + return Collections.unmodifiableList(additionalNamespaces); + } + + /** + * Returns the XPath 1.0 string value of this element, which is the + * complete, ordered content of all text node descendants of this element + * (i.e. the text that's left after all references are resolved + * and all other markup is stripped out.) + * + * @return a concatentation of all text node descendants + */ + public String getValue() { + final StringBuffer buffer = new StringBuffer(); + + final Iterator iter = getContent().iterator(); + while (iter.hasNext()) { + final Content child = (Content) iter.next(); + if (child instanceof Element || child instanceof Text) { + buffer.append(child.getValue()); + } + } + return buffer.toString(); + } + + /** + * Returns whether this element is a root element. This can be used in + * tandem with {@link #getParent} to determine if an element has any + * "attachments" to a parent element or document. + * + * @return whether this is a root element + */ + public boolean isRootElement() { + return parent instanceof Document; + } + + public int getContentSize() { + return content.size(); + } + + public int indexOf(final Content child) { + return content.indexOf(child); + } + +// 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; +// } + + + /** + * Returns the textual content directly held under this element as a string. + * This includes all text within this single element, including whitespace + * and CDATA sections if they exist. It's essentially the concatenation of + * all {@link Text} and {@link CDATA} nodes returned by {@link #getContent}. + * The call does not recurse into child elements. If no textual value exists + * for the element, an empty string is returned. + * + * @return text content for this element, or empty + * string if none + */ + public String getText() { + if (content.size() == 0) { + return ""; + } + + // If we hold only a Text or CDATA, return it directly + if (content.size() == 1) { + final Object obj = content.get(0); + if (obj instanceof Text) { + return ((Text) obj).getText(); + } + else { + return ""; + } + } + + // Else build String up + final StringBuffer textContent = new StringBuffer(); + boolean hasText = false; + + for (int i = 0; i < content.size(); i++) { + final Object obj = content.get(i); + if (obj instanceof Text) { + textContent.append(((Text) obj).getText()); + hasText = true; + } + } + + if (!hasText) { + return ""; + } + else { + return textContent.toString(); + } + } + + /** + * Returns the textual content of this element with all surrounding + * whitespace removed. If no textual value exists for the element, or if + * only whitespace exists, the empty string is returned. + * + * @return trimmed text content for this element, or + * empty string if none + */ + public String getTextTrim() { + return getText().trim(); + } + + /** + * Returns the textual content of this element with all surrounding + * whitespace removed and internal whitespace normalized to a single space. + * If no textual value exists for the element, or if only whitespace exists, + * the empty string is returned. + * + * @return normalized text content for this element, or + * empty string if none + */ + public String getTextNormalize() { + return Text.normalizeString(getText()); + } + + /** + * Returns the textual content of the named child element, or null if + * there's no such child. This method is a convenience because calling + * getChild().getText() can throw a NullPointerException. + * + * @param name the name of the child + * @return text content for the named child, or null if + * no such child + */ + public String getChildText(final String name) { + final Element child = getChild(name); + if (child == null) { + return null; + } + return child.getText(); + } + + /** + * Returns the trimmed textual content of the named child element, or null + * if there's no such child. See {@link #getTextTrim()} for + * details of text trimming. + * + * @param name the name of the child + * @return trimmed text content for the named child, or + * null if no such child + */ + public String getChildTextTrim(final String name) { + final Element child = getChild(name); + if (child == null) { + return null; + } + return child.getTextTrim(); + } + + /** + * Returns the normalized textual content of the named child element, or + * null if there's no such child. See {@link + * #getTextNormalize()} for details of text normalizing. + * + * @param name the name of the child + * @return normalized text content for the named child, + * or null if no such child + */ + public String getChildTextNormalize(final String name) { + final Element child = getChild(name); + if (child == null) { + return null; + } + return child.getTextNormalize(); + } + + /** + * Returns the textual content of the named child element, or null if + * there's no such child. + * + * @param name the name of the child + * @param ns the namespace of the child + * @return text content for the named child, or null if + * no such child + */ + public String getChildText(final String name, final Namespace ns) { + final Element child = getChild(name, ns); + if (child == null) { + return null; + } + return child.getText(); + } + + /** + * Returns the trimmed textual content of the named child element, or null + * if there's no such child. + * + * @param name the name of the child + * @param ns the namespace of the child + * @return trimmed text content for the named child, or + * null if no such child + */ + public String getChildTextTrim(final String name, final Namespace ns) { + final Element child = getChild(name, ns); + if (child == null) { + return null; + } + return child.getTextTrim(); + } + + /** + * Returns the normalized textual content of the named child element, or + * null if there's no such child. + * + * @param name the name of the child + * @param ns the namespace of the child + * @return normalized text content for the named child, + * or null if no such child + */ + public String getChildTextNormalize(final String name, final Namespace ns) { + final Element child = getChild(name, ns); + if (child == null) { + return null; + } + return child.getTextNormalize(); + } + + /** + * Sets the content of the element to be the text given. All existing text + * content and non-text context is removed. If this element should have both + * textual content and nested elements, use {@link #setContent} + * instead. Setting a null text value is equivalent to setting an empty + * string value. + * + * @param text new text content for the element + * @return the target element + * @throws IllegalDataException if the assigned text contains an illegal + * character such as a vertical tab (as + * determined by {@link + * org.jdom.Verifier#checkCharacterData}) + */ + public Element setText(final String text) { + content.clear(); + + if (text != null) { + addContent(new Text(text)); + } + + return this; + } + + /** + * This returns the full content of the element as a List which + * may contain objects of type Text, Element, + * Comment, ProcessingInstruction, + * CDATA, and EntityRef. + * The List returned is "live" in document order and modifications + * to it affect the element's actual contents. Whitespace content is + * returned in its entirety. + * + *

+ * Sequential traversal through the List is best done with an Iterator + * since the underlying implement of List.size() may require walking the + * entire list. + *

+ * + * @return a List containing the mixed content of the + * element: may contain Text, + * {@link Element}, {@link Comment}, + * {@link ProcessingInstruction}, + * {@link CDATA}, and + * {@link EntityRef} objects. + */ + public List getContent() { + return content; + } + + /** + * Return a filter view of this Element's content. + * + *

+ * Sequential traversal through the List is best done with a Iterator + * since the underlying implement of List.size() may require walking the + * entire list. + *

+ * + * @param filter Filter to apply + * @return List - filtered Element content + */ + public List getContent(final Filter filter) { + return content.getView(filter); + } + + /** + * Removes all child content from this parent. + * + * @return list of the old children detached from this parent + */ + public List removeContent() { + final 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(final Filter filter) { + final List old = new ArrayList(); + final Iterator iter = content.getView(filter).iterator(); + while (iter.hasNext()) { + final Content child = (Content) iter.next(); + old.add(child); + iter.remove(); + } + return old; + } + + /** + * This sets the content of the element. The supplied List should + * contain only objects of type Element, Text, + * CDATA, Comment, + * ProcessingInstruction, and EntityRef. + * + *

+ * 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} or {@link #getChildren}) will also + * change to reflect the new content. In addition, all objects in the + * supplied List will have their parentage set to this element, but the + * List itself will not be "live" and further removals and additions will + * have no effect on this elements 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} or {@link #getChildren} to + * obtain a "live" version of the content. + *

+ * + *

+ * Passing a null or empty List clears the existing content. + *

+ * + *

+ * In event of an exception the original content will be unchanged and + * the objects in the supplied content will be unaltered. + *

+ * + * @param newContent Collection of content to set + * @return this element modified + * @throws IllegalAddException if the List contains objects of + * illegal types or with existing parentage. + */ + public Element setContent(final Collection newContent) { + content.clearAndSet(newContent); + return this; + } + + /** + * Replace the current child the given index with the supplied child. + *

+ * In event of an exception the original content will be unchanged and + * the supplied child will be unaltered. + *

+ * + * @param index - index of child to replace. + * @param child - child to add. + * @return element on which this method was invoked + * @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 Element setContent(final int index, final Content child) { + content.set(index, child); + return this; + } + + /** + * Replace the child at the given index whith the supplied + * collection. + *

+ * In event of an exception the original content will be unchanged and + * the content in the supplied collection will be unaltered. + *

+ * + * @param index - index of child to replace. + * @param newContent - Collection of content to replace child. + * @return object on which this 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 Parent setContent(final int index, final Collection newContent) { + content.remove(index); + content.addAll(index, newContent); + return this; + } + + /** + * This adds text content to this element. It does not replace the + * existing content as does setText(). + * + * @param str String to add + * @return this element modified + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + */ + public Element addContent(final String str) { + return addContent(new Text(str)); + } + + /** + * Appends the child to the end of the element's content list. + * + * @param child child to append to end of content list + * @return the element on which the method was called + * @throws IllegalAddException if the given child already has a parent. */ + public Element addContent(final 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 newContent Collection of content to append + * @return the element on which the method was called + * @throws IllegalAddException if any item in the collection + * already has a parent or is of an inappropriate type. + */ + public Element addContent(final Collection newContent) { + content.addAll(newContent); + 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 Element addContent(final int index, final 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 newContent Collection of content 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 inappropriate type. + */ + public Element addContent(final int index, final Collection newContent) { + content.addAll(index, newContent); + return this; + } + + public List cloneContent() { + final int size = getContentSize(); + final List list = new ArrayList(size); + for (int i = 0; i < size; i++) { + final Content child = getContent(i); + list.add(child.clone()); + } + return list; + } + + public Content getContent(final int index) { + return (Content) content.get(index); + } + +// public Content getChild(Filter filter) { +// int i = indexOf(0, filter); +// return (i < 0) ? null : getContent(i); +// } + + public boolean removeContent(final Content child) { + return content.remove(child); + } + + public Content removeContent(final int index) { + return (Content) content.remove(index); + } + + /** + * Set this element's content to be the supplied child. + *

+ * If the supplied child is legal content for this parent 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. + *

+ * 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 parent. If the user + * wants to continue working with a "live" list of this parent's + * child, then a call to setContent should be followed by a call to one + * of the {@link #getContent} methods to obtain a "live" + * version of the children. + *

+ * Passing a null child clears the existing content. + *

+ * 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 an Element + */ + public Element setContent(final Content child) { + content.clear(); + content.add(child); + return this; + } + + + /** + * Determines if this element is the ancestor of another element. + * + * @param element Element to check against + * @return true if this element is the ancestor of the + * supplied element + */ + public boolean isAncestor(final Element element) { + Parent p = element.getParent(); + while (p instanceof Element) { + if (p == this) { + return true; + } + p = p.getParent(); + } + return false; + } + + /** + *

+ * This returns the complete set of attributes for this element, as a + * List of Attribute objects in no particular + * order, or an empty list if there are none. + * The returned list is "live" and changes to it affect the + * element's actual attributes. + *

+ * + * @return attributes for the element + */ + public List getAttributes() { + return attributes; + } + + /** + *

+ * This returns the attribute for this element with the given name + * and within no namespace, or null if no such attribute exists. + *

+ * + * @param name name of the attribute to return + * @return attribute for the element + */ + public Attribute getAttribute(final String name) { + return getAttribute(name, Namespace.NO_NAMESPACE); + } + + /** + *

+ * This returns the attribute for this element with the given name + * and within the given Namespace, or null if no such attribute exists. + *

+ * + * @param name name of the attribute to return + * @param ns Namespace to search within + * @return attribute for the element + */ + public Attribute getAttribute(final String name, final Namespace ns) { + return (Attribute) attributes.get(name, ns); + } + + /** + *

+ * This returns the attribute value for the attribute with the given name + * and within no namespace, null if there is no such attribute, and the + * empty string if the attribute value is empty. + *

+ * + * @param name name of the attribute whose value to be returned + * @return the named attribute's value, or null if no such attribute + */ + public String getAttributeValue(final String name) { + return getAttributeValue(name, Namespace.NO_NAMESPACE); + } + + /** + *

+ * This returns the attribute value for the attribute with the given name + * and within no namespace, or the passed-in default if there is no + * such attribute. + *

+ * + * @param name name of the attribute whose value to be returned + * @param def a default value to return if the attribute does not exist + * @return the named attribute's value, or the default if no such attribute + */ + public String getAttributeValue(final String name, final String def) { + return getAttributeValue(name, Namespace.NO_NAMESPACE, def); + } + + /** + *

+ * This returns the attribute value for the attribute with the given name + * and within the given Namespace, null if there is no such attribute, and + * the empty string if the attribute value is empty. + *

+ * + * @param name name of the attribute whose valud is to be returned + * @param ns Namespace to search within + * @return the named attribute's value, or null if no such attribute + */ + public String getAttributeValue(final String name, final Namespace ns) { + return getAttributeValue(name, ns, null); + } + + /** + *

+ * This returns the attribute value for the attribute with the given name + * and within the given Namespace, or the passed-in default if there is no + * such attribute. + *

+ * + * @param name name of the attribute whose valud is to be returned + * @param ns Namespace to search within + * @param def a default value to return if the attribute does not exist + * @return the named attribute's value, or the default if no such attribute + */ + public String getAttributeValue(final String name, final Namespace ns, final String def) { + final Attribute attribute = (Attribute) attributes.get(name, ns); + if (attribute == null) { + return def; + } + + return attribute.getValue(); + } + + /** + *

+ * This sets the attributes of the element. The supplied Collection should + * contain only objects of type Attribute. + *

+ * + *

+ * When all objects in the supplied List are legal and before the new + * attributes are added, all old attributes will have their + * parentage set to null (no parent) and the old attribute list will be + * cleared. This has the effect that any active attribute list (previously + * obtained with a call to {@link #getAttributes}) will also change to + * reflect the new attributes. In addition, all attributes in the supplied + * List will have their parentage set to this element, but the List itself + * will not be "live" and further removals and additions will have no + * effect on this elements attributes. If the user wants to continue + * working with a "live" attribute list, then a call to setAttributes + * should be followed by a call to {@link #getAttributes} to obtain a + * "live" version of the attributes. + *

+ * + *

+ * Passing a null or empty List clears the existing attributes. + *

+ * + *

+ * In cases where the List contains duplicate attributes, only the last + * one will be retained. This has the same effect as calling + * {@link #setAttribute(Attribute)} sequentially. + *

+ * + *

+ * In event of an exception the original attributes will be unchanged and + * the attributes in the supplied attributes will be unaltered. + *

+ * + * @param newAttributes Collection of attributes to set + * @return this element modified + * @throws IllegalAddException if the List contains objects + * that are not instances of Attribute, + * or if any of the Attribute objects have + * conflicting namespace prefixes. + */ + public Element setAttributes(final Collection newAttributes) { + attributes.clearAndSet(newAttributes); + return this; + } + + /** + *

+ * This sets the attributes of the element. It's an alternate form of + * the method, accepting a List instead of a + * Collection, for backward compatibility. + *

+ */ + public Element setAttributes(final List newAttributes) { + return setAttributes((Collection)newAttributes); + } + + /** + *

+ * This sets an attribute value for this element. Any existing attribute + * with the same name and namespace URI is removed. + *

+ * + * @param name name of the attribute to set + * @param value value of the attribute to set + * @return this element modified + * @throws IllegalNameException if the given name is illegal as an + * attribute name. + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}). + */ + public Element setAttribute(final String name, final String value) { + final Attribute attribute = getAttribute(name); + if (attribute == null) { + final Attribute newAttribute = new Attribute(name, value); + setAttribute(newAttribute); + } else { + attribute.setValue(value); + } + + return this; + } + + /** + *

+ * This sets an attribute value for this element. Any existing attribute + * with the same name and namespace URI is removed. + *

+ * + * @param name name of the attribute to set + * @param value value of the attribute to set + * @param ns namespace of the attribute to set + * @return this element modified + * @throws IllegalNameException if the given name is illegal as an + * attribute name, or if the namespace is an unprefixed default + * namespace + * @throws IllegalDataException if the given attribute value is + * illegal character data (as determined by + * {@link org.jdom.Verifier#checkCharacterData}). + * @throws IllegalAddException if the attribute namespace prefix + * collides with another namespace prefix on the element. + */ + public Element setAttribute(final String name, final String value, final Namespace ns) { + final Attribute attribute = getAttribute(name, ns); + if (attribute == null) { + final Attribute newAttribute = new Attribute(name, value, ns); + setAttribute(newAttribute); + } else { + attribute.setValue(value); + } + + return this; + } + + /** + *

+ * This sets an attribute value for this element. Any existing attribute + * with the same name and namespace URI is removed. + *

+ * + * @param attribute Attribute to set + * @return this element modified + * @throws IllegalAddException if the attribute being added already has a + * parent or if the attribute namespace prefix collides with another + * namespace prefix on the element. + */ + public Element setAttribute(final Attribute attribute) { + attributes.add(attribute); + return this; + } + + /** + *

+ * This removes the attribute with the given name and within no + * namespace. If no such attribute exists, this method does nothing. + *

+ * + * @param name name of attribute to remove + * @return whether the attribute was removed + */ + public boolean removeAttribute(final String name) { + return removeAttribute(name, Namespace.NO_NAMESPACE); + } + + /** + *

+ * This removes the attribute with the given name and within the + * given Namespace. If no such attribute exists, this method does + * nothing. + *

+ * + * @param name name of attribute to remove + * @param ns namespace URI of attribute to remove + * @return whether the attribute was removed + */ + public boolean removeAttribute(final String name, final Namespace ns) { + return attributes.remove(name, ns); + } + + /** + *

+ * This removes the supplied Attribute should it exist. + *

+ * + * @param attribute Reference to the attribute to be removed. + * @return whether the attribute was removed + */ + public boolean removeAttribute(final Attribute attribute) { + return attributes.remove(attribute); + } + + /** + *

+ * This returns a String representation of the + * Element, suitable for debugging. If the XML + * representation of the Element is desired, + * {@link org.jdom.output.XMLOutputter#outputString(Element)} + * should be used. + *

+ * + * @return String - information about the + * Element + */ + public String toString() { + final StringBuffer stringForm = new StringBuffer(64) + .append("[Element: <") + .append(getQualifiedName()); + + final String nsuri = getNamespaceURI(); + if (!"".equals(nsuri)) { + stringForm + .append(" [Namespace: ") + .append(nsuri) + .append("]"); + } + stringForm.append("/>]"); + + return stringForm.toString(); + } + + /** + *

+ * This returns a deep clone of this element. + * The new element is detached from its parent, and getParent() + * on the clone will return null. + *

+ * + * @return the clone of this element + */ + public Object clone() { + + // Ken Rune Helland is our local clone() guru + + final Element element = (Element) super.clone(); + + // name and namespace are references to immutable objects + // so super.clone() handles them ok + + // Reference to parent is copied by super.clone() + // (Object.clone()) so we have to remove it + // Actually, super is a Content, which has already detached in the + // clone(). + // element.parent = null; + + // Reference to content list and attribute lists are copyed by + // super.clone() so we set it new lists if the original had lists + element.content = new ContentList(element); + element.attributes = new AttributeList(element); + + // Cloning attributes + if (attributes != null) { + for(int i = 0; i < attributes.size(); i++) { + final Attribute attribute = (Attribute) attributes.get(i); + element.attributes.add(attribute.clone()); + } + } + + // Cloning additional namespaces + if (additionalNamespaces != null) { + element.additionalNamespaces = new ArrayList(additionalNamespaces); + } + + // Cloning content + if (content != null) { + for(int i = 0; i < content.size(); i++) { + final Content c = (Content) content.get(i); + element.content.add(c.clone()); + } + } + + return element; + } + + + // Support a custom Namespace serialization so no two namespace + // object instances may exist for the same prefix/uri pair + private void writeObject(final ObjectOutputStream out) throws IOException { + + out.defaultWriteObject(); + + // We use writeObject() and not writeUTF() to minimize space + // This allows for writing pointers to already written strings + out.writeObject(namespace.getPrefix()); + out.writeObject(namespace.getURI()); + + if (additionalNamespaces == null) { + out.write(0); + } + else { + final int size = additionalNamespaces.size(); + out.write(size); + for (int i = 0; i < size; i++) { + final Namespace additional = (Namespace) additionalNamespaces.get(i); + out.writeObject(additional.getPrefix()); + out.writeObject(additional.getURI()); + } + } + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + + in.defaultReadObject(); + + namespace = Namespace.getNamespace( + (String)in.readObject(), (String)in.readObject()); + + final int size = in.read(); + + if (size != 0) { + additionalNamespaces = new ArrayList(size); + for (int i = 0; i < size; i++) { + final Namespace additional = Namespace.getNamespace( + (String)in.readObject(), (String)in.readObject()); + additionalNamespaces.add(additional); + } + } + } + + /** + * 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(final Filter filter) { + final Iterator iterator = new DescendantIterator(this); + return new FilterIterator(iterator, filter); + } + + + + /** + * This returns a List of all the child elements + * nested directly (one level deep) within this element, as + * Element objects. If this target element has no nested + * elements, an empty List is returned. The returned list is "live" + * in document order and changes to it affect the element's actual + * contents. + * + *

+ * Sequential traversal through the List is best done with a Iterator + * since the underlying implement of List.size() may not be the most + * efficient. + *

+ * + *

+ * No recursion is performed, so elements nested two levels deep + * would have to be obtained with: + *

+     * 
+     *   Iterator itr = (currentElement.getChildren()).iterator();
+     *   while(itr.hasNext()) {
+     *     Element oneLevelDeep = (Element)itr.next();
+     *     List twoLevelsDeep = oneLevelDeep.getChildren();
+     *     // Do something with these children
+     *   }
+     * 
+     * 
+ *

+ * + * @return list of child Element objects for this element + */ + public List getChildren() { + return content.getView(new ElementFilter()); + } + + /** + * This returns a List of all the child elements + * nested directly (one level deep) within this element with the given + * local name and belonging to no namespace, returned as + * Element objects. If this target element has no nested + * elements with the given name outside a namespace, an empty List + * is returned. The returned list is "live" in document order + * and changes to it affect the element's actual contents. + *

+ * Please see the notes for {@link #getChildren} + * for a code example. + *

+ * + * @param name local name for the children to match + * @return all matching child elements + */ + public List getChildren(final String name) { + return getChildren(name, Namespace.NO_NAMESPACE); + } + + /** + * This returns a List of all the child elements + * nested directly (one level deep) within this element with the given + * local name and belonging to the given Namespace, returned as + * Element objects. If this target element has no nested + * elements with the given name in the given Namespace, an empty List + * is returned. The returned list is "live" in document order + * and changes to it affect the element's actual contents. + *

+ * Please see the notes for {@link #getChildren} + * for a code example. + *

+ * + * @param name local name for the children to match + * @param ns Namespace to search within + * @return all matching child elements + */ + public List getChildren(final String name, final Namespace ns) { + return content.getView(new ElementFilter(name, ns)); + } + + /** + * This returns the first child element within this element with the + * given local name and belonging to the given namespace. + * If no elements exist for the specified name and namespace, null is + * returned. + * + * @param name local name of child element to match + * @param ns Namespace to search within + * @return the first matching child element, or null if not found + */ + public Element getChild(final String name, final Namespace ns) { + final List elements = content.getView(new ElementFilter(name, ns)); + final Iterator iter = elements.iterator(); + if (iter.hasNext()) { + return (Element) iter.next(); + } + return null; + } + + /** + * This returns the first child element within this element with the + * given local name and belonging to no namespace. + * If no elements exist for the specified name and namespace, null is + * returned. + * + * @param name local name of child element to match + * @return the first matching child element, or null if not found + */ + public Element getChild(final String name) { + return getChild(name, Namespace.NO_NAMESPACE); + } + + /** + *

+ * This removes the first child element (one level deep) with the + * given local name and belonging to no namespace. + * Returns true if a child was removed. + *

+ * + * @param name the name of child elements to remove + * @return whether deletion occurred + */ + public boolean removeChild(final String name) { + return removeChild(name, Namespace.NO_NAMESPACE); + } + + /** + *

+ * This removes the first child element (one level deep) with the + * given local name and belonging to the given namespace. + * Returns true if a child was removed. + *

+ * + * @param name the name of child element to remove + * @param ns Namespace to search within + * @return whether deletion occurred + */ + public boolean removeChild(final String name, final Namespace ns) { + final Filter filter = new ElementFilter(name, ns); + final List old = content.getView(filter); + final Iterator iter = old.iterator(); + if (iter.hasNext()) { + iter.next(); + iter.remove(); + return true; + } + + return false; + } + + /** + *

+ * This removes all child elements (one level deep) with the + * given local name and belonging to no namespace. + * Returns true if any were removed. + *

+ * + * @param name the name of child elements to remove + * @return whether deletion occurred + */ + public boolean removeChildren(final String name) { + return removeChildren(name, Namespace.NO_NAMESPACE); + } + + /** + *

+ * This removes all child elements (one level deep) with the + * given local name and belonging to the given namespace. + * Returns true if any were removed. + *

+ * + * @param name the name of child elements to remove + * @param ns Namespace to search within + * @return whether deletion occurred + */ + public boolean removeChildren(final String name, final Namespace ns) { + boolean deletedSome = false; + + final Filter filter = new ElementFilter(name, ns); + final List old = content.getView(filter); + final Iterator iter = old.iterator(); + while (iter.hasNext()) { + iter.next(); + iter.remove(); + deletedSome = true; + } + + return deletedSome; + } + +} Index: 3rdParty_sources/jdom/org/jdom/EntityRef.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/EntityRef.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/EntityRef.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,239 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * An XML entity reference. Methods allow the user to manage its name, public + * id, and system id. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Philip Nelson + */ +public class EntityRef extends Content { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The name of the EntityRef */ + protected String name; + + /** The PublicID of the EntityRef */ + protected String publicID; + + /** The SystemID of the EntityRef */ + protected String systemID; + + /** + * Default, no-args constructor for implementations to use if needed. + */ + protected EntityRef() {} + + /** + * This will create a new EntityRef with the supplied name. + * + * @param name String name of element. + * @throws IllegalNameException if the given name is not a legal + * XML name. + */ + public EntityRef(String name) { + this(name, null, null); + } + + /** + * This will create a new EntityRef + * with the supplied name and system id. + * + * @param name String name of element. + * @param systemID system id of the entity reference being constructed + * @throws IllegalNameException if the given name is not a legal + * XML name. + * @throws IllegalDataException if the given system ID is not a legal + * system literal. + */ + public EntityRef(String name, String systemID) { + this(name, null, systemID); + } + + /** + * This will create a new EntityRef + * with the supplied name, public id, and system id. + * + * @param name String name of element. + * @param publicID public id of the entity reference being constructed + * @param systemID system id of the entity reference being constructed + * @throws IllegalDataException if the given system ID is not a legal + * system literal or the the given public ID is not a + * legal public ID + * @throws IllegalNameException if the given name is not a legal + * XML name. + */ + public EntityRef(String name, String publicID, String systemID) { + setName(name); + setPublicID(publicID); + setSystemID(systemID); + } + + /** + * This returns the name of the EntityRef. + * + * @return String - entity name. + */ + public String getName() { + return name; + } + + /** + * Returns the empty string since entity references don't have an XPath + * 1.0 string value. + * @return the empty string + */ + public String getValue() { + return ""; // entity references don't have XPath string values + } + + /** + * This will return the publid ID of this EntityRef. + * If there is no public ID, then this returns null. + * + * @return public ID of this EntityRef + */ + public String getPublicID() { + return publicID; + } + + /** + * This will return the system ID of this EntityRef. + * If there is no system ID, then this returns null. + * + * @return system ID of this EntityRef + */ + public String getSystemID() { + return systemID; + } + + /** + * This will set the name of this EntityRef. + * + * @param name new name of the entity + * @return this EntityRef modified. + * @throws IllegalNameException if the given name is not a legal + * XML name. + */ + public EntityRef setName(String name) { + // This can contain a colon so we use checkXMLName() + // instead of checkElementName() + String reason = Verifier.checkXMLName(name); + if (reason != null) { + throw new IllegalNameException(name, "EntityRef", reason); + } + this.name = name; + return this; + } + + /** + * This will set the public ID of this EntityRef. + * + * @param publicID new public id + * @return this EntityRef modified. + * @throws IllegalDataException if the given public ID is not a legal + * public ID. + */ + public EntityRef setPublicID(String publicID) { + String reason = Verifier.checkPublicID(publicID); + if (reason != null) { + throw new IllegalDataException(publicID, "EntityRef", reason); + } + this.publicID = publicID; + return this; + } + + /** + * This will set the system ID of this EntityRef. + * + * @param systemID new system id + * @throws IllegalDataException if the given system ID is not a legal + * system literal. + * @return this EntityRef modified. + */ + public EntityRef setSystemID(String systemID) { + String reason = Verifier.checkSystemLiteral(systemID); + if (reason != null) { + throw new IllegalDataException(systemID, "EntityRef", reason); + } + this.systemID = systemID; + return this; + } + + /** + * This returns a String representation of the + * EntityRef, suitable for debugging. + * + * @return String - information about the + * EntityRef + */ + public String toString() { + return new StringBuffer() + .append("[EntityRef: ") + .append("&") + .append(name) + .append(";") + .append("]") + .toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/FilterIterator.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/FilterIterator.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/FilterIterator.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,115 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; +import org.jdom.filter.*; + +/** + * Traverse a parent's children that match the supplied filter. + * + * @author Bradley S. Huffman + * @version $Revision$, $Date$ + */ +class FilterIterator implements Iterator { + + private Iterator iterator; + private Filter filter; + private Object nextObject; + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + public FilterIterator(Iterator iterator, Filter filter) { + if ((iterator == null) || (filter == null)) { + throw new IllegalArgumentException("null parameter"); + } + this.iterator = iterator; + this.filter = filter; + } + + public boolean hasNext() { + if (nextObject != null) { + return true; + } + + while (iterator.hasNext()) { + Object obj = iterator.next(); + if (filter.matches(obj)) { + nextObject = obj; + return true; + } + } + return false; + } + + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + Object obj = nextObject; + nextObject = null; + return obj; + } + + public void remove() { + // XXX Could cause probs for sure if hasNext() is + // called before the remove(), although that's unlikely. + iterator.remove(); + } +} Index: 3rdParty_sources/jdom/org/jdom/IllegalAddException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/IllegalAddException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/IllegalAddException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,323 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * Thrown when trying to add a illegal object to a JDOM construct. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class IllegalAddException extends IllegalArgumentException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This will create an Exception indicating + * that the addition of the {@link Attribute} + * to the {@link Element} is illegal. + * + * @param base Element that Attribute + * couldn't be added to + * @param added Attribute that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, Attribute added, String reason) { + super(new StringBuffer() + .append("The attribute \"") + .append(added.getQualifiedName()) + .append("\" could not be added to the element \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link Element} + * to parent is illegal. + * + * @param base Element that the child + * couldn't be added to + * @param added Element that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, Element added, String reason) { + super(new StringBuffer() + .append("The element \"") + .append(added.getQualifiedName()) + .append("\" could not be added as a child of \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link Element} + * to the {@link Document} is illegal. + * + * @param added Element that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element added, String reason) { + super(new StringBuffer() + .append("The element \"") + .append(added.getQualifiedName()) + .append("\" could not be added as the root of the document: ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link ProcessingInstruction} + * to the {@link Element} is illegal. + * + * @param base Element that the + * ProcessingInstruction couldn't be added to + * @param added ProcessingInstruction that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, ProcessingInstruction added, + String reason) { + super(new StringBuffer() + .append("The PI \"") + .append(added.getTarget()) + .append("\" could not be added as content to \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link ProcessingInstruction} + * to the {@link Document} is illegal. + * + * @param added ProcessingInstruction that could not be added + * @param reason cause of the problem + */ + IllegalAddException(ProcessingInstruction added, + String reason) { + super(new StringBuffer() + .append("The PI \"") + .append(added.getTarget()) + .append("\" could not be added to the top level of the document: ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link Comment} + * to the {@link Element} is illegal. + * + * @param base Element that the Comment + * couldn't be added to + * @param added Comment that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, Comment added, String reason) { + super(new StringBuffer() + .append("The comment \"") + .append(added.getText()) + .append("\" could not be added as content to \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + + /** + * This will create an Exception indicating + * that the addition of the {@link CDATA} + * + * @param base Element that the CDATA + * couldn't be added to + * @param added CDATA that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, CDATA added, String reason) { + super(new StringBuffer() + .append("The CDATA \"") + .append(added.getText()) + .append("\" could not be added as content to \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + + /** + * This will create an Exception indicating + * that the addition of the {@link Text} + * to the {@link Element} is illegal. + * + * @param base Element that the Comment + * couldn't be added to + * @param added Text that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, Text added, String reason) { + super(new StringBuffer() + .append("The Text \"") + .append(added.getText()) + .append("\" could not be added as content to \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link Comment} + * to the {@link Document} is illegal. + * + * @param added Comment that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Comment added, String reason) { + super(new StringBuffer() + .append("The comment \"") + .append(added.getText()) + .append("\" could not be added to the top level of the document: ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link EntityRef} + * to the {@link Element} is illegal. + * + * @param base Element that the EntityRef + * couldn't be added to + * @param added EntityRef reference that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, EntityRef added, String reason) { + super(new StringBuffer() + .append("The entity reference\"") + .append(added.getName()) + .append("\" could not be added as content to \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link Namespace} + * to the {@link Element} is illegal. + * + * @param base Element that the Namespace + * couldn't be added to + * @param added Namespace that could not be added + * @param reason cause of the problem + */ + IllegalAddException(Element base, Namespace added, String reason) { + super(new StringBuffer() + .append("The namespace xmlns") + .append((added.getPrefix() == null || + added.getPrefix().equals("")) ? "=" + : ":" + added.getPrefix() + "=") + .append("\"") + .append(added.getURI()) + .append("\" could not be added as a namespace to \"") + .append(base.getQualifiedName()) + .append("\": ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception indicating + * that the addition of the {@link DocType} + * to the {@link Document} is illegal. + * + * @param added DocType that could not be added + * @param reason cause of the problem + */ + IllegalAddException(DocType added, String reason) { + super(new StringBuffer() + .append("The DOCTYPE ") + .append(added.toString()) + .append(" could not be added to the document: ") + .append(reason) + .toString()); + } + + /** + * This will create an Exception with the specified + * error message. + * + * @param reason cause of the problem + */ + public IllegalAddException(String reason) { + super(reason); + } +} Index: 3rdParty_sources/jdom/org/jdom/IllegalDataException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/IllegalDataException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/IllegalDataException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,118 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * Thrown when illegal text is supplied to a JDOM construct. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Elliotte Rusty Harold + */ +public class IllegalDataException extends IllegalArgumentException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This will create an Exception indicating + * that the specified data is illegal for the construct + * it was supplied to. + * + * @param data String data that breaks rules. + * @param construct String construct that data is illegal for. + * @param reason String message or reason data is illegal. + */ + IllegalDataException(String data, String construct, String reason) { + super(new StringBuffer() + .append("The data \"") + .append(data) + .append("\" is not legal for a JDOM ") + .append(construct) + .append(": ") + .append(reason) + .append(".") + .toString()); + } + + /** + * This will create an Exception indicating + * that the specified data is illegal for the construct + * it was supplied to. + * + * @param data String data that breaks rules. + * @param construct String construct that data is illegal for. + */ + IllegalDataException(String data, String construct) { + super(new StringBuffer() + .append("The data \"") + .append(data) + .append("\" is not legal for a JDOM ") + .append(construct) + .append(".") + .toString()); + } + + /** + * This will create an exceptoin with the specified error message. + * + * @param reason cause of the problem + */ + public IllegalDataException(String reason) { + super(reason); + } +} Index: 3rdParty_sources/jdom/org/jdom/IllegalNameException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/IllegalNameException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/IllegalNameException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,121 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * Thrown when a name is supplied in construction of a JDOM construct whose + * where the name breaks XML naming conventions. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Elliotte Rusty Harold + */ +public class IllegalNameException extends IllegalArgumentException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This will create an Exception indicating + * that the specified name is illegal for the construct + * it was supplied to. + * + * @param name String name that breaks rules. + * @param construct String name of JDOM construct + * that name was supplied to. + * @param reason String message or reason name is illegal. + */ + IllegalNameException(String name, String construct, String reason) { + super(new StringBuffer() + .append("The name \"") + .append(name) + .append("\" is not legal for JDOM/XML ") + .append(construct) + .append("s: ") + .append(reason) + .append(".") + .toString()); + } + + /** + * This will create an Exception indicating + * that the specified name is illegal for the construct + * it was supplied to. + * + * @param name String name that breaks rules. + * @param construct String name of JDOM construct + * that name was supplied to. + */ + IllegalNameException(String name, String construct) { + super(new StringBuffer() + .append("The name \"") + .append(name) + .append("\" is not legal for JDOM/XML ") + .append(construct) + .append("s.") + .toString()); + } + + /** + * Creates an exception with the specified error message. + * + * @param reason cause of the problem + */ + public IllegalNameException(String reason) { + super(reason); + } +} Index: 3rdParty_sources/jdom/org/jdom/IllegalTargetException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/IllegalTargetException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/IllegalTargetException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,97 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * Thrown when a target is supplied in construction of a JDOM {@link + * ProcessingInstruction}, and that name breaks XML naming conventions. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + */ +public class IllegalTargetException extends IllegalArgumentException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This will create an Exception indicating + * that the specified target is illegal for the + * {@link ProcessingInstruction} it was supplied to. + * + * @param target String target that breaks rules. + * @param reason String message or reason target is illegal. + */ + IllegalTargetException(String target, String reason) { + super(new StringBuffer() + .append("The target \"") + .append(target) + .append("\" is not legal for JDOM/XML Processing Instructions: ") + .append(reason) + .append(".") + .toString()); + } + + /** + * Creates an exception with the specified error message. + * + * @param reason cause of the problem + */ + public IllegalTargetException(String reason) { + super(reason); + } +} Index: 3rdParty_sources/jdom/org/jdom/JDOMException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/JDOMException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/JDOMException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,367 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.io.*; +import java.lang.reflect.*; +import java.sql.*; + +import org.xml.sax.*; + +/** + * The top level exception that JDOM classes can throw. Its subclasses add + * specificity to the problems that can occur using JDOM. This single exception + * can be caught to handle all JDOM specific problems (some methods may throw + * {@link java.io.IOException} and such). + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class JDOMException extends Exception { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** A wrapped Throwable */ + private Throwable cause; + + /** + * This will create an Exception. + */ + public JDOMException() { + super("Error occurred in JDOM application."); + } + + /** + * This will create an Exception with the given message. + * + * @param message String message indicating + * the problem that occurred. + */ + public JDOMException(String message) { + super(message); + } + + /** + * This will create an Exception with the given message + * and wrap another Exception. This is useful when + * the originating Exception should be held on to. + * + * @param message String message indicating + * the problem that occurred. + * @param cause Throwable that caused this + * to be thrown. + */ + public JDOMException(String message, Throwable cause) { + super(message); + this.cause = cause; + } + + /** + * Intializes the cause of this exception to be the specified value. + * + * @param cause Throwable that caused this + * to be thrown. + * @return a pointer to this throwable + */ + // Created to match the JDK 1.4 Throwable method. + public Throwable initCause(Throwable cause) { + this.cause = cause; + return this; + } + + /** + * This returns the message for the Exception. If + * there are one or more nested exceptions, their messages + * are appended. + * + * @return String - message for Exception. + */ + public String getMessage() { + // Get this exception's message. + String msg = super.getMessage(); + + Throwable parent = this; + Throwable child; + + // Look for nested exceptions. + while((child = getNestedException(parent)) != null) { + // Get the child's message. + String msg2 = child.getMessage(); + + // Special case: If a SAXException has no message of its own, but has a + // nested exception, then it returns the nested exception's message as its + // message. We don't want to add that message twice. + if (child instanceof SAXException) { + Throwable grandchild = ((SAXException)child).getException(); + // If the SAXException tells us that it's message is identical to + // its nested exception's message, then we skip it, so we don't + // add it twice. + if (grandchild != null && msg2 != null && msg2.equals(grandchild.getMessage())) { + msg2 = null; + } + } + + // If we found a message for the child exception, we append it. + if (msg2 != null) { + if (msg != null) { + msg += ": " + msg2; + } else { + msg = msg2; + } + } + + // Any nested JDOMException will append its own children, + // so we need to break out of here. + if (child instanceof JDOMException) { + break; + } + parent = child; + } + + // Return the completed message. + return msg; + } + + /** + * This prints the stack trace of the Exception. If + * there is a root cause, the stack trace of the root + * Exception is printed right after. + */ + public void printStackTrace() { + // Print the stack trace for this exception. + super.printStackTrace(); + + Throwable parent = this; + Throwable child; + + // Print the stack trace for each nested exception. + while((child = getNestedException(parent)) != null) { + System.err.print("Caused by: "); + child.printStackTrace(); + // Any nested JDOMException will print its own children, + // so we need to break out of here. + if (child instanceof JDOMException) { + break; + } + parent = child; + } + } + + /** + * Prints the stack trace of the Exception to the given + * PrintStream. If there is a root cause, the stack trace of the root + * Exception is printed right after. + * + * @param s PrintStream to print to + */ + public void printStackTrace(PrintStream s) { + // Print the stack trace for this exception. + super.printStackTrace(s); + + Throwable parent = this; + Throwable child; + + // Print the stack trace for each nested exception. + while((child = getNestedException(parent)) != null) { + s.print("Caused by: "); + child.printStackTrace(s); + // Any nested JDOMException will print its own children, + // so we need to break out of here. + if (child instanceof JDOMException) { + break; + } + parent = child; + } + } + + /** + * Prints the stack trace of the Exception to the given + * PrintWriter. If there is a root cause, the stack trace of the root + * Exception is printed right after. + * + * @param w PrintWriter to print to + */ + public void printStackTrace(PrintWriter w) { + // Print the stack trace for this exception. + super.printStackTrace(w); + + Throwable parent = this; + Throwable child; + + // Print the stack trace for each nested exception. + while((child = getNestedException(parent)) != null) { + w.print("Caused by: "); + child.printStackTrace(w); + // Any nested JDOMException will print its own children, + // so we need to break out of here. + if (child instanceof JDOMException) { + break; + } + parent = child; + } + } + + /** + * This will return the root cause Throwable, or null + * if one does not exist. + * + * @return Throwable - the wrapped Throwable. + */ + public Throwable getCause() { + return cause; + } + + // If this Throwable has a nested (child) exception, then we return it. + // Otherwise we return null. + private static Throwable getNestedException(Throwable parent) { + if (parent instanceof JDOMException) { + return ((JDOMException)parent).getCause(); + } + + if (parent instanceof SAXException) { + return ((SAXException)parent).getException(); + } + + if (parent instanceof SQLException) { + return ((SQLException)parent).getNextException(); + } + + if (parent instanceof InvocationTargetException) { + return ((InvocationTargetException)parent).getTargetException(); + } + + if (parent instanceof ExceptionInInitializerError) { + return ((ExceptionInInitializerError)parent).getException(); + } + + // The RMI classes are not present in Android's Dalvik VM, so we use reflection to access them. + + Throwable nestedException = getNestedExceptionFromField(parent, "java.rmi.RemoteException", "detail"); + if (nestedException != null) { + return nestedException; + } + + // These classes are not part of standard JDK 1.1 or 1.2, so again we use reflection to access them. + + nestedException = getNestedException(parent, "javax.naming.NamingException", "getRootCause"); + if (nestedException != null) { + return nestedException; + } + + nestedException = getNestedException(parent, "javax.servlet.ServletException", "getRootCause"); + if (nestedException != null) { + return nestedException; + } + + return null; + } + + // This method uses reflection to obtain the nest exception of a Throwable. We use reflection + // because the desired class may not exist in the currently-running VM. + private static Throwable getNestedException( + Throwable parent, String className, String methodName) { + try { + // See if this Throwable is of the desired type, by using isAssignableFrom(). + Class testClass = Class.forName(className); + Class objectClass = parent.getClass(); + if (testClass.isAssignableFrom(objectClass)) { + // Use reflection to call the specified method. + Class[] argClasses = new Class[0]; + Method method = testClass.getMethod(methodName, argClasses); + Object[] args = new Object[0]; + return (Throwable)method.invoke(parent, args); + } + } + catch(Exception ex) { + // Most likely, the desired class is not available in this VM. That's fine. + // Even if it's caused by something else, we don't want to display an error + // here, since we're already in the process of trying to display the original + // error - another error here will just confuse things. + } + + return null; + } + + // This method is similar to getNestedException() except it looks for a field instead + // of a method. + private static Throwable getNestedExceptionFromField( + Throwable parent, String className, String fieldName) { + try { + // See if this Throwable is of the desired type, by using isAssignableFrom(). + Class testClass = Class.forName(className); + Class objectClass = parent.getClass(); + if (testClass.isAssignableFrom(objectClass)) { + // Use reflection to call the specified method. + Class[] argClasses = new Class[0]; + Field field = testClass.getField(fieldName); + return (Throwable)field.get(parent); + } + } + catch(Exception ex) { + // Most likely, the desired class is not available in this VM. That's fine. + // Could be that the named field isn't of type Throwable, but that should happen + // with proper call usage. + // Even if it's caused by something else, we don't want to display an error + // here, since we're already in the process of trying to display the original + // error - another error here will just confuse things. + } + + return null; + } +} Index: 3rdParty_sources/jdom/org/jdom/JDOMFactory.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/JDOMFactory.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/JDOMFactory.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,338 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * An interface to be used by builders when constructing JDOM objects. The + * DefaultJDOMFactory creates the standard top-level JDOM classes + * (Element, Document, Comment, etc). Another implementation of this factory + * could be used to create custom classes. + * + * @version $Revision$, $Date$ + * @author Ken Rune Holland + * @author Phil Nelson + * @author Bradley S. Huffman + */ +public interface JDOMFactory { + + // **** constructing Attributes **** + + /** + *

+ * This will create a new Attribute with the + * specified (local) name and value, and in the provided + * {@link org.jdom.Namespace}. + *

+ * + * @param name String name of Attribute. + * @param value String value for new attribute. + */ + public Attribute attribute(String name, String value, Namespace namespace); + + /** + * This will create a new Attribute with the + * specified (local) name, value, and type, and in the provided + * {@link org.jdom.Namespace}. + * + * @param name String name of Attribute. + * @param value String value for new attribute. + * @param type int type for new attribute. + * @param namespace Namespace namespace for new attribute. + */ + public Attribute attribute(String name, String value, + int type, Namespace namespace); + + /** + * This will create a new Attribute with the + * specified (local) name and value, and does not place + * the attribute in a {@link org.jdom.Namespace}. + *

+ * Note: This actually explicitly puts the + * Attribute in the "empty" Namespace + * ({@link org.jdom.Namespace#NO_NAMESPACE}). + *

+ * + * @param name String name of Attribute. + * @param value String value for new attribute. + */ + public Attribute attribute(String name, String value); + + /** + * This will create a new Attribute with the + * specified (local) name, value and type, and does not place + * the attribute in a {@link org.jdom.Namespace}. + *

+ * Note: This actually explicitly puts the + * Attribute in the "empty" Namespace + * ({@link org.jdom.Namespace#NO_NAMESPACE}). + *

+ * + * @param name String name of Attribute. + * @param value String value for new attribute. + * @param type int type for new attribute. + */ + public Attribute attribute(String name, String value, int type); + + // **** constructing CDATA **** + + /** + * This creates the CDATA with the supplied text. + * + * @param str String content of CDATA. + */ + public CDATA cdata(String str); + + // **** constructing Text **** + + /** + * This creates the Text with the supplied text. + * + * @param str String content of Text. + */ + public Text text(String str); + + // **** constructing Comment **** + + /** + * This creates the comment with the supplied text. + * + * @param text String content of comment. + */ + public Comment comment(String text); + + // **** constructing DocType + + /** + * This will create the DocType with + * the specified element name and a reference to an + * external DTD. + * + * @param elementName String name of + * element being constrained. + * @param publicID String public ID of + * referenced DTD + * @param systemID String system ID of + * referenced DTD + */ + public DocType docType(String elementName, + String publicID, String systemID); + + /** + * This will create the DocType with + * the specified element name and reference to an + * external DTD. + * + * @param elementName String name of + * element being constrained. + * @param systemID String system ID of + * referenced DTD + */ + public DocType docType(String elementName, String systemID); + + /** + * This will create the DocType with + * the specified element name + * + * @param elementName String name of + * element being constrained. + */ + public DocType docType(String elementName); + + // **** constructing Document + + /** + * This will create a new Document, + * with the supplied {@link org.jdom.Element} + * as the root element and the supplied + * {@link org.jdom.DocType} declaration. + * + * @param rootElement Element for document root. + * @param docType DocType declaration. + */ + public Document document(Element rootElement, DocType docType); + + /** + * This will create a new Document, + * with the supplied {@link org.jdom.Element} + * as the root element and the supplied + * {@link org.jdom.DocType} declaration. + * + * @param rootElement Element for document root. + * @param docType DocType declaration. + * @param baseURI the URI from which this doucment was loaded. + */ + public Document document(Element rootElement, DocType docType, String baseURI); + + /** + * This will create a new Document, + * with the supplied {@link org.jdom.Element} + * as the root element, and no {@link org.jdom.DocType} + * declaration. + * + * @param rootElement Element for document root + */ + public Document document(Element rootElement); + + // **** constructing Elements **** + + /** + * This will create a new Element + * with the supplied (local) name, and define + * the {@link org.jdom.Namespace} to be used. + * + * @param name String name of element. + * @param namespace Namespace to put element in. + */ + public Element element(String name, Namespace namespace); + + /** + * This will create an Element in no + * {@link org.jdom.Namespace}. + * + * @param name String name of element. + */ + public Element element(String name); + + /** + * This will create a new Element with + * the supplied (local) name, and specifies the URI + * of the {@link org.jdom.Namespace} the Element + * should be in, resulting it being unprefixed (in the default + * namespace). + * + * @param name String name of element. + * @param uri String URI for Namespace element + * should be in. + */ + public Element element(String name, String uri); + + /** + * This will create a new Element with + * the supplied (local) name, and specifies the prefix and URI + * of the {@link org.jdom.Namespace} the Element + * should be in. + * + * @param name String name of element. + * @param uri String URI for Namespace element + * should be in. + */ + public Element element(String name, String prefix, String uri); + + // **** constructing ProcessingInstruction **** + + /** + * This will create a new ProcessingInstruction + * with the specified target and data. + * + * @param target String target of PI. + * @param data Map data for PI, in + * name/value pairs + */ + public ProcessingInstruction processingInstruction(String target, + Map data); + + /** + * This will create a new ProcessingInstruction + * with the specified target and data. + * + * @param target String target of PI. + * @param data String data for PI. + */ + public ProcessingInstruction processingInstruction(String target, + String data); + + // **** constructing EntityRef **** + + /** + * This will create a new EntityRef + * with the supplied name. + * + * @param name String name of element. + */ + public EntityRef entityRef(String name); + + /** + * This will create a new EntityRef + * with the supplied name, public ID, and system ID. + * + * @param name String name of element. + * @param publicID String public ID of element. + * @param systemID String system ID of element. + */ + public EntityRef entityRef(String name, String publicID, String systemID); + + /** + * This will create a new EntityRef + * with the supplied name and system ID. + * + * @param name String name of element. + * @param systemID String system ID of element. + */ + public EntityRef entityRef(String name, String systemID); + + // ===================================================================== + // List manipulation + // ===================================================================== + + public void addContent(Parent parent, Content content); + + public void setAttribute(Element element, Attribute a); + + public void addNamespaceDeclaration(Element element, Namespace additional); +} Index: 3rdParty_sources/jdom/org/jdom/Namespace.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Namespace.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Namespace.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,276 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * An XML namespace representation, as well as a factory for creating XML + * namespace objects. Namespaces are not Serializable, however objects that use + * namespaces have special logic to handle serialization manually. These classes + * call the getNamespace() method on deserialization to ensure there is one + * unique Namespace object for any unique prefix/uri pair. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Elliotte Rusty Harold + * @author Jason Hunter + * @author Wesley Biggs + */ +public final class Namespace { + + // XXX May want to use weak references to keep the maps from growing + // large with extended use + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Factory list of namespaces. + * Keys are prefix&URI. + * Values are Namespace objects + */ + private static HashMap namespaces; + + /** Define a Namespace for when not in a namespace */ + public static final Namespace NO_NAMESPACE = new Namespace("", ""); + + /** Define a Namespace for the standard xml prefix. */ + public static final Namespace XML_NAMESPACE = + new Namespace("xml", "http://www.w3.org/XML/1998/namespace"); + + /** The prefix mapped to this namespace */ + private String prefix; + + /** The URI for this namespace */ + private String uri; + + /** + * This static initializer acts as a factory contructor. + * It sets up storage and required initial values. + */ + static { + namespaces = new HashMap(16); + + // Add the "empty" namespace + namespaces.put(new NamespaceKey(NO_NAMESPACE), NO_NAMESPACE); + namespaces.put(new NamespaceKey(XML_NAMESPACE), XML_NAMESPACE); + } + + /** + * This will retrieve (if in existence) or create (if not) a + * Namespace for the supplied prefix and URI. + * + * @param prefix String prefix to map to + * Namespace. + * @param uri String URI of new Namespace. + * @return Namespace - ready to use namespace. + * @throws IllegalNameException if the given prefix and uri make up + * an illegal namespace name. + */ + public static Namespace getNamespace(String prefix, String uri) { + // Sanity checking + if ((prefix == null) || (prefix.trim().equals(""))) { + // Short-cut out for common case of no namespace + if ((uri == null) || (uri.trim().equals(""))) { + return NO_NAMESPACE; + } + prefix = ""; + } + else if ((uri == null) || (uri.trim().equals(""))) { + uri = ""; + } + + // Return existing namespace if found. The preexisting namespaces + // should all be legal. In other words, an illegal namespace won't + // have been placed in this. Thus we can do this test before + // verifying the URI and prefix. + NamespaceKey lookup = new NamespaceKey(prefix, uri); + Namespace preexisting; + synchronized (namespaces) { + preexisting = (Namespace) namespaces.get(lookup); + } + if (preexisting != null) { + return preexisting; + } + + // Ensure proper naming + String reason; + if ((reason = Verifier.checkNamespacePrefix(prefix)) != null) { + throw new IllegalNameException(prefix, "Namespace prefix", reason); + } + if ((reason = Verifier.checkNamespaceURI(uri)) != null) { + throw new IllegalNameException(uri, "Namespace URI", reason); + } + + // Unless the "empty" Namespace (no prefix and no URI), require a URI + if ((!prefix.equals("")) && (uri.equals(""))) { + throw new IllegalNameException("", "namespace", + "Namespace URIs must be non-null and non-empty Strings"); + } + + // Handle XML namespace mislabels. If the user requested the correct + // namespace and prefix -- xml, http://www.w3.org/XML/1998/namespace + // -- then it was already returned from the preexisting namespaces. + // Thus any use of the xml prefix or the + // http://www.w3.org/XML/1998/namespace URI at this point must be + // incorrect. + if (prefix.equals("xml")) { + throw new IllegalNameException(prefix, "Namespace prefix", + "The xml prefix can only be bound to " + + "http://www.w3.org/XML/1998/namespace"); + } + + // The erratum to Namespaces in XML 1.0 that suggests this + // next check is controversial. Not everyone accepts it. + if (uri.equals("http://www.w3.org/XML/1998/namespace")) { + throw new IllegalNameException(uri, "Namespace URI", + "The http://www.w3.org/XML/1998/namespace must be bound to " + + "the xml prefix."); + } + + // Finally, store and return + Namespace ns = new Namespace(prefix, uri); + synchronized (namespaces) { + namespaces.put(lookup, ns); + } + return ns; + } + + /** + * This will retrieve (if in existence) or create (if not) a + * Namespace for the supplied URI, and make it usable + * as a default namespace, as no prefix is supplied. + * + * @param uri String URI of new Namespace. + * @return Namespace - ready to use namespace. + */ + public static Namespace getNamespace(String uri) { + return getNamespace("", uri); + } + + /** + * This constructor handles creation of a Namespace object + * with a prefix and URI; it is intentionally left private + * so that it cannot be invoked by external programs/code. + * + * @param prefix String prefix to map to this namespace. + * @param uri String URI for namespace. + */ + private Namespace(String prefix, String uri) { + this.prefix = prefix; + this.uri = uri; + } + + /** + * This returns the prefix mapped to this Namespace. + * + * @return String - prefix for this Namespace. + */ + public String getPrefix() { + return prefix; + } + + /** + * This returns the namespace URI for this Namespace. + * + * @return String - URI for this Namespace. + */ + public String getURI() { + return uri; + } + + /** + * This tests for equality - Two Namespaces + * are equal if and only if their URIs are byte-for-byte equals. + * + * @param ob Object to compare to this Namespace. + * @return boolean - whether the supplied object is equal to + * this Namespace. + */ + public boolean equals(Object ob) { + if (this == ob) { + return true; + } + if (ob instanceof Namespace) { // instanceof returns false if null + return uri.equals(((Namespace)ob).uri); + } + return false; + } + + /** + * This returns a String representation of this + * Namespace, suitable for use in debugging. + * + * @return String - information about this instance. + */ + public String toString() { + return "[Namespace: prefix \"" + prefix + "\" is mapped to URI \"" + + uri + "\"]"; + } + + /** + * This returns a probably unique hash code for the Namespace. + * If two namespaces have the same URI, they are equal and have the same + * hash code, even if they have different prefixes. + * + * @return int - hash code for this Namespace. + */ + public int hashCode() { + return uri.hashCode(); + } +} Index: 3rdParty_sources/jdom/org/jdom/NamespaceKey.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/NamespaceKey.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/NamespaceKey.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,108 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * Key for storing a namespace representation in a map. + * + * @version $Revision$, $Date$ + * @author Tatu Saloranta + * @author Bradley S. Huffman + */ +final class NamespaceKey { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + private String prefix; + private String uri; + private int hash; + + public NamespaceKey(String prefix, String uri) { + this.prefix = prefix; + this.uri = uri; + this.hash = prefix.hashCode(); + } + + public NamespaceKey(Namespace namespace) { + this(namespace.getPrefix(), namespace.getURI()); + } + + public boolean equals(Object ob) { + if (this == ob) { + return true; + } + else if (ob instanceof NamespaceKey) { + NamespaceKey other = (NamespaceKey) ob; + return prefix.equals(other.prefix) && uri.equals(other.uri); + } + else { + return false; + } + } + + public int hashCode() { + return hash; + } + + public String toString() { + return "[NamespaceKey: prefix \"" + prefix + + "\" is mapped to URI \"" + uri + "\"]"; + } +} Index: 3rdParty_sources/jdom/org/jdom/Parent.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Parent.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Parent.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,239 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.io.Serializable; +import java.util.*; +import org.jdom.filter.Filter; + +/** + * Superclass for JDOM objects which are allowed to contain + * {@link Content} content. + * + * @see org.jdom.Content + * @see org.jdom.Document + * @see org.jdom.Element + * + * @author Bradley S. Huffman + * @author Jason Hunter + * @version $Revision$, $Date$ + */ +public interface Parent extends Cloneable, Serializable { + + /** + * Returns the number of children in this parent's content list. + * Children may be any {@link Content} type. + * + * @return number of children + */ + int getContentSize(); + + /** + * Returns the index of the supplied child in the content list, + * or -1 if not a child of this parent. + * + * @param child child to search for + * @return index of child, or -1 if not found + */ + int indexOf(Content child); + +// /** +// * Starting at the given index (inclusive), returns 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 +// */ +// int indexOf(int index, Filter filter); + + /** + * Returns a list containing detached clones of this parent's content list. + * + * @return list of cloned child content + */ + List cloneContent(); + + /** + * Returns the child at the given index. + * + * @param index location of desired child + * @return child at the given index + * @throws IndexOutOfBoundsException if index is negative or beyond + * the current number of children + * @throws IllegalStateException if parent is a Document + * and the root element is not set + */ + Content getContent(int index); + + /** + * Returns the full content of this parent as a {@link java.util.List} + * which contains objects of type {@link Content}. The returned list is + * "live" and in document order. Any modifications + * to it affect the element's actual contents. Modifications are checked + * for conformance to XML 1.0 rules. + *

+ * Sequential traversal through the List is best done with an Iterator + * since the underlying implement of {@link java.util.List#size} may + * require walking the entire list and indexed lookups may require + * starting at the beginning each time. + * + * @return a list of the content of the parent + * @throws IllegalStateException if parent is a Document + * and the root element is not set + */ + List getContent(); + + /** + * Returns as a {@link java.util.List} the content of + * this parent that matches the supplied filter. The returned list is + * "live" and in document order. Any modifications to it affect + * the element's actual contents. Modifications are checked for + * conformance to XML 1.0 rules. + *

+ * Sequential traversal through the List is best done with an Iterator + * since the underlying implement of {@link java.util.List#size} may + * require walking the entire list and indexed lookups may require + * starting at the beginning each time. + * + * @param filter filter to apply + * @return a list of the content of the parent matching the filter + * @throws IllegalStateException if parent is a Document + * and the root element is not set + */ + List getContent(Filter filter); + + /** + * Removes all content from this parent and returns the detached + * children. + * + * @return list of the old content detached from this parent + */ + List removeContent(); + + /** + * Removes from this parent all child content matching the given filter + * and returns a list of the detached children. + * + * @param filter filter to apply + * @return list of the detached children matching the filter + */ + List removeContent(Filter filter); + + /** + * Removes a single child node from the content list. + * + * @param child child to remove + * @return whether the removal occurred + */ + boolean removeContent(Content child); + + /** + * Removes and returns the child at the given + * index, or returns null if there's no such child. + * + * @param index index of child to remove + * @return detached child at given index or null if no + * @throws IndexOutOfBoundsException if index is negative or beyond + * the current number of children + */ + Content removeContent(int index); + + /** + * Obtain a deep, unattached copy of this parent and it's children. + * + * @return a deep copy of this parent and it's children. + */ + Object clone(); + + /** + * Returns an {@link java.util.Iterator} that walks over all descendants + * in document order. + * + * @return an iterator to walk descendants + */ + Iterator getDescendants(); + + /** + * Returns an {@link java.util.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 that match a filter + */ + Iterator getDescendants(Filter filter); + + /** + * Return this parent's parent, or null if this parent is currently + * not attached to another parent. This is the same method as in Content but + * also added to Parent to allow more easy up-the-tree walking. + * + * @return this parent's parent or null if none + */ + Parent getParent(); + + /** + * Return this parent's owning document or null if the branch containing + * this parent is currently not attached to a document. + * + * @return this child's owning document or null if none + */ + Document getDocument(); + +} Index: 3rdParty_sources/jdom/org/jdom/ProcessingInstruction.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/ProcessingInstruction.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/ProcessingInstruction.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,474 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * An XML processing instruction. Methods allow the user to obtain the target of + * the PI as well as its data. The data can always be accessed as a String or, + * if the data appears akin to an attribute list, can be retrieved as name/value + * pairs. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Steven Gould + */ + +public class ProcessingInstruction extends Content { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The target of the PI */ + protected String target; + + /** The data for the PI as a String */ + protected String rawData; + + /** The data for the PI in name/value pairs */ + protected Map mapData; + + /** + * Default, no-args constructor for implementations + * to use if needed. + */ + protected ProcessingInstruction() { } + + /** + * This will create a new ProcessingInstruction + * with the specified target and data. + * + * @param target String target of PI. + * @param data Map data for PI, in + * name/value pairs + * @throws IllegalTargetException if the given target is illegal + * as a processing instruction name. + */ + public ProcessingInstruction(String target, Map data) { + setTarget(target); + setData(data); + } + + /** + * This will create a new ProcessingInstruction + * with the specified target and data. + * + * @param target String target of PI. + * @param data String data for PI. + * @throws IllegalTargetException if the given target is illegal + * as a processing instruction name. + */ + public ProcessingInstruction(String target, String data) { + setTarget(target); + setData(data); + } + + /** + * This will set the target for the PI. + * + * @param newTarget String new target of PI. + * @return ProcessingInstruction - this PI modified. + */ + public ProcessingInstruction setTarget(String newTarget) { + String reason; + if ((reason = Verifier.checkProcessingInstructionTarget(newTarget)) + != null) { + throw new IllegalTargetException(newTarget, reason); + } + + target = newTarget; + return this; + } + + /** + * Returns the XPath 1.0 string value of this element, which is the + * data of this PI. + * + * @return the data of this PI + */ + public String getValue() { + return rawData; + } + + + /** + * This will retrieve the target of the PI. + * + * @return String - target of PI. + */ + public String getTarget() { + return target; + } + + /** + * This will return the raw data from all instructions. + * + * @return String - data of PI. + */ + public String getData() { + return rawData; + } + + /** + * This will return a List containing the names of the + * "attribute" style pieces of name/value pairs in this PI's data. + * + * @return List - the List containing the + * "attribute" names. + */ + public List getPseudoAttributeNames() { + Set mapDataSet = mapData.entrySet(); + List nameList = new ArrayList(); + for (Iterator i = mapDataSet.iterator(); i.hasNext();) { + String wholeSet = (i.next()).toString(); + String attrName = wholeSet.substring(0,(wholeSet.indexOf("="))); + nameList.add(attrName); + } + return nameList; + } + + /** + * This will set the raw data for the PI. + * + * @param data String data of PI. + * @return ProcessingInstruction - this PI modified. + */ + public ProcessingInstruction setData(String data) { + String reason = Verifier.checkProcessingInstructionData(data); + if (reason != null) { + throw new IllegalDataException(data, reason); + } + + this.rawData = data; + this.mapData = parseData(data); + return this; + } + + /** + * This will set the name/value pairs within the passed + * Map as the pairs for the data of + * this PI. The keys should be the pair name + * and the values should be the pair values. + * + * @param data new map data to use + * @return ProcessingInstruction - modified PI. + */ + public ProcessingInstruction setData(Map data) { + String temp = toString(data); + + String reason = Verifier.checkProcessingInstructionData(temp); + if (reason != null) { + throw new IllegalDataException(temp, reason); + } + + this.rawData = temp; + // make a copy of the data. + this.mapData = new HashMap(data); + return this; + } + + + /** + * This will return the value for a specific + * name/value pair on the PI. If no such pair is + * found for this PI, null is returned. + * + * @param name String name of name/value pair + * to lookup value for. + * @return String - value of name/value pair. + */ + public String getPseudoAttributeValue(String name) { + return (String)mapData.get(name); + } + + /** + * This will set a pseudo attribute with the given name and value. + * If the PI data is not already in a pseudo-attribute format, this will + * replace the existing data. + * + * @param name String name of pair. + * @param value String value for pair. + * @return ProcessingInstruction this PI modified. + */ + public ProcessingInstruction setPseudoAttribute(String name, String value) { + String reason = Verifier.checkProcessingInstructionData(name); + if (reason != null) { + throw new IllegalDataException(name, reason); + } + + reason = Verifier.checkProcessingInstructionData(value); + if (reason != null) { + throw new IllegalDataException(value, reason); + } + + this.mapData.put(name, value); + this.rawData = toString(mapData); + return this; + } + + + /** + * This will remove the pseudo attribute with the specified name. + * + * @param name name of pseudo attribute to remove + * @return boolean - whether the requested + * instruction was removed. + */ + public boolean removePseudoAttribute(String name) { + if ((mapData.remove(name)) != null) { + rawData = toString(mapData); + return true; + } + + return false; + } + + /** + * This will convert the Map to a string representation. + * + * @param mapData Map PI data to convert + * @return a string representation of the Map as appropriate for a PI + */ + private String toString(Map mapData) { + StringBuffer rawData = new StringBuffer(); + + Iterator i = mapData.keySet().iterator(); + while (i.hasNext()) { + String name = (String)i.next(); + String value = (String)mapData.get(name); + rawData.append(name) + .append("=\"") + .append(value) + .append("\" "); + } + // Remove last space, if we did any appending + if (rawData.length() > 0) { + rawData.setLength(rawData.length() - 1); + } + + return rawData.toString(); + } + + /** + * This will parse and load the instructions for the PI. + * This is separated to allow it to occur once and then be reused. + */ + private Map parseData(String rawData) { + // The parsing here is done largely "by hand" which means the code + // gets a little tricky/messy. The following conditions should + // now be handled correctly: + // Reads OK + // Reads OK + // Reads OK + // Reads OK + // Empty Map + // Empty Map + // Empty Map + + Map data = new HashMap(); + + // System.out.println("rawData: " + rawData); + + // The inputData variable holds the part of rawData left to parse + String inputData = rawData.trim(); + + // Iterate through the remaining inputData string + while (!inputData.trim().equals("")) { + //System.out.println("parseData() looking at: " + inputData); + + // Search for "name =", "name=" or "name1 name2..." + String name = ""; + String value = ""; + int startName = 0; + char previousChar = inputData.charAt(startName); + int pos = 1; + for (; pos 0 && value != null) { + //if (data.containsKey(name)) { + // A repeat, that's a parse error, so return a null map + //return new HashMap(); + //} + //else { + data.put(name, value); + //} + } + } + + return data; + } + + /** + * This is a helper routine, only used by parseData, to extract a + * quoted String from the input parameter, rawData. A quoted string + * can use either single or double quotes, but they must match up. + * A singly quoted string can contain an unbalanced amount of double + * quotes, or vice versa. For example, the String "JDOM's the best" + * is legal as is 'JDOM"s the best'. + * + * @param rawData the input string from which a quoted string is to + * be extracted. + * @return the first quoted string encountered in the input data. If + * no quoted string is found, then the empty string, "", is + * returned. + * @see #parseData + */ + private static int[] extractQuotedString(String rawData) { + // Remembers whether we're actually in a quoted string yet + boolean inQuotes = false; + + // Remembers which type of quoted string we're in + char quoteChar = '"'; + + // Stores the position of the first character inside + // the quoted string (i.e. the start of the return string) + int start = 0; + + // Iterate through the input string looking for the start + // and end of the quoted string + for (int pos=0; pos < rawData.length(); pos++) { + char currentChar = rawData.charAt(pos); + if (currentChar=='"' || currentChar=='\'') { + if (!inQuotes) { + // We're entering a quoted string + quoteChar = currentChar; + inQuotes = true; + start = pos+1; + } + else if (quoteChar == currentChar) { + // We're leaving a quoted string + inQuotes = false; + return new int[] { start, pos }; + } + // Otherwise we've encountered a quote + // inside a quote, so just continue + } + } + + return null; + } + + /** + * This returns a String representation of the + * ProcessingInstruction, suitable for debugging. If the XML + * representation of the ProcessingInstruction is desired, + * {@link org.jdom.output.XMLOutputter#outputString(ProcessingInstruction)} + * should be used. + * + * @return String - information about the + * ProcessingInstruction + */ + public String toString() { + return new StringBuffer() + .append("[ProcessingInstruction: ") + .append(new org.jdom.output.XMLOutputter().outputString(this)) + .append("]") + .toString(); + } + + /** + * This will return a clone of this ProcessingInstruction. + * + * @return Object - clone of this + * ProcessingInstruction. + */ + public Object clone() { + ProcessingInstruction pi = (ProcessingInstruction) super.clone(); + + // target and rawdata are immutable and references copied by + // Object.clone() + + // Create a new Map object for the clone (since Map isn't Cloneable) + if (mapData != null) { + pi.mapData = parseData(rawData); + } + return pi; + } +} Index: 3rdParty_sources/jdom/org/jdom/Text.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Text.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Text.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,271 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +/** + * Character-based XML content. Provides a modular, parentable method of + * representing text. Text makes no guarantees about the underlying textual + * representation of character data, but does expose that data as a Java String. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Bradley S. Huffman + */ +public class Text extends Content { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + static final String EMPTY_STRING = ""; + + /** The actual character content */ + // XXX See http://www.servlets.com/archive/servlet/ReadMsg?msgId=8612 + // from elharo for a description of why Java characters may not suffice + // long term + protected String value; + + /** + * This is the protected, no-args constructor standard in all JDOM + * classes. It allows subclassers to get a raw instance with no + * initialization. + */ + protected Text() { } + + /** + * This constructor creates a new Text node, with the + * supplied string value as it's character content. + * + * @param str the node's character content. + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + */ + public Text(String str) { + setText(str); + } + + /** + * This returns the value of this Text node as a Java + * String. + * + * @return String - character content of this node. + */ + public String getText() { + return value; + } + + /** + * This returns the textual content with all surrounding whitespace + * removed. If only whitespace exists, the empty string is returned. + * + * @return trimmed text content or empty string + */ + public String getTextTrim() { + return getText().trim(); + } + + /** + * This returns the textual content with all surrounding whitespace + * removed and internal whitespace normalized to a single space. If + * only whitespace exists, the empty string is returned. + * + * @return normalized text content or empty string + */ + public String getTextNormalize() { + return normalizeString(getText()); + } + + /** + * This returns a new string with all surrounding whitespace + * removed and internal whitespace normalized to a single space. If + * only whitespace exists, the empty string is returned. + *

+ * Per XML 1.0 Production 3 whitespace includes: #x20, #x9, #xD, #xA + *

+ * + * @param str string to be normalized. + * @return normalized string or empty string + */ + public static String normalizeString(String str) { + if (str == null) + return EMPTY_STRING; + + char[] c = str.toCharArray(); + char[] n = new char[c.length]; + boolean white = true; + int pos = 0; + for (int i = 0; i < c.length; i++) { + if (" \t\n\r".indexOf(c[i]) != -1) { + if (!white) { + n[pos++] = ' '; + white = true; + } + } + else { + n[pos++] = c[i]; + white = false; + } + } + if (white && pos > 0) { + pos--; + } + return new String(n, 0, pos); + } + + /** + * This will set the value of this Text node. + * + * @param str value for node's content. + * @return the object on which the method was invoked + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + */ + public Text setText(String str) { + String reason; + + if (str == null) { + value = EMPTY_STRING; + return this; + } + + if ((reason = Verifier.checkCharacterData(str)) != null) { + throw new IllegalDataException(str, "character content", reason); + } + value = str; + return this; + } + + /** + * This will append character content to whatever content already + * exists within this Text node. + * + * @param str character content to append. + * @throws IllegalDataException if str contains an + * illegal character such as a vertical tab (as determined + * by {@link org.jdom.Verifier#checkCharacterData}) + */ + public void append(String str) { + String reason; + + if (str == null) { + return; + } + if ((reason = Verifier.checkCharacterData(str)) != null) { + throw new IllegalDataException(str, "character content", reason); + } + + if (str.length() > 0) { + value += str; + } + } + + /** + * This will append the content of another Text node + * to this node. + * + * @param text Text node to append. + */ + public void append(Text text) { + if (text == null) { + return; + } + value += text.getText(); + } + + /** + * Returns the XPath 1.0 string value of this element, which is the + * text itself. + * + * @return the text + */ + public String getValue() { + return value; + } + + /** + * This returns a String representation of the + * Text node, suitable for debugging. If the XML + * representation of the Text node is desired, + * either {@link #getText} or + * {@link org.jdom.output.XMLOutputter#outputString(Text)} + * should be used. + * + * @return String - information about this node. + */ + public String toString() { + return new StringBuffer(64) + .append("[Text: ") + .append(getText()) + .append("]") + .toString(); + } + + /** + * This will return a clone of this Text node, with the + * same character content, but no parent. + * + * @return Text - cloned node. + */ + public Object clone() { + Text text = (Text)super.clone(); + text.value = value; + return text; + } + +} Index: 3rdParty_sources/jdom/org/jdom/UncheckedJDOMFactory.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/UncheckedJDOMFactory.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/UncheckedJDOMFactory.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,287 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * Special factory for building documents without any content or structure + * checking. This should only be used when you are 100% positive that the + * input is absolutely correct. This factory can speed builds, but any + * problems in the input will be uncaught until later when they could cause + * infinite loops, malformed XML, or worse. Use with extreme caution. + */ +public class UncheckedJDOMFactory implements JDOMFactory { + + // ===================================================================== + // Element Factory + // ===================================================================== + + public Element element(String name, Namespace namespace) { + Element e = new Element(); + e.name = name; + if (namespace == null) { + namespace = Namespace.NO_NAMESPACE; + } + e.namespace = namespace; + return e; + } + + public Element element(String name) { + Element e = new Element(); + e.name = name; + e.namespace = Namespace.NO_NAMESPACE; + return e; + } + + public Element element(String name, String uri) { + return element(name, Namespace.getNamespace("", uri)); + } + + public Element element(String name, String prefix, String uri) { + return element(name, Namespace.getNamespace(prefix, uri)); + } + + // ===================================================================== + // Attribute Factory + // ===================================================================== + + public Attribute attribute(String name, String value, Namespace namespace) { + Attribute a = new Attribute(); + a.name = name; + a.value = value; + if (namespace == null) { + namespace = Namespace.NO_NAMESPACE; + } + a.namespace = namespace; + return a; + } + + public Attribute attribute(String name, String value, int type, Namespace namespace) { + Attribute a = new Attribute(); + a.name = name; + a.type = type; + a.value = value; + if (namespace == null) { + namespace = Namespace.NO_NAMESPACE; + } + a.namespace = namespace; + return a; + } + + public Attribute attribute(String name, String value) { + Attribute a = new Attribute(); + a.name = name; + a.value = value; + a.namespace = Namespace.NO_NAMESPACE; + return a; + } + + public Attribute attribute(String name, String value, int type) { + Attribute a = new Attribute(); + a.name = name; + a.type = type; + a.value = value; + a.namespace = Namespace.NO_NAMESPACE; + return a; + } + + // ===================================================================== + // Text Factory + // ===================================================================== + + public Text text(String str) { + Text t = new Text(); + t.value = str; + return t; + } + + // ===================================================================== + // CDATA Factory + // ===================================================================== + + public CDATA cdata(String str) { + CDATA c = new CDATA(); + c.value = str; + return c; + } + + // ===================================================================== + // Comment Factory + // ===================================================================== + + public Comment comment(String str) { + Comment c = new Comment(); + c.text = str; + return c; + } + + // ===================================================================== + // Processing Instruction Factory + // ===================================================================== + + public ProcessingInstruction processingInstruction(String target, Map data) { + ProcessingInstruction p = new ProcessingInstruction(); + p.target = target; + p.setData(data); + return p; + } + + public ProcessingInstruction processingInstruction(String target, String data) { + ProcessingInstruction p = new ProcessingInstruction(); + p.target = target; + p.setData(data); + return p; + } + + // ===================================================================== + // Entity Ref Factory + // ===================================================================== + + public EntityRef entityRef(String name) { + EntityRef e = new org.jdom.EntityRef(); + e.name = name; + return e; + } + + public EntityRef entityRef(String name, String systemID) { + EntityRef e = new EntityRef(); + e.name = name; + e.systemID = systemID; + return e; + } + + public EntityRef entityRef(String name, String publicID, String systemID) { + EntityRef e = new EntityRef(); + e.name = name; + e.publicID = publicID; + e.systemID = systemID; + return e; + } + + // ===================================================================== + // DocType Factory + // ===================================================================== + + public DocType docType(String elementName, String publicID, String systemID) { + DocType d = new DocType(); + d.elementName = elementName; + d.publicID = publicID; + d.systemID = systemID; + return d; + } + + public DocType docType(String elementName, String systemID) { + return docType(elementName, null, systemID); + } + + public DocType docType(String elementName) { + return docType(elementName, null, null); + } + + // ===================================================================== + // Document Factory + // ===================================================================== + + public Document document(Element rootElement, DocType docType, String baseURI) { + Document d = new Document(); + if (docType != null) { + addContent(d, docType); + } + if (rootElement != null) { + addContent(d, rootElement); + } + if (baseURI != null) { + d.baseURI = baseURI; + } + return d; + } + + public Document document(Element rootElement, DocType docType) { + return document(rootElement, docType, null); + } + + public Document document(Element rootElement) { + return document(rootElement, null, null); + } + + // ===================================================================== + // List manipulation + // ===================================================================== + + public void addContent(Parent parent, Content child) { + if (parent instanceof Element) { + Element elt = (Element) parent; + elt.content.uncheckedAddContent(child); + } + else { + Document doc = (Document) parent; + doc.content.uncheckedAddContent(child); + } + } + + public void setAttribute(Element parent, Attribute a) { + parent.attributes.uncheckedAddAttribute(a); + } + + public void addNamespaceDeclaration(Element parent, Namespace additional) { + if (parent.additionalNamespaces == null) { + parent.additionalNamespaces = new ArrayList(5); //Element.INITIAL_ARRAY_SIZE + } + parent.additionalNamespaces.add(additional); + } +} Index: 3rdParty_sources/jdom/org/jdom/Verifier.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/Verifier.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/Verifier.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,1271 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom; + +import java.util.*; + +/** + * A utility class to handle well-formedness checks on names, data, and other + * verification tasks for JDOM. The class is final and may not be subclassed. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Elliotte Rusty Harold + * @author Jason Hunter + * @author Bradley S. Huffman + */ +final public class Verifier { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Ensure instantation cannot occur. + */ + private Verifier() { } + + /** + * This will check the supplied name to see if it is legal for use as + * a JDOM {@link Element} name. + * + * @param name String name to check. + * @return String reason name is illegal, or + * null if name is OK. + */ + public static String checkElementName(String name) { + // Check basic XML name rules first + String reason; + if ((reason = checkXMLName(name)) != null) { + return reason; + } + + // No colons allowed, since elements handle this internally + if (name.indexOf(":") != -1) { + return "Element names cannot contain colons"; + } + + // If we got here, everything is OK + return null; + } + + /** + * This will check the supplied name to see if it is legal for use as + * a JDOM {@link Attribute} name. + * + * @param name String name to check. + * @return String reason name is illegal, or + * null if name is OK. + */ + public static String checkAttributeName(String name) { + // Check basic XML name rules first + String reason; + if ((reason = checkXMLName(name)) != null) { + return reason; + } + + // No colons are allowed, since attributes handle this internally + if (name.indexOf(":") != -1) { + return "Attribute names cannot contain colons"; + } + + // Attribute names may not be xmlns since we do this internally too + if (name.equals("xmlns")) { + return "An Attribute name may not be \"xmlns\"; " + + "use the Namespace class to manage namespaces"; + } + + // If we got here, everything is OK + return null; + } + + /** + * This will check the supplied string to see if it only contains + * characters allowed by the XML 1.0 specification. The C0 controls + * (e.g. null, vertical tab, formfeed, etc.) are specifically excluded + * except for carriage return, linefeed, and the horizontal tab. + * Surrogates are also excluded. + *

+ * This method is useful for checking element content and attribute + * values. Note that characters + * like " and < are allowed in attribute values and element content. + * They will simply be escaped as " or < + * when the value is serialized. + *

+ * + * @param text String value to check. + * @return String reason name is illegal, or + * null if name is OK. + */ + public static String checkCharacterData(String text) { + if (text == null) { + return "A null is not a legal XML value"; + } + + // Do check + for (int i = 0, len = text.length(); i{@link CDATA}. + * + * @param data String data to check. + * @return String reason data is illegal, or + * null is name is OK. + */ + public static String checkCDATASection(String data) { + String reason = null; + if ((reason = checkCharacterData(data)) != null) { + return reason; + } + + if (data.indexOf("]]>") != -1) { + return "CDATA cannot internally contain a CDATA ending " + + "delimiter (]]>)"; + } + + // If we got here, everything is OK + return null; + } + + /** + * This will check the supplied name to see if it is legal for use as + * a JDOM {@link Namespace} prefix. + * + * @param prefix String prefix to check. + * @return String reason name is illegal, or + * null if name is OK. + */ + public static String checkNamespacePrefix(String prefix) { + // Manually do rules, since URIs can be null or empty + if ((prefix == null) || (prefix.equals(""))) { + return null; + } + + // Cannot start with a number + char first = prefix.charAt(0); + if (isXMLDigit(first)) { + return "Namespace prefixes cannot begin with a number"; + } + // Cannot start with a $ + if (first == '$') { + return "Namespace prefixes cannot begin with a dollar sign ($)"; + } + // Cannot start with a - + if (first == '-') { + return "Namespace prefixes cannot begin with a hyphen (-)"; + } + // Cannot start with a . + if (first == '.') { + return "Namespace prefixes cannot begin with a period (.)"; + } + // Cannot start with "xml" in any character case + if (prefix.toLowerCase().startsWith("xml")) { + return "Namespace prefixes cannot begin with " + + "\"xml\" in any combination of case"; + } + + // Ensure legal content + for (int i=0, len = prefix.length(); i{@link Namespace} URI. + * + * @param uri String URI to check. + * @return String reason name is illegal, or + * null if name is OK. + */ + public static String checkNamespaceURI(String uri) { + // Manually do rules, since URIs can be null or empty + if ((uri == null) || (uri.equals(""))) { + return null; + } + + // Cannot start with a number + char first = uri.charAt(0); + if (Character.isDigit(first)) { + return "Namespace URIs cannot begin with a number"; + } + // Cannot start with a $ + if (first == '$') { + return "Namespace URIs cannot begin with a dollar sign ($)"; + } + // Cannot start with a - + if (first == '-') { + return "Namespace URIs cannot begin with a hyphen (-)"; + } + + // If we got here, everything is OK + return null; + } + + /** + * Check if two namespaces collide. + * + * @param namespace Namespace to check. + * @param other Namespace to check against. + * @return String reason for collision, or + * null if no collision. + */ + public static String checkNamespaceCollision(Namespace namespace, + Namespace other) { + String p1,p2,u1,u2,reason; + + reason = null; + p1 = namespace.getPrefix(); + u1 = namespace.getURI(); + p2 = other.getPrefix(); + u2 = other.getURI(); + if (p1.equals(p2) && !u1.equals(u2)) { + reason = "The namespace prefix \"" + p1 + "\" collides"; + } + return reason; + } + + /** + * Check if {@link Attribute}'s namespace collides with a + * {@link Element}'s namespace. + * + * @param attribute Attribute to check. + * @param element Element to check against. + * @return String reason for collision, or + * null if no collision. + */ + public static String checkNamespaceCollision(Attribute attribute, + Element element) { + Namespace namespace = attribute.getNamespace(); + String prefix = namespace.getPrefix(); + if ("".equals(prefix)) { + return null; + } + + return checkNamespaceCollision(namespace, element); + } + + /** + * Check if a {@link Namespace} collides with a + * {@link Element}'s namespace. + * + * @param namespace Namespace to check. + * @param element Element to check against. + * @return String reason for collision, or + * null if no collision. + */ + public static String checkNamespaceCollision(Namespace namespace, + Element element) { + String reason = checkNamespaceCollision(namespace, + element.getNamespace()); + if (reason != null) { + return reason + " with the element namespace prefix"; + } + + reason = checkNamespaceCollision(namespace, + element.getAdditionalNamespaces()); + if (reason != null) { + return reason; + } + + reason = checkNamespaceCollision(namespace, element.getAttributes()); + if (reason != null) { + return reason; + } + + return null; + } + + /** + * Check if a {@link Namespace} collides with a + * {@link Attribute}'s namespace. + * + * @param namespace Namespace to check. + * @param attribute Attribute to check against. + * @return String reason for collision, or + * null if no collision. + */ + public static String checkNamespaceCollision(Namespace namespace, + Attribute attribute) { + String reason = null; + if (!attribute.getNamespace().equals(Namespace.NO_NAMESPACE)) { + reason = checkNamespaceCollision(namespace, + attribute.getNamespace()); + if (reason != null) { + reason += " with an attribute namespace prefix on the element"; + } + } + return reason; + } + + /** + * Check if a {@link Namespace} collides with any namespace + * from a list of objects. + * + * @param namespace Namespace to check. + * @param list List to check against. + * @return String reason for collision, or + * null if no collision. + */ + public static String checkNamespaceCollision(Namespace namespace, + List list) { + if (list == null) { + return null; + } + + String reason = null; + Iterator i = list.iterator(); + while ((reason == null) && i.hasNext()) { + Object obj = i.next(); + if (obj instanceof Attribute) { + reason = checkNamespaceCollision(namespace, (Attribute) obj); + } + else if (obj instanceof Element) { + reason = checkNamespaceCollision(namespace, (Element) obj); + } + else if (obj instanceof Namespace) { + reason = checkNamespaceCollision(namespace, (Namespace) obj); + if (reason != null) { + reason += " with an additional namespace declared" + + " by the element"; + } + } + } + return reason; + } + + /** + * This will check the supplied data to see if it is legal for use as + * a JDOM {@link ProcessingInstruction} target. + * + * @param target String target to check. + * @return String reason target is illegal, or + * null if target is OK. + */ + public static String checkProcessingInstructionTarget(String target) { + // Check basic XML name rules first + String reason; + if ((reason = checkXMLName(target)) != null) { + return reason; + } + + // No colons allowed, per Namespace Specification Section 6 + if (target.indexOf(":") != -1) { + return "Processing instruction targets cannot contain colons"; + } + + // Cannot begin with 'xml' in any case + if (target.equalsIgnoreCase("xml")) { + return "Processing instructions cannot have a target of " + + "\"xml\" in any combination of case. (Note that the " + + "\"\" declaration at the beginning of a " + + "document is not a processing instruction and should not " + + "be added as one; it is written automatically during " + + "output, e.g. by XMLOutputter.)"; + } + + // If we got here, everything is OK + return null; + } + + /** + * This will check the supplied data to see if it is legal for use as + * {@link ProcessingInstruction} data. Besides checking that + * all the characters are allowed in XML, this also checks + * that the data does not contain the PI end-string "?>". + * + * @param data String data to check. + * @return String reason data is illegal, or + * null if data is OK. + */ + public static String checkProcessingInstructionData(String data) { + // Check basic XML name rules first + String reason = checkCharacterData(data); + + if (reason == null) { + if (data.indexOf("?>") >= 0) { + return "Processing instructions cannot contain " + + "the string \"?>\""; + } + } + + return reason; + } + + /** + * This will check the supplied data to see if it is legal for use as + * JDOM {@link Comment} data. + * + * @param data String data to check. + * @return String reason data is illegal, or + * null if data is OK. + */ + public static String checkCommentData(String data) { + String reason = null; + if ((reason = checkCharacterData(data)) != null) { + return reason; + } + + if (data.indexOf("--") != -1) { + return "Comments cannot contain double hyphens (--)"; + } + if (data.endsWith("-")) { + return "Comment data cannot end with a hyphen."; + } + + // If we got here, everything is OK + return null; + } + /** + * This is a utility function to decode a non-BMP + * UTF-16 surrogate pair. + * @param high high 16 bits + * @param low low 16 bits + * @return decoded character + */ + public static int decodeSurrogatePair(char high, char low) { + return 0x10000 + (high - 0xD800) * 0x400 + (low - 0xDC00); + } + + // [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | + // [-'()+,./:=?;*#@$_%] + public static boolean isXMLPublicIDCharacter(char c) { + + if (c >= 'a' && c <= 'z') return true; + if (c >= '?' && c <= 'Z') return true; + if (c >= '\'' && c <= ';') return true; + + if (c == ' ') return true; + if (c == '!') return true; + if (c == '=') return true; + if (c == '#') return true; + if (c == '$') return true; + if (c == '_') return true; + if (c == '%') return true; + if (c == '\n') return true; + if (c == '\r') return true; + if (c == '\t') return true; + + return false; + } + + /** + * This will ensure that the data for a public identifier + * is legal. + * + * @param publicID String public ID to check. + * @return String reason public ID is illegal, or + * null if public ID is OK. + */ + public static String checkPublicID(String publicID) { + String reason = null; + + if (publicID == null) return null; + // This indicates there is no public ID + + for (int i = 0; i < publicID.length(); i++) { + char c = publicID.charAt(i); + if (!isXMLPublicIDCharacter(c)) { + reason = c + " is not a legal character in public IDs"; + break; + } + } + + return reason; + } + + + /** + * This will ensure that the data for a system literal + * is legal. + * + * @param systemLiteral String system literal to check. + * @return String reason system literal is illegal, or + * null if system literal is OK. + */ + public static String checkSystemLiteral(String systemLiteral) { + String reason = null; + + if (systemLiteral == null) return null; + // This indicates there is no system ID + + if (systemLiteral.indexOf('\'') != -1 + && systemLiteral.indexOf('"') != -1) { + reason = + "System literals cannot simultaneously contain both single and double quotes."; + } + else { + reason = checkCharacterData(systemLiteral); + } + + return reason; + } + + /** + * This is a utility function for sharing the base process of checking + * any XML name. + * + * @param name String to check for XML name compliance. + * @return String reason the name is illegal, or + * null if OK. + */ + public static String checkXMLName(String name) { + // Cannot be empty or null + if ((name == null) || (name.length() == 0) + || (name.trim().equals(""))) { + return "XML names cannot be null or empty"; + } + + + // Cannot start with a number + char first = name.charAt(0); + if (!isXMLNameStartCharacter(first)) { + return "XML names cannot begin with the character \"" + + first + "\""; + } + // Ensure legal content for non-first chars + for (int i=1, len = name.length(); i + * Checks a string to see if it is a legal RFC 2396 URI. + * Both absolute and relative URIs are supported. + *

+ * + * @param uri String to check. + * @return String reason the URI is illegal, or + * null if OK. + */ + public static String checkURI(String uri) { + // URIs can be null or empty + if ((uri == null) || (uri.equals(""))) { + return null; + } + + for (int i = 0; i < uri.length(); i++) { + char test = uri.charAt(i); + if (!isURICharacter(test)) { + String msgNumber = "0x" + Integer.toHexString(test); + if (test <= 0x09) msgNumber = "0x0" + Integer.toHexString(test); + return "URIs cannot contain " + msgNumber; + } // end if + if (test == '%') { // must be followed by two hexadecimal digits + try { + char firstDigit = uri.charAt(i+1); + char secondDigit = uri.charAt(i+2); + if (!isHexDigit(firstDigit) || + !isHexDigit(secondDigit)) { + return "Percent signs in URIs must be followed by " + + "exactly two hexadecimal digits."; + } + + } + catch (StringIndexOutOfBoundsException e) { + return "Percent signs in URIs must be followed by " + + "exactly two hexadecimal digits."; + } + } + } // end for + + // If we got here, everything is OK + return null; + } + + /** + *

+ * This is a utility function for determining whether a specified + * Unicode character is a hexadecimal digit as defined in RFC 2396; + * that is, one of the ASCII characters 0-9, a-f, or A-F. + *

+ * + * @param c to check for hex digit. + * @return true if it's allowed, false otherwise. + */ + public static boolean isHexDigit(char c) { + + // I suspect most characters passed to this method will be + // correct hexadecimal digits, so I test for the true cases + // first. If this proves to be a performance bottleneck + // a switch statement or lookup table + // might optimize this. + if (c >= '0' && c <= '9') return true; + if (c >= 'A' && c <= 'F') return true; + if (c >= 'a' && c <= 'f') return true; + + return false; + } + + /** + * This is a function for determining whether the + * specified character is the high 16 bits in a + * UTF-16 surrogate pair. + * @param ch character to check + * @return true if the character is a high surrogate, false otherwise + */ + public static boolean isHighSurrogate(char ch) { + return (ch >= 0xD800 && ch <= 0xDBFF); + } + + /** + * This is a function for determining whether the + * specified character is the low 16 bits in a + * UTF-16 surrogate pair. + * @param ch character to check + * @return true if the character is a low surrogate, false otherwise. + */ + public static boolean isLowSurrogate(char ch) { + return (ch >= 0xDC00 && ch <= 0xDFFF); + } + + /** + *

+ * This is a utility function for determining whether + * a specified Unicode character is legal in URI references + * as determined by RFC 2396. + *

+ * + * @param c char to check for URI reference compliance. + * @return true if it's allowed, false otherwise. + */ + public static boolean isURICharacter(char c) { + if (c >= 'a' && c <= 'z') return true; + if (c >= 'A' && c <= 'Z') return true; + if (c >= '0' && c <= '9') return true; + if (c == '/') return true; + if (c == '-') return true; + if (c == '.') return true; + if (c == '?') return true; + if (c == ':') return true; + if (c == '@') return true; + if (c == '&') return true; + if (c == '=') return true; + if (c == '+') return true; + if (c == '$') return true; + if (c == ',') return true; + if (c == '%') return true; + + if (c == '_') return true; + if (c == '!') return true; + if (c == '~') return true; + if (c == '*') return true; + if (c == '\'') return true; + if (c == '(') return true; + if (c == ')') return true; + return false; + } + + /** + * This is a utility function for determining whether a specified + * character is a character according to production 2 of the + * XML 1.0 specification. + * + * @param c char to check for XML compliance + * @return boolean true if it's a character, + * false otherwise + */ + public static boolean isXMLCharacter(int c) { + + if (c == '\n') return true; + if (c == '\r') return true; + if (c == '\t') return true; + + if (c < 0x20) return false; if (c <= 0xD7FF) return true; + if (c < 0xE000) return false; if (c <= 0xFFFD) return true; + if (c < 0x10000) return false; if (c <= 0x10FFFF) return true; + + return false; + } + + + /** + * This is a utility function for determining whether a specified + * character is a name character according to production 4 of the + * XML 1.0 specification. + * + * @param c char to check for XML name compliance. + * @return boolean true if it's a name character, + * false otherwise. + */ + public static boolean isXMLNameCharacter(char c) { + + return (isXMLLetter(c) || isXMLDigit(c) || c == '.' || c == '-' + || c == '_' || c == ':' || isXMLCombiningChar(c) + || isXMLExtender(c)); + } + + /** + * This is a utility function for determining whether a specified + * character is a legal name start character according to production 5 + * of the XML 1.0 specification. This production does allow names + * to begin with colons which the Namespaces in XML Recommendation + * disallows. + * + * @param c char to check for XML name start compliance. + * @return boolean true if it's a name start character, + * false otherwise. + */ + public static boolean isXMLNameStartCharacter(char c) { + + return (isXMLLetter(c) || c == '_' || c ==':'); + + } + + /** + * This is a utility function for determining whether a specified + * character is a letter or digit according to productions 84 and 88 + * of the XML 1.0 specification. + * + * @param c char to check. + * @return boolean true if it's letter or digit, + * false otherwise. + */ + public static boolean isXMLLetterOrDigit(char c) { + + return (isXMLLetter(c) || isXMLDigit(c)); + + } + + /** + * This is a utility function for determining whether a specified character + * is a letter according to production 84 of the XML 1.0 specification. + * + * @param c char to check for XML name compliance. + * @return String true if it's a letter, false otherwise. + */ + public static boolean isXMLLetter(char c) { + // Note that order is very important here. The search proceeds + // from lowest to highest values, so that no searching occurs + // above the character's value. BTW, the first line is equivalent to: + // if (c >= 0x0041 && c <= 0x005A) return true; + + if (c < 0x0041) return false; if (c <= 0x005a) return true; + if (c < 0x0061) return false; if (c <= 0x007A) return true; + if (c < 0x00C0) return false; if (c <= 0x00D6) return true; + if (c < 0x00D8) return false; if (c <= 0x00F6) return true; + if (c < 0x00F8) return false; if (c <= 0x00FF) return true; + if (c < 0x0100) return false; if (c <= 0x0131) return true; + if (c < 0x0134) return false; if (c <= 0x013E) return true; + if (c < 0x0141) return false; if (c <= 0x0148) return true; + if (c < 0x014A) return false; if (c <= 0x017E) return true; + if (c < 0x0180) return false; if (c <= 0x01C3) return true; + if (c < 0x01CD) return false; if (c <= 0x01F0) return true; + if (c < 0x01F4) return false; if (c <= 0x01F5) return true; + if (c < 0x01FA) return false; if (c <= 0x0217) return true; + if (c < 0x0250) return false; if (c <= 0x02A8) return true; + if (c < 0x02BB) return false; if (c <= 0x02C1) return true; + if (c == 0x0386) return true; + if (c < 0x0388) return false; if (c <= 0x038A) return true; + if (c == 0x038C) return true; + if (c < 0x038E) return false; if (c <= 0x03A1) return true; + if (c < 0x03A3) return false; if (c <= 0x03CE) return true; + if (c < 0x03D0) return false; if (c <= 0x03D6) return true; + if (c == 0x03DA) return true; + if (c == 0x03DC) return true; + if (c == 0x03DE) return true; + if (c == 0x03E0) return true; + if (c < 0x03E2) return false; if (c <= 0x03F3) return true; + if (c < 0x0401) return false; if (c <= 0x040C) return true; + if (c < 0x040E) return false; if (c <= 0x044F) return true; + if (c < 0x0451) return false; if (c <= 0x045C) return true; + if (c < 0x045E) return false; if (c <= 0x0481) return true; + if (c < 0x0490) return false; if (c <= 0x04C4) return true; + if (c < 0x04C7) return false; if (c <= 0x04C8) return true; + if (c < 0x04CB) return false; if (c <= 0x04CC) return true; + if (c < 0x04D0) return false; if (c <= 0x04EB) return true; + if (c < 0x04EE) return false; if (c <= 0x04F5) return true; + if (c < 0x04F8) return false; if (c <= 0x04F9) return true; + if (c < 0x0531) return false; if (c <= 0x0556) return true; + if (c == 0x0559) return true; + if (c < 0x0561) return false; if (c <= 0x0586) return true; + if (c < 0x05D0) return false; if (c <= 0x05EA) return true; + if (c < 0x05F0) return false; if (c <= 0x05F2) return true; + if (c < 0x0621) return false; if (c <= 0x063A) return true; + if (c < 0x0641) return false; if (c <= 0x064A) return true; + if (c < 0x0671) return false; if (c <= 0x06B7) return true; + if (c < 0x06BA) return false; if (c <= 0x06BE) return true; + if (c < 0x06C0) return false; if (c <= 0x06CE) return true; + if (c < 0x06D0) return false; if (c <= 0x06D3) return true; + if (c == 0x06D5) return true; + if (c < 0x06E5) return false; if (c <= 0x06E6) return true; + if (c < 0x0905) return false; if (c <= 0x0939) return true; + if (c == 0x093D) return true; + if (c < 0x0958) return false; if (c <= 0x0961) return true; + if (c < 0x0985) return false; if (c <= 0x098C) return true; + if (c < 0x098F) return false; if (c <= 0x0990) return true; + if (c < 0x0993) return false; if (c <= 0x09A8) return true; + if (c < 0x09AA) return false; if (c <= 0x09B0) return true; + if (c == 0x09B2) return true; + if (c < 0x09B6) return false; if (c <= 0x09B9) return true; + if (c < 0x09DC) return false; if (c <= 0x09DD) return true; + if (c < 0x09DF) return false; if (c <= 0x09E1) return true; + if (c < 0x09F0) return false; if (c <= 0x09F1) return true; + if (c < 0x0A05) return false; if (c <= 0x0A0A) return true; + if (c < 0x0A0F) return false; if (c <= 0x0A10) return true; + if (c < 0x0A13) return false; if (c <= 0x0A28) return true; + if (c < 0x0A2A) return false; if (c <= 0x0A30) return true; + if (c < 0x0A32) return false; if (c <= 0x0A33) return true; + if (c < 0x0A35) return false; if (c <= 0x0A36) return true; + if (c < 0x0A38) return false; if (c <= 0x0A39) return true; + if (c < 0x0A59) return false; if (c <= 0x0A5C) return true; + if (c == 0x0A5E) return true; + if (c < 0x0A72) return false; if (c <= 0x0A74) return true; + if (c < 0x0A85) return false; if (c <= 0x0A8B) return true; + if (c == 0x0A8D) return true; + if (c < 0x0A8F) return false; if (c <= 0x0A91) return true; + if (c < 0x0A93) return false; if (c <= 0x0AA8) return true; + if (c < 0x0AAA) return false; if (c <= 0x0AB0) return true; + if (c < 0x0AB2) return false; if (c <= 0x0AB3) return true; + if (c < 0x0AB5) return false; if (c <= 0x0AB9) return true; + if (c == 0x0ABD) return true; + if (c == 0x0AE0) return true; + if (c < 0x0B05) return false; if (c <= 0x0B0C) return true; + if (c < 0x0B0F) return false; if (c <= 0x0B10) return true; + if (c < 0x0B13) return false; if (c <= 0x0B28) return true; + if (c < 0x0B2A) return false; if (c <= 0x0B30) return true; + if (c < 0x0B32) return false; if (c <= 0x0B33) return true; + if (c < 0x0B36) return false; if (c <= 0x0B39) return true; + if (c == 0x0B3D) return true; + if (c < 0x0B5C) return false; if (c <= 0x0B5D) return true; + if (c < 0x0B5F) return false; if (c <= 0x0B61) return true; + if (c < 0x0B85) return false; if (c <= 0x0B8A) return true; + if (c < 0x0B8E) return false; if (c <= 0x0B90) return true; + if (c < 0x0B92) return false; if (c <= 0x0B95) return true; + if (c < 0x0B99) return false; if (c <= 0x0B9A) return true; + if (c == 0x0B9C) return true; + if (c < 0x0B9E) return false; if (c <= 0x0B9F) return true; + if (c < 0x0BA3) return false; if (c <= 0x0BA4) return true; + if (c < 0x0BA8) return false; if (c <= 0x0BAA) return true; + if (c < 0x0BAE) return false; if (c <= 0x0BB5) return true; + if (c < 0x0BB7) return false; if (c <= 0x0BB9) return true; + if (c < 0x0C05) return false; if (c <= 0x0C0C) return true; + if (c < 0x0C0E) return false; if (c <= 0x0C10) return true; + if (c < 0x0C12) return false; if (c <= 0x0C28) return true; + if (c < 0x0C2A) return false; if (c <= 0x0C33) return true; + if (c < 0x0C35) return false; if (c <= 0x0C39) return true; + if (c < 0x0C60) return false; if (c <= 0x0C61) return true; + if (c < 0x0C85) return false; if (c <= 0x0C8C) return true; + if (c < 0x0C8E) return false; if (c <= 0x0C90) return true; + if (c < 0x0C92) return false; if (c <= 0x0CA8) return true; + if (c < 0x0CAA) return false; if (c <= 0x0CB3) return true; + if (c < 0x0CB5) return false; if (c <= 0x0CB9) return true; + if (c == 0x0CDE) return true; + if (c < 0x0CE0) return false; if (c <= 0x0CE1) return true; + if (c < 0x0D05) return false; if (c <= 0x0D0C) return true; + if (c < 0x0D0E) return false; if (c <= 0x0D10) return true; + if (c < 0x0D12) return false; if (c <= 0x0D28) return true; + if (c < 0x0D2A) return false; if (c <= 0x0D39) return true; + if (c < 0x0D60) return false; if (c <= 0x0D61) return true; + if (c < 0x0E01) return false; if (c <= 0x0E2E) return true; + if (c == 0x0E30) return true; + if (c < 0x0E32) return false; if (c <= 0x0E33) return true; + if (c < 0x0E40) return false; if (c <= 0x0E45) return true; + if (c < 0x0E81) return false; if (c <= 0x0E82) return true; + if (c == 0x0E84) return true; + if (c < 0x0E87) return false; if (c <= 0x0E88) return true; + if (c == 0x0E8A) return true; + if (c == 0x0E8D) return true; + if (c < 0x0E94) return false; if (c <= 0x0E97) return true; + if (c < 0x0E99) return false; if (c <= 0x0E9F) return true; + if (c < 0x0EA1) return false; if (c <= 0x0EA3) return true; + if (c == 0x0EA5) return true; + if (c == 0x0EA7) return true; + if (c < 0x0EAA) return false; if (c <= 0x0EAB) return true; + if (c < 0x0EAD) return false; if (c <= 0x0EAE) return true; + if (c == 0x0EB0) return true; + if (c < 0x0EB2) return false; if (c <= 0x0EB3) return true; + if (c == 0x0EBD) return true; + if (c < 0x0EC0) return false; if (c <= 0x0EC4) return true; + if (c < 0x0F40) return false; if (c <= 0x0F47) return true; + if (c < 0x0F49) return false; if (c <= 0x0F69) return true; + if (c < 0x10A0) return false; if (c <= 0x10C5) return true; + if (c < 0x10D0) return false; if (c <= 0x10F6) return true; + if (c == 0x1100) return true; + if (c < 0x1102) return false; if (c <= 0x1103) return true; + if (c < 0x1105) return false; if (c <= 0x1107) return true; + if (c == 0x1109) return true; + if (c < 0x110B) return false; if (c <= 0x110C) return true; + if (c < 0x110E) return false; if (c <= 0x1112) return true; + if (c == 0x113C) return true; + if (c == 0x113E) return true; + if (c == 0x1140) return true; + if (c == 0x114C) return true; + if (c == 0x114E) return true; + if (c == 0x1150) return true; + if (c < 0x1154) return false; if (c <= 0x1155) return true; + if (c == 0x1159) return true; + if (c < 0x115F) return false; if (c <= 0x1161) return true; + if (c == 0x1163) return true; + if (c == 0x1165) return true; + if (c == 0x1167) return true; + if (c == 0x1169) return true; + if (c < 0x116D) return false; if (c <= 0x116E) return true; + if (c < 0x1172) return false; if (c <= 0x1173) return true; + if (c == 0x1175) return true; + if (c == 0x119E) return true; + if (c == 0x11A8) return true; + if (c == 0x11AB) return true; + if (c < 0x11AE) return false; if (c <= 0x11AF) return true; + if (c < 0x11B7) return false; if (c <= 0x11B8) return true; + if (c == 0x11BA) return true; + if (c < 0x11BC) return false; if (c <= 0x11C2) return true; + if (c == 0x11EB) return true; + if (c == 0x11F0) return true; + if (c == 0x11F9) return true; + if (c < 0x1E00) return false; if (c <= 0x1E9B) return true; + if (c < 0x1EA0) return false; if (c <= 0x1EF9) return true; + if (c < 0x1F00) return false; if (c <= 0x1F15) return true; + if (c < 0x1F18) return false; if (c <= 0x1F1D) return true; + if (c < 0x1F20) return false; if (c <= 0x1F45) return true; + if (c < 0x1F48) return false; if (c <= 0x1F4D) return true; + if (c < 0x1F50) return false; if (c <= 0x1F57) return true; + if (c == 0x1F59) return true; + if (c == 0x1F5B) return true; + if (c == 0x1F5D) return true; + if (c < 0x1F5F) return false; if (c <= 0x1F7D) return true; + if (c < 0x1F80) return false; if (c <= 0x1FB4) return true; + if (c < 0x1FB6) return false; if (c <= 0x1FBC) return true; + if (c == 0x1FBE) return true; + if (c < 0x1FC2) return false; if (c <= 0x1FC4) return true; + if (c < 0x1FC6) return false; if (c <= 0x1FCC) return true; + if (c < 0x1FD0) return false; if (c <= 0x1FD3) return true; + if (c < 0x1FD6) return false; if (c <= 0x1FDB) return true; + if (c < 0x1FE0) return false; if (c <= 0x1FEC) return true; + if (c < 0x1FF2) return false; if (c <= 0x1FF4) return true; + if (c < 0x1FF6) return false; if (c <= 0x1FFC) return true; + if (c == 0x2126) return true; + if (c < 0x212A) return false; if (c <= 0x212B) return true; + if (c == 0x212E) return true; + if (c < 0x2180) return false; if (c <= 0x2182) return true; + if (c == 0x3007) return true; // ideographic + if (c < 0x3021) return false; if (c <= 0x3029) return true; // ideo + if (c < 0x3041) return false; if (c <= 0x3094) return true; + if (c < 0x30A1) return false; if (c <= 0x30FA) return true; + if (c < 0x3105) return false; if (c <= 0x312C) return true; + if (c < 0x4E00) return false; if (c <= 0x9FA5) return true; // ideo + if (c < 0xAC00) return false; if (c <= 0xD7A3) return true; + + return false; + + } + + /** + * This is a utility function for determining whether a specified character + * is a combining character according to production 87 + * of the XML 1.0 specification. + * + * @param c char to check. + * @return boolean true if it's a combining character, + * false otherwise. + */ + public static boolean isXMLCombiningChar(char c) { + // CombiningChar + if (c < 0x0300) return false; if (c <= 0x0345) return true; + if (c < 0x0360) return false; if (c <= 0x0361) return true; + if (c < 0x0483) return false; if (c <= 0x0486) return true; + if (c < 0x0591) return false; if (c <= 0x05A1) return true; + + if (c < 0x05A3) return false; if (c <= 0x05B9) return true; + if (c < 0x05BB) return false; if (c <= 0x05BD) return true; + if (c == 0x05BF) return true; + if (c < 0x05C1) return false; if (c <= 0x05C2) return true; + + if (c == 0x05C4) return true; + if (c < 0x064B) return false; if (c <= 0x0652) return true; + if (c == 0x0670) return true; + if (c < 0x06D6) return false; if (c <= 0x06DC) return true; + + if (c < 0x06DD) return false; if (c <= 0x06DF) return true; + if (c < 0x06E0) return false; if (c <= 0x06E4) return true; + if (c < 0x06E7) return false; if (c <= 0x06E8) return true; + + if (c < 0x06EA) return false; if (c <= 0x06ED) return true; + if (c < 0x0901) return false; if (c <= 0x0903) return true; + if (c == 0x093C) return true; + if (c < 0x093E) return false; if (c <= 0x094C) return true; + + if (c == 0x094D) return true; + if (c < 0x0951) return false; if (c <= 0x0954) return true; + if (c < 0x0962) return false; if (c <= 0x0963) return true; + if (c < 0x0981) return false; if (c <= 0x0983) return true; + + if (c == 0x09BC) return true; + if (c == 0x09BE) return true; + if (c == 0x09BF) return true; + if (c < 0x09C0) return false; if (c <= 0x09C4) return true; + if (c < 0x09C7) return false; if (c <= 0x09C8) return true; + + if (c < 0x09CB) return false; if (c <= 0x09CD) return true; + if (c == 0x09D7) return true; + if (c < 0x09E2) return false; if (c <= 0x09E3) return true; + if (c == 0x0A02) return true; + if (c == 0x0A3C) return true; + + if (c == 0x0A3E) return true; + if (c == 0x0A3F) return true; + if (c < 0x0A40) return false; if (c <= 0x0A42) return true; + if (c < 0x0A47) return false; if (c <= 0x0A48) return true; + + if (c < 0x0A4B) return false; if (c <= 0x0A4D) return true; + if (c < 0x0A70) return false; if (c <= 0x0A71) return true; + if (c < 0x0A81) return false; if (c <= 0x0A83) return true; + if (c == 0x0ABC) return true; + + if (c < 0x0ABE) return false; if (c <= 0x0AC5) return true; + if (c < 0x0AC7) return false; if (c <= 0x0AC9) return true; + if (c < 0x0ACB) return false; if (c <= 0x0ACD) return true; + + if (c < 0x0B01) return false; if (c <= 0x0B03) return true; + if (c == 0x0B3C) return true; + if (c < 0x0B3E) return false; if (c <= 0x0B43) return true; + if (c < 0x0B47) return false; if (c <= 0x0B48) return true; + + if (c < 0x0B4B) return false; if (c <= 0x0B4D) return true; + if (c < 0x0B56) return false; if (c <= 0x0B57) return true; + if (c < 0x0B82) return false; if (c <= 0x0B83) return true; + + if (c < 0x0BBE) return false; if (c <= 0x0BC2) return true; + if (c < 0x0BC6) return false; if (c <= 0x0BC8) return true; + if (c < 0x0BCA) return false; if (c <= 0x0BCD) return true; + if (c == 0x0BD7) return true; + + if (c < 0x0C01) return false; if (c <= 0x0C03) return true; + if (c < 0x0C3E) return false; if (c <= 0x0C44) return true; + if (c < 0x0C46) return false; if (c <= 0x0C48) return true; + + if (c < 0x0C4A) return false; if (c <= 0x0C4D) return true; + if (c < 0x0C55) return false; if (c <= 0x0C56) return true; + if (c < 0x0C82) return false; if (c <= 0x0C83) return true; + + if (c < 0x0CBE) return false; if (c <= 0x0CC4) return true; + if (c < 0x0CC6) return false; if (c <= 0x0CC8) return true; + if (c < 0x0CCA) return false; if (c <= 0x0CCD) return true; + + if (c < 0x0CD5) return false; if (c <= 0x0CD6) return true; + if (c < 0x0D02) return false; if (c <= 0x0D03) return true; + if (c < 0x0D3E) return false; if (c <= 0x0D43) return true; + + if (c < 0x0D46) return false; if (c <= 0x0D48) return true; + if (c < 0x0D4A) return false; if (c <= 0x0D4D) return true; + if (c == 0x0D57) return true; + if (c == 0x0E31) return true; + + if (c < 0x0E34) return false; if (c <= 0x0E3A) return true; + if (c < 0x0E47) return false; if (c <= 0x0E4E) return true; + if (c == 0x0EB1) return true; + if (c < 0x0EB4) return false; if (c <= 0x0EB9) return true; + + if (c < 0x0EBB) return false; if (c <= 0x0EBC) return true; + if (c < 0x0EC8) return false; if (c <= 0x0ECD) return true; + if (c < 0x0F18) return false; if (c <= 0x0F19) return true; + if (c == 0x0F35) return true; + + if (c == 0x0F37) return true; + if (c == 0x0F39) return true; + if (c == 0x0F3E) return true; + if (c == 0x0F3F) return true; + if (c < 0x0F71) return false; if (c <= 0x0F84) return true; + + if (c < 0x0F86) return false; if (c <= 0x0F8B) return true; + if (c < 0x0F90) return false; if (c <= 0x0F95) return true; + if (c == 0x0F97) return true; + if (c < 0x0F99) return false; if (c <= 0x0FAD) return true; + + if (c < 0x0FB1) return false; if (c <= 0x0FB7) return true; + if (c == 0x0FB9) return true; + if (c < 0x20D0) return false; if (c <= 0x20DC) return true; + if (c == 0x20E1) return true; + + if (c < 0x302A) return false; if (c <= 0x302F) return true; + if (c == 0x3099) return true; + if (c == 0x309A) return true; + + return false; + + } + + /** + * This is a utility function for determining whether a specified + * character is an extender according to production 88 of the XML 1.0 + * specification. + * + * @param c char to check. + * @return String true if it's an extender, false otherwise. + */ + public static boolean isXMLExtender(char c) { + + if (c < 0x00B6) return false; // quick short circuit + + // Extenders + if (c == 0x00B7) return true; + if (c == 0x02D0) return true; + if (c == 0x02D1) return true; + if (c == 0x0387) return true; + if (c == 0x0640) return true; + if (c == 0x0E46) return true; + if (c == 0x0EC6) return true; + if (c == 0x3005) return true; + + if (c < 0x3031) return false; if (c <= 0x3035) return true; + if (c < 0x309D) return false; if (c <= 0x309E) return true; + if (c < 0x30FC) return false; if (c <= 0x30FE) return true; + + return false; + + } + + /** + * This is a utility function for determining whether a specified + * Unicode character + * is a digit according to production 88 of the XML 1.0 specification. + * + * @param c char to check for XML digit compliance + * @return boolean true if it's a digit, false otherwise + */ + public static boolean isXMLDigit(char c) { + + if (c < 0x0030) return false; if (c <= 0x0039) return true; + if (c < 0x0660) return false; if (c <= 0x0669) return true; + if (c < 0x06F0) return false; if (c <= 0x06F9) return true; + if (c < 0x0966) return false; if (c <= 0x096F) return true; + + if (c < 0x09E6) return false; if (c <= 0x09EF) return true; + if (c < 0x0A66) return false; if (c <= 0x0A6F) return true; + if (c < 0x0AE6) return false; if (c <= 0x0AEF) return true; + + if (c < 0x0B66) return false; if (c <= 0x0B6F) return true; + if (c < 0x0BE7) return false; if (c <= 0x0BEF) return true; + if (c < 0x0C66) return false; if (c <= 0x0C6F) return true; + + if (c < 0x0CE6) return false; if (c <= 0x0CEF) return true; + if (c < 0x0D66) return false; if (c <= 0x0D6F) return true; + if (c < 0x0E50) return false; if (c <= 0x0E59) return true; + + if (c < 0x0ED0) return false; if (c <= 0x0ED9) return true; + if (c < 0x0F20) return false; if (c <= 0x0F29) return true; + + return false; + } + + /** + * This is a utility function for determining whether a specified + * Unicode character is a whitespace character according to production 3 + * of the XML 1.0 specification. + * + * @param c char to check for XML whitespace compliance + * @return boolean true if it's a whitespace, false otherwise + */ + public static boolean isXMLWhitespace(char c) { + if (c==' ' || c=='\n' || c=='\t' || c=='\r' ){ + return true; + } + return false; + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/AbstractDOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/AbstractDOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/AbstractDOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,172 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.w3c.dom.*; +import org.w3c.dom.Document; + +/** + * A DOMAdapter utility abstract base class. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public abstract class AbstractDOMAdapter implements DOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param filename file to parse. + * @param validate boolean to indicate if validation should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(File filename, boolean validate) + throws IOException, JDOMException { + + return getDocument(new FileInputStream(filename), validate); + } + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public abstract Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException; + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public abstract Document createDocument() throws JDOMException; + + /** + * This creates an empty Document object based + * on a specific parser implementation with the given DOCTYPE. + * If the doctype parameter is null, the behavior is the same as + * calling createDocument(). + * + * @param doctype Initial DocType of the document. + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument(DocType doctype) throws JDOMException { + if (doctype == null) { + return createDocument(); + } + + DOMImplementation domImpl = createDocument().getImplementation(); + DocumentType domDocType = domImpl.createDocumentType( + doctype.getElementName(), + doctype.getPublicID(), + doctype.getSystemID()); + + // Set the internal subset if possible + setInternalSubset(domDocType, doctype.getInternalSubset()); + + return domImpl.createDocument("http://temporary", + doctype.getElementName(), + domDocType); + } + + /** + * This attempts to change the DocumentType to have the given internal DTD + * subset value. This is not a standard ability in DOM, so it's only + * available with some parsers. Subclasses can alter the mechanism by + * which the attempt is made to set the value. + * + * @param dt DocumentType to be altered + * @param s String to use as the internal DTD subset + */ + protected void setInternalSubset(DocumentType dt, String s) { + if (dt == null || s == null) return; + + // Default behavior is to attempt a setInternalSubset() call using + // reflection. This method is not part of the DOM spec, but it's + // available on Xerces 1.4.4+. It's not currently in Crimson. + try { + Class dtclass = dt.getClass(); + Method setInternalSubset = dtclass.getMethod( + "setInternalSubset", new Class[] {java.lang.String.class}); + setInternalSubset.invoke(dt, new Object[] {s}); + } + catch (Exception e) { + // ignore + } + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/CrimsonDOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/CrimsonDOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/CrimsonDOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,146 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.w3c.dom.Document; +import org.xml.sax.*; + +/** + * An adapter for the Apache Crimson DOM parser. + * + * @version $Revision$, $Date$ + * @author Jason Hunter + */ +public class CrimsonDOMAdapter extends AbstractDOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException { + + try { + Class[] parameterTypes = new Class[2]; + parameterTypes[0] = Class.forName("java.io.InputStream"); + parameterTypes[1] = boolean.class; + + Object[] args = new Object[2]; + args[0] = in; + args[1] = new Boolean(false); + + // Load the parser class and invoke the parse method + Class parserClass = Class.forName("org.apache.crimson.tree.XmlDocument"); + Method createXmlDocument = + parserClass.getMethod("createXmlDocument", parameterTypes); + Document doc = + (Document)createXmlDocument.invoke(null, args); + + return doc; + + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof org.xml.sax.SAXParseException) { + SAXParseException parseException = (SAXParseException)targetException; + throw new JDOMException("Error on line " + parseException.getLineNumber() + + " of XML document: " + parseException.getMessage(), parseException); + } else if (targetException instanceof IOException) { + IOException ioException = (IOException) targetException; + throw ioException; + } else { + throw new JDOMException(targetException.getMessage(), targetException); + } + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage(), e); + } + } + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument() throws JDOMException { + try { + return + (Document)Class.forName( + "org.apache.crimson.tree.XmlDocument") + .newInstance(); + + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage() + " when creating document", e); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/DOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/DOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/DOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,123 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; + +import org.jdom.*; +import org.w3c.dom.Document; + +/** + * Defines a standard set of adapter methods for interfacing with a DOM parser + * and obtaining a DOM {@link org.w3c.dom.Document org.w3c.dom.Document} object. + * Implementing classes map these calls to DOM parser-specific calls, allowing + * any third-party parser to be used with JDOM. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public interface DOMAdapter { + + /** + * This creates a new Document from a + * given filename by letting a DOM parser handle parsing from the file. + * + * @param filename file to parse. + * @param validate boolean to indicate if validation + * should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(File filename, boolean validate) + throws IOException, JDOMException; + + /** + * This creates a new Document from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation + * should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException; + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument() throws JDOMException; + + /** + * This creates an empty Document object based + * on a specific parser implementation with the given DOCTYPE. + * + * @param doctype Initial DocType of the document. + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument(DocType doctype) throws JDOMException; +} Index: 3rdParty_sources/jdom/org/jdom/adapters/JAXPDOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/JAXPDOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/JAXPDOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,195 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.jdom.input.*; +import org.w3c.dom.Document; + +/** + * An adapter for any parser supporting the Sun JAXP APIs. + * + * @version $Revision$, $Date$ + * @author Jason Hunter + */ +public class JAXPDOMAdapter extends AbstractDOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a JAXP + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation + * should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException { + + try { + // Try using JAXP... + // Note we need DOM Level 2 and thus JAXP 1.1. + Class.forName("javax.xml.transform.Transformer"); + + // Try JAXP 1.1 calls to build the document + Class factoryClass = + Class.forName("javax.xml.parsers.DocumentBuilderFactory"); + + // factory = DocumentBuilderFactory.newInstance(); + Method newParserInstance = + factoryClass.getMethod("newInstance", null); + Object factory = newParserInstance.invoke(null, null); + + // factory.setValidating(validate); + Method setValidating = + factoryClass.getMethod("setValidating", + new Class[]{boolean.class}); + setValidating.invoke(factory, + new Object[]{new Boolean(validate)}); + + // factory.setNamespaceAware(true); + Method setNamespaceAware = + factoryClass.getMethod("setNamespaceAware", + new Class[]{boolean.class}); + setNamespaceAware.invoke(factory, + new Object[]{Boolean.TRUE}); + + // jaxpParser = factory.newDocumentBuilder(); + Method newDocBuilder = + factoryClass.getMethod("newDocumentBuilder", null); + Object jaxpParser = newDocBuilder.invoke(factory, null); + + // jaxpParser.setErrorHandler(null); + Class parserClass = jaxpParser.getClass(); + Method setErrorHandler = + parserClass.getMethod("setErrorHandler", + new Class[]{org.xml.sax.ErrorHandler.class}); + setErrorHandler.invoke(jaxpParser, + new Object[]{new BuilderErrorHandler()}); + + // domDoc = jaxpParser.parse(in); + Method parse = parserClass.getMethod( + "parse", new Class[]{InputStream.class}); + org.w3c.dom.Document domDoc = (org.w3c.dom.Document) + parse.invoke(jaxpParser, new Object[]{in}); + + return domDoc; + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof IOException) { + throw (IOException) targetException; + } else { + throw new JDOMException(targetException.getMessage(), targetException); + } + } catch (Exception e) { + throw new JDOMException("Reflection failed while parsing a document with JAXP", e); + } + + // Allow all exceptions to pass through + } + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur in parsing. + */ + public Document createDocument() + throws JDOMException { + + try { + // We need DOM Level 2 and thus JAXP 1.1. + // If JAXP 1.0 is all that's available then we error out. + Class.forName("javax.xml.transform.Transformer"); + + // Try JAXP 1.1 calls to build the document + Class factoryClass = + Class.forName("javax.xml.parsers.DocumentBuilderFactory"); + + // factory = DocumentBuilderFactory.newInstance(); + Method newParserInstance = + factoryClass.getMethod("newInstance", null); + Object factory = newParserInstance.invoke(null, null); + + // jaxpParser = factory.newDocumentBuilder(); + Method newDocBuilder = + factoryClass.getMethod("newDocumentBuilder", null); + Object jaxpParser = newDocBuilder.invoke(factory, null); + + // domDoc = jaxpParser.newDocument(); + Class parserClass = jaxpParser.getClass(); + Method newDoc = parserClass.getMethod("newDocument", null); + org.w3c.dom.Document domDoc = + (org.w3c.dom.Document) newDoc.invoke(jaxpParser, null); + + return domDoc; + } catch (Exception e) { + throw new JDOMException("Reflection failed while creating new JAXP document", e); + } + + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/OracleV1DOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/OracleV1DOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/OracleV1DOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,145 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.w3c.dom.Document; +import org.xml.sax.*; + +/** + * An adapter for the Oracle Version 1 DOM parser. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class OracleV1DOMAdapter extends AbstractDOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException { + + try { + // Load the parser class + Class parserClass = Class.forName("oracle.xml.parser.XMLParser"); + Object parser = parserClass.newInstance(); + + // Parse the document + Method parse = + parserClass.getMethod("parse", + new Class[] {org.xml.sax.InputSource.class}); + parse.invoke(parser, new Object[] {new InputSource(in)}); + + // Get the Document object + Method getDocument = parserClass.getMethod("getDocument", null); + Document doc = (Document)getDocument.invoke(parser, null); + + return doc; + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof org.xml.sax.SAXParseException) { + SAXParseException parseException = (SAXParseException) targetException; + throw new JDOMException("Error on line " + parseException.getLineNumber() + + " of XML document: " + parseException.getMessage(), parseException); + } else if (targetException instanceof IOException) { + IOException ioException = (IOException) targetException; + throw ioException; + } else { + throw new JDOMException(targetException.getMessage(), targetException); + } + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage(), e); + } + } + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument() throws JDOMException { + try { + return + (Document)Class.forName( + "oracle.xml.parser.XMLDocument") + .newInstance(); + + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage() + " when creating document", e); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/OracleV2DOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/OracleV2DOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/OracleV2DOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,145 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.w3c.dom.Document; +import org.xml.sax.*; + +/** + * An adapter for the Oracle Version 2 DOM parser. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class OracleV2DOMAdapter extends AbstractDOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException { + + try { + // Load the parser class + Class parserClass = Class.forName("oracle.xml.parser.v2.DOMParser"); + Object parser = parserClass.newInstance(); + + // Parse the document + Method parse = + parserClass.getMethod("parse", + new Class[] {org.xml.sax.InputSource.class}); + parse.invoke(parser, new Object[] {new InputSource(in)}); + + // Get the Document object + Method getDocument = parserClass.getMethod("getDocument", null); + Document doc = (Document)getDocument.invoke(parser, null); + + return doc; + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof org.xml.sax.SAXParseException) { + SAXParseException parseException = (SAXParseException)targetException; + throw new JDOMException("Error on line " + parseException.getLineNumber() + + " of XML document: " + parseException.getMessage(), parseException); + } else if (targetException instanceof IOException) { + IOException ioException = (IOException) targetException; + throw ioException; + } else { + throw new JDOMException(targetException.getMessage(), targetException); + } + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage(), e); + } + } + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument() throws JDOMException { + try { + return + (Document)Class.forName( + "oracle.xml.parser.v2.XMLDocument") + .newInstance(); + + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage() + " when creating document", e); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/XML4JDOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/XML4JDOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/XML4JDOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,171 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.jdom.input.*; +import org.w3c.dom.Document; +import org.xml.sax.*; + +/** + * An adapter for the IBM XML4J DOM parser. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class XML4JDOMAdapter extends AbstractDOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException { + + try { + /* + * IBM XML4J actually uses the Xerces parser, so this is + * all Xerces specific code. + */ + + // Load the parser class + Class parserClass = Class.forName("org.apache.xerces.parsers.DOMParser"); + Object parser = parserClass.newInstance(); + + // Set validation + Method setFeature = + parserClass.getMethod("setFeature", + new Class[] {java.lang.String.class, + boolean.class}); + setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/validation", + new Boolean(validate)}); + + // Set namespaces + setFeature.invoke(parser, new Object[] {"http://xml.org/sax/features/namespaces", + new Boolean(false)}); + + // Set the error handler + if (validate) { + Method setErrorHandler = + parserClass.getMethod("setErrorHandler", + new Class[] {ErrorHandler.class}); + setErrorHandler.invoke(parser, new Object[] {new BuilderErrorHandler()}); + } + + // Parse the document + Method parse = + parserClass.getMethod("parse", + new Class[] {org.xml.sax.InputSource.class}); + parse.invoke(parser, new Object[]{new InputSource(in)}); + + // Get the Document object + Method getDocument = parserClass.getMethod("getDocument", null); + Document doc = (Document)getDocument.invoke(parser, null); + + return doc; + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof org.xml.sax.SAXParseException) { + SAXParseException parseException = (SAXParseException)targetException; + throw new JDOMException("Error on line " + parseException.getLineNumber() + + " of XML document: " + parseException.getMessage(), parseException); + } else if (targetException instanceof IOException) { + IOException ioException = (IOException) targetException; + throw ioException; + } else { + throw new JDOMException(targetException.getMessage(), targetException); + } + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage(), e); + } + } + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument() throws JDOMException { + try { + return + (Document)Class.forName( + "org.apache.xerces.dom.DocumentImpl") + .newInstance(); + + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage() + " while creating document", e); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/XercesDOMAdapter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/XercesDOMAdapter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/XercesDOMAdapter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,170 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.adapters; + +import java.io.*; +import java.lang.reflect.*; + +import org.jdom.*; +import org.jdom.input.*; +import org.w3c.dom.Document; +import org.xml.sax.*; + +/** + * An adapter for the Apache Xerces DOM parser. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + */ +public class XercesDOMAdapter extends AbstractDOMAdapter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This creates a new {@link Document} from an + * existing InputStream by letting a DOM + * parser handle parsing using the supplied stream. + * + * @param in InputStream to parse. + * @param validate boolean to indicate if validation + * should occur. + * @return Document - instance ready for use. + * @throws IOException when I/O error occurs. + * @throws JDOMException when errors occur in parsing. + */ + public Document getDocument(InputStream in, boolean validate) + throws IOException, JDOMException { + + try { + // Load the parser class + Class parserClass = + Class.forName("org.apache.xerces.parsers.DOMParser"); + Object parser = parserClass.newInstance(); + + // Set validation + Method setFeature = parserClass.getMethod( + "setFeature", + new Class[] {java.lang.String.class, boolean.class}); + setFeature.invoke(parser, + new Object[] {"http://xml.org/sax/features/validation", + new Boolean(validate)}); + + // Set namespaces true + setFeature.invoke(parser, + new Object[] {"http://xml.org/sax/features/namespaces", + new Boolean(true)}); + + // Set the error handler + if (validate) { + Method setErrorHandler = parserClass.getMethod( + "setErrorHandler", + new Class[] {ErrorHandler.class}); + setErrorHandler.invoke(parser, + new Object[] {new BuilderErrorHandler()}); + } + + // Parse the document + Method parse = parserClass.getMethod( + "parse", + new Class[] {org.xml.sax.InputSource.class}); + parse.invoke(parser, new Object[]{new InputSource(in)}); + + // Get the Document object + Method getDocument = parserClass.getMethod("getDocument", null); + Document doc = (Document)getDocument.invoke(parser, null); + + return doc; + } catch (InvocationTargetException e) { + Throwable targetException = e.getTargetException(); + if (targetException instanceof org.xml.sax.SAXParseException) { + SAXParseException parseException = + (SAXParseException)targetException; + throw new JDOMException("Error on line " + + parseException.getLineNumber() + + " of XML document: " + + parseException.getMessage(), e); + } else if (targetException instanceof IOException) { + IOException ioException = (IOException) targetException; + throw ioException; + } else { + throw new JDOMException(targetException.getMessage(), e); + } + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage(), e); + } + } + + /** + * This creates an empty Document object based + * on a specific parser implementation. + * + * @return Document - created DOM Document. + * @throws JDOMException when errors occur. + */ + public Document createDocument() throws JDOMException { + try { + return (Document)Class.forName( + "org.apache.xerces.dom.DocumentImpl").newInstance(); + } catch (Exception e) { + throw new JDOMException(e.getClass().getName() + ": " + + e.getMessage() + " when creating document", e); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/adapters/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/adapters/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/adapters/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,7 @@ + + +Classes to interface with various DOM implementations. Not generally +needed except in truly advanced situations. JAXPDOMAdapter is most commonly +used. + + Index: 3rdParty_sources/jdom/org/jdom/filter/AbstractFilter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/AbstractFilter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/AbstractFilter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,82 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + +/** + * Partial implementation of {@link Filter}. + * + * @author Bradley S. Huffman + * @version $Revision$, $Date$ + */ +public abstract class AbstractFilter implements Filter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$"; + + public Filter negate() { + return new NegateFilter(this); + } + + public Filter or(Filter filter) { + return new OrFilter(this, filter); + } + + public Filter and(Filter filter) { + return new AndFilter(this, filter); + } + +} Index: 3rdParty_sources/jdom/org/jdom/filter/AndFilter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/AndFilter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/AndFilter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,125 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + +/** + * Allow two filters to be chained together with a logical + * and operation. + * + * @author Bradley S. Huffman + * @version $Revision$, $Date$ + */ +final class AndFilter extends AbstractFilter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$"; + + // Filter for left side of logical and. + private Filter left; + + // Filter for right side of logical and. + private Filter right; + + /** + * Match if only both supplied filters match. + * + * @param left left side of logical and + * @param right right side of logical and + * @throws IllegalArgumentException if either supplied filter is null + */ + public AndFilter(Filter left, Filter right) { + if ((left == null) || (right == null)) { + throw new IllegalArgumentException("null filter not allowed"); + } + this.left = left; + this.right = right; + } + + public boolean matches(Object obj) { + return left.matches(obj) && right.matches(obj); + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof AndFilter) { + AndFilter filter = (AndFilter) obj; + if ((left.equals(filter.left) && right.equals(filter.right)) || + (left.equals(filter.right) && right.equals(filter.left))) { + return true; + } + } + return false; + } + + public int hashCode() { + return (31 * left.hashCode()) + right.hashCode(); + } + + public String toString() { + return new StringBuffer(64) + .append("[AndFilter: ") + .append(left.toString()) + .append(",\n") + .append(" ") + .append(right.toString()) + .append("]") + .toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/filter/ContentFilter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/ContentFilter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/ContentFilter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,356 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + +import org.jdom.*; + +/** + * A general purpose Filter able to represent all legal JDOM objects or a + * specific subset. Filtering is accomplished by way of a filtering mask in + * which each bit represents whether a JDOM object is visible or not. + * For example to view all Text and CDATA nodes in the content of element x. + *

+ *      Filter filter = new ContentFilter(ContentFilter.TEXT |
+ *                                        ContentFilter.CDATA);
+ *      List content = x.getContent(filter);
+ * 
+ *

+ * For those who don't like bit-masking, set methods are provided as an + * alternative. For example to allow everything except Comment nodes. + *


+ *      Filter filter =  new ContentFilter();
+ *      filter.setCommentVisible(false);
+ *      List content = x.getContent(filter);
+ * 
+ *

+ * The default is to allow all valid JDOM objects. + * + * @version $Revision$, $Date$ + * @author Bradley S. Huffman + */ +public class ContentFilter extends AbstractFilter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** Mask for JDOM {@link Element} objects */ + public static final int ELEMENT = 1; + + /** Mask for JDOM {@link CDATA} objects */ + public static final int CDATA = 2; + + /** Mask for JDOM {@link Text} objects */ + public static final int TEXT = 4; + + /** Mask for JDOM {@link Comment} objects */ + public static final int COMMENT = 8; + + /** Mask for JDOM {@link ProcessingInstruction} objects */ + public static final int PI = 16; + + /** Mask for JDOM {@link EntityRef} objects */ + public static final int ENTITYREF = 32; + + /** Mask for JDOM {@link Document} object */ + public static final int DOCUMENT = 64; + + /** Mask for JDOM {@link DocType} object */ + public static final int DOCTYPE = 128; + + /** The JDOM object mask */ + private int filterMask; + + /** + * Default constructor that allows any legal JDOM objects. + */ + public ContentFilter() { + setDefaultMask(); + } + + /** + * Set whether all JDOM objects are visible or not. + * + * @param allVisible true all JDOM objects are visible, + * false all JDOM objects are hidden. + */ + public ContentFilter(boolean allVisible) { + if (allVisible) { + setDefaultMask(); + } + else { + filterMask &= ~filterMask; + } + } + + /** + * Filter out JDOM objects according to a filtering mask. + * + * @param mask Mask of JDOM objects to allow. + */ + public ContentFilter(int mask) { + setFilterMask(mask); + } + + /** + * Return current filtering mask. + * + * @return the current filtering mask + */ + public int getFilterMask() { + return filterMask; + } + + /** + * Set filtering mask. + * + * @param mask the new filtering mask + */ + public void setFilterMask(int mask) { + setDefaultMask(); + filterMask &= mask; + } + + /** + * Set this filter to allow all legal JDOM objects. + */ + public void setDefaultMask() { + filterMask = ELEMENT | CDATA | TEXT | COMMENT | + PI | ENTITYREF | DOCUMENT | DOCTYPE; + } + + /** + * Set filter to match only JDOM objects that are legal + * document content. + */ + public void setDocumentContent() { + filterMask = ELEMENT | COMMENT | PI | DOCTYPE; + } + + /** + * Set filter to match only JDOM objects that are legal + * element content. + */ + public void setElementContent() { + filterMask = ELEMENT | CDATA | TEXT | + COMMENT | PI | ENTITYREF; + } + + /** + * Set visiblity of Element objects. + * + * @param visible whether Elements are visible, true + * if yes, false if not + */ + public void setElementVisible(boolean visible) { + if (visible) { + filterMask |= ELEMENT; + } + else { + filterMask &= ~ELEMENT; + } + } + + /** + * Set visiblity of CDATA objects. + * + * @param visible whether CDATA nodes are visible, true + * if yes, false if not + */ + public void setCDATAVisible(boolean visible) { + if (visible) { + filterMask |= CDATA; + } + else { + filterMask &= ~CDATA; + } + } + + /** + * Set visiblity of Text objects. + * + * @param visible whether Text nodes are visible, true + * if yes, false if not + */ + public void setTextVisible(boolean visible) { + if (visible) { + filterMask |= TEXT; + } + else { + filterMask &= ~TEXT; + } + } + + /** + * Set visiblity of Comment objects. + * + * @param visible whether Comments are visible, true + * if yes, false if not + */ + public void setCommentVisible(boolean visible) { + if (visible) { + filterMask |= COMMENT; + } + else { + filterMask &= ~COMMENT; + } + } + + /** + * Set visiblity of ProcessingInstruction objects. + * + * @param visible whether ProcessingInstructions are visible, + * true if yes, false if not + */ + public void setPIVisible(boolean visible) { + if (visible) { + filterMask |= PI; + } + else { + filterMask &= ~PI; + } + } + + /** + * Set visiblity of EntityRef objects. + * + * @param visible whether EntityRefs are visible, true + * if yes, false if not + */ + public void setEntityRefVisible(boolean visible) { + if (visible) { + filterMask |= ENTITYREF; + } + else { + filterMask &= ~ENTITYREF; + } + } + + /** + * Set visiblity of DocType objects. + * + * @param visible whether the DocType is visible, true + * if yes, false if not + */ + public void setDocTypeVisible(boolean visible) { + if (visible) { + filterMask |= DOCTYPE; + } + else { + filterMask &= ~DOCTYPE; + } + } + + /** + * Check to see if the object matches according to the filter mask. + * + * @param obj The object to verify. + * @return true if the objected matched a predfined + * set of rules. + */ + public boolean matches(Object obj) { + if (obj instanceof Element) { + return (filterMask & ELEMENT) != 0; + } + else if (obj instanceof CDATA) { // must come before Text check + return (filterMask & CDATA) != 0; + } + else if (obj instanceof Text) { + return (filterMask & TEXT) != 0; + } + else if (obj instanceof Comment) { + return (filterMask & COMMENT) != 0; + } + else if (obj instanceof ProcessingInstruction) { + return (filterMask & PI) != 0; + } + else if (obj instanceof EntityRef) { + return (filterMask & ENTITYREF) != 0; + } + else if (obj instanceof Document) { + return (filterMask & DOCUMENT) != 0; + } + else if (obj instanceof DocType) { + return (filterMask & DOCTYPE) != 0; + } + + return false; + } + + /** + * Returns whether the two filters are equivalent (i.e. the + * matching mask values are identical). + * + * @param obj the object to compare against + * @return whether the two filters are equal + */ + public boolean equals(Object obj) { + // Generated by IntelliJ + if (this == obj) return true; + if (!(obj instanceof ContentFilter)) return false; + + final ContentFilter filter = (ContentFilter) obj; + + if (filterMask != filter.filterMask) return false; + + return true; + } + + public int hashCode() { + // Generated by IntelliJ + return filterMask; + } +} Index: 3rdParty_sources/jdom/org/jdom/filter/ElementFilter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/ElementFilter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/ElementFilter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,189 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + +import java.io.*; +import org.jdom.*; + +/** + * A Filter that only matches {@link org.jdom.Element} objects. + * + * @version $Revision$, $Date$ + * @author Jools Enticknap + * @author Bradley S. Huffman + */ +public class ElementFilter extends AbstractFilter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The element name */ + private String name; + + /** The element namespace */ + private transient Namespace namespace; + + /** + * Select only the Elements. + */ + public ElementFilter() {} + + /** + * Select only the Elements with the supplied name in any Namespace. + * + * @param name The name of the Element. + */ + public ElementFilter(String name) { + this.name = name; + } + + /** + * Select only the Elements with the supplied Namespace. + * + * @param namespace The namespace the Element lives in. + */ + public ElementFilter(Namespace namespace) { + this.namespace = namespace; + } + + /** + * Select only the Elements with the supplied name and Namespace. + * + * @param name The name of the Element. + * @param namespace The namespace the Element lives in. + */ + public ElementFilter(String name, Namespace namespace) { + this.name = name; + this.namespace = namespace; + } + + /** + * Check to see if the object matches a predefined set of rules. + * + * @param obj The object to verify. + * @return true if the objected matched a predfined + * set of rules. + */ + public boolean matches(Object obj) { + if (obj instanceof Element) { + Element el = (Element) obj; + return + (this.name == null || this.name.equals(el.getName())) && + (this.namespace == null || this.namespace.equals(el.getNamespace())); + } + return false; + } + + /** + * Returns whether the two filters are equivalent (i.e. the + * matching names and namespace are equivalent). + * + * @param obj the object to compare against + * @return whether the two filters are equal + */ + public boolean equals(Object obj) { + // Generated by IntelliJ + if (this == obj) return true; + if (!(obj instanceof ElementFilter)) return false; + + final ElementFilter filter = (ElementFilter) obj; + + if (name != null ? !name.equals(filter.name) : filter.name != null) return false; + if (namespace != null ? !namespace.equals(filter.namespace) : filter.namespace != null) return false; + + return true; + } + + public int hashCode() { + // Generated by IntelliJ + int result; + result = (name != null ? name.hashCode() : 0); + result = 29 * result + (namespace != null ? namespace.hashCode() : 0); + return result; + } + + // Support a custom Namespace serialization so no two namespace + // object instances may exist for the same prefix/uri pair + private void writeObject(ObjectOutputStream out) throws IOException { + + out.defaultWriteObject(); + + // We use writeObject() and not writeUTF() to minimize space + // This allows for writing pointers to already written strings + if (namespace != null) { + out.writeObject(namespace.getPrefix()); + out.writeObject(namespace.getURI()); + } + else { + out.writeObject(null); + out.writeObject(null); + } + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + + in.defaultReadObject(); + + Object prefix = in.readObject(); + Object uri = in.readObject(); + + if (prefix != null) { // else leave namespace null here + namespace = Namespace.getNamespace((String) prefix, (String) uri); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/filter/Filter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/Filter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/Filter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,76 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + + +/** + * A generalized filter to restrict visibility or mutability on a list. + * + * @version $Revision$, $Date$ + * @author Jools Enticknap + * @author Bradley S. Huffman + */ +public interface Filter extends java.io.Serializable { + /** + * Check to see if the object matches a predefined set of rules. + * + * @param obj The object to verify. + * @return true if the object matches a predfined + * set of rules. + */ + public boolean matches(Object obj); +} Index: 3rdParty_sources/jdom/org/jdom/filter/NegateFilter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/NegateFilter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/NegateFilter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,113 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + +/** + * Filter that is the logical negation operation of another filter. + * + * + * @author Bradley S. Huffman + * @version $Revision$, $Date$ + */ +final class NegateFilter extends AbstractFilter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$"; + + // Underlying filter. + private Filter filter; + + /** + * Match if the supplied filter does not match. + * + * @param filter filter to use. + */ + public NegateFilter(Filter filter) { + this.filter = filter; + } + + public boolean matches(Object obj) { + return !filter.matches(obj); + } + + public Filter negate() { + return filter; + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof NegateFilter) { + return filter.equals(((NegateFilter) obj).filter); + } + return false; + } + + public int hashCode() { + return ~filter.hashCode(); + } + + public String toString() { + return new StringBuffer(64) + .append("[NegateFilter: ") + .append(filter.toString()) + .append("]") + .toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/filter/OrFilter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/OrFilter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/OrFilter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,125 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.filter; + +/** + * Allow two filters to be chained together with a logical + * or operation. + * + * @author Bradley S. Huffman + * @version $Revision$, $Date$ + */ +final class OrFilter extends AbstractFilter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$"; + + /** Filter for left side of logical or */ + private Filter left; + + /** Filter for right side of logical or */ + private Filter right; + + /** + * Match if either of the supplied filters. + * + * @param left left side of logical or + * @param right right side of logical or + * @throws IllegalArgumentException if either supplied filter is null + */ + public OrFilter(Filter left, Filter right) { + if ((left == null) || (right == null)) { + throw new IllegalArgumentException("null filter not allowed"); + } + this.left = left; + this.right = right; + } + + public boolean matches(Object obj) { + return left.matches(obj) || right.matches(obj); + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof OrFilter) { + OrFilter filter = (OrFilter) obj; + if ((left.equals(filter.left) && right.equals(filter.right)) || + (left.equals(filter.right) && right.equals(filter.left))) { + return true; + } + } + return false; + } + + public int hashCode() { + return (31 * left.hashCode()) + right.hashCode(); + } + + public String toString() { + return new StringBuffer(64) + .append("[OrFilter: ") + .append(left.toString()) + .append(",\n") + .append(" ") + .append(right.toString()) + .append("]") + .toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/filter/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/filter/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/filter/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,9 @@ + + +Classes to programmatically filter nodes of a document based on type, name, +value, or other aspects and to boolean and/or/negate these rules. Filters can +be used in methods like getContent(Filter) and getDescendants(Filter). A +sampling of generally useful filters are provided here. Alternate filters can +be user defined. + + Index: 3rdParty_sources/jdom/org/jdom/input/BuilderErrorHandler.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/BuilderErrorHandler.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/BuilderErrorHandler.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,111 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import org.xml.sax.*; + +/** + * The standard JDOM error handler implementation. + * + * @author Jason Hunter + * @version $Revision$, $Date$ + */ + +public class BuilderErrorHandler implements ErrorHandler { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * This method is called when a warning has occurred; this indicates + * that while no XML rules were broken, something appears to be + * incorrect or missing. + * The implementation of this method here is a "no op". + * + * @param exception SAXParseException that occurred. + * @throws SAXException when things go wrong + */ + public void warning(SAXParseException exception) throws SAXException { + // nothing + } + + /** + * This method is called in response to an error that has occurred; + * this indicates that a rule was broken, typically in validation, but + * that parsing could reasonably continue. + * The implementation of this method here is to rethrow the exception. + * + * @param exception SAXParseException that occurred. + * @throws SAXException when things go wrong + */ + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + /** + * This method is called in response to a fatal error; this indicates that + * a rule has been broken that makes continued parsing either impossible + * or an almost certain waste of time. + * The implementation of this method here is to rethrow the exception. + * + * @param exception SAXParseException that occurred. + * @throws SAXException when things go wrong + */ + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } +} Index: 3rdParty_sources/jdom/org/jdom/input/DOMBuilder.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/DOMBuilder.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/DOMBuilder.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,421 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import java.util.HashSet; +import java.util.Iterator; + +import org.jdom.*; +import org.jdom.Document; +import org.jdom.Element; +import org.w3c.dom.*; + +/** + * Builds a JDOM {@link org.jdom.Document org.jdom.Document} from a pre-existing + * DOM {@link org.w3c.dom.Document org.w3c.dom.Document}. Also handy for testing + * builds from files to sanity check {@link SAXBuilder}. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Philip Nelson + * @author Kevin Regan + * @author Yusuf Goolamabbas + * @author Dan Schaffer + * @author Bradley S. Huffman + */ +public class DOMBuilder { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** Adapter class to use */ + private String adapterClass; + + /** The factory for creating new JDOM objects */ + private JDOMFactory factory = new DefaultJDOMFactory(); + + /** + * This creates a new DOMBuilder which will attempt to first locate + * a parser via JAXP, then will try to use a set of default parsers. + * The underlying parser will not validate. + */ + public DOMBuilder() { + } + + /** + * This creates a new DOMBuilder using the specified DOMAdapter + * implementation as a way to choose the underlying parser. + * The underlying parser will not validate. + * + * @param adapterClass String name of class + * to use for DOM building. + */ + public DOMBuilder(String adapterClass) { + this.adapterClass = adapterClass; + } + + /* + * This sets a custom JDOMFactory for the builder. Use this to build + * the tree with your own subclasses of the JDOM classes. + * + * @param factory JDOMFactory to use + */ + public void setFactory(JDOMFactory factory) { + this.factory = factory; + } + + /** + * Returns the current {@link org.jdom.JDOMFactory} in use. + * @return the factory in use + */ + public JDOMFactory getFactory() { + return factory; + } + + /** + * This will build a JDOM tree from an existing DOM tree. + * + * @param domDocument org.w3c.dom.Document object + * @return Document - JDOM document object. + */ + public Document build(org.w3c.dom.Document domDocument) { + Document doc = factory.document(null); + buildTree(domDocument, doc, null, true); + return doc; + } + + /** + * This will build a JDOM Element from an existing DOM Element + * + * @param domElement org.w3c.dom.Element object + * @return Element - JDOM Element object + */ + public org.jdom.Element build(org.w3c.dom.Element domElement) { + Document doc = factory.document(null); + buildTree(domElement, doc, null, true); + return doc.getRootElement(); + } + + /** + * This takes a DOM Node and builds up + * a JDOM tree, recursing until the DOM tree is exhausted + * and the JDOM tree results. + * + * @param node Code to examine. + * @param doc JDOM Document being built. + * @param current Element that is current parent. + * @param atRoot boolean indicating whether at root level. + */ + private void buildTree(Node node, + Document doc, + Element current, + boolean atRoot) { + // Recurse through the tree + switch (node.getNodeType()) { + case Node.DOCUMENT_NODE: + NodeList nodes = node.getChildNodes(); + for (int i=0, size=nodes.getLength(); i= 0) { + prefix = nodeName.substring(0, colon); + localName = nodeName.substring(colon + 1); + } + + // Get element's namespace + Namespace ns = null; + String uri = node.getNamespaceURI(); + if (uri == null) { + ns = (current == null) ? Namespace.NO_NAMESPACE + : current.getNamespace(prefix); + } + else { + ns = Namespace.getNamespace(prefix, uri); + } + + Element element = factory.element(localName, ns); + + if (atRoot) { + // If at root, set as document root + doc.setRootElement(element); // XXX should we use a factory call? + } else { + // else add to parent element + factory.addContent(current, element); + } + + // Add namespaces + NamedNodeMap attributeList = node.getAttributes(); + int attsize = attributeList.getLength(); + + for (int i = 0; i < attsize; i++) { + Attr att = (Attr) attributeList.item(i); + + String attname = att.getName(); + if (attname.startsWith("xmlns")) { + String attPrefix = ""; + colon = attname.indexOf(':'); + if (colon >= 0) { + attPrefix = attname.substring(colon + 1); + } + + String attvalue = att.getValue(); + + Namespace declaredNS = + Namespace.getNamespace(attPrefix, attvalue); + + // Add as additional namespaces if it's different + // to this element's namespace (perhaps we should + // also have logic not to mark them as additional if + // it's been done already, but it probably doesn't + // matter) + if (prefix.equals(attPrefix)) { + // RL: note, it should also be true that uri.equals(attvalue) + // if not, then the parser is boken. + // further, declaredNS should be exactly the same as ns + // so the following should in fact do nothing. + element.setNamespace(declaredNS); + } + else { + factory.addNamespaceDeclaration(element, declaredNS); + } + } + } + + // Add attributes + for (int i = 0; i < attsize; i++) { + Attr att = (Attr) attributeList.item(i); + + String attname = att.getName(); + + if ( !attname.startsWith("xmlns")) { + String attPrefix = ""; + String attLocalName = attname; + colon = attname.indexOf(':'); + if (colon >= 0) { + attPrefix = attname.substring(0, colon); + attLocalName = attname.substring(colon + 1); + } + + String attvalue = att.getValue(); + + // Get attribute's namespace + Namespace attNS = null; + String attURI = att.getNamespaceURI(); + if (attURI == null || "".equals(attURI)) { + attNS = Namespace.NO_NAMESPACE; + } else { + // various conditions can lead here. + // the logical one is that we have a prefix for the + // attribute, and also a namespace URI. + // The alternative to that is in some conditions, + // the parser could have a 'default' or 'fixed' + // attribute that comes from an XSD used for + // validation. In that case there may not be a prefix + // There's also the possibility the DOM contains + // garbage. + if (attPrefix.length() > 0) { + // If the att has a prefix, we can assume that + // the DOM is valid, and we can just use the prefix. + // if this prefix conflicts with some other namespace + // then we re-declare it. If redeclaring it screws up + // other attributes in this Element, then the DOM + // was broken to start with. + attNS = Namespace.getNamespace(attPrefix, attURI); + } else { + // OK, no prefix. + // must be a defaulted value from an XSD. + // perhaps we can find the namespace in our + // element's ancestry, and use the prefix from that. + // We need to ensure that a particular prefix has not been + // overridden at a lower level than what we are expecting. + // track all prefixes to ensure they are not changed lower + // down. + HashSet overrides = new HashSet(); + Element p = element; + uploop: do { + // Search up the Element tree looking for a prefixed namespace + // matching our attURI + if (p.getNamespace().getURI().equals(attURI) + && !overrides.contains(p.getNamespacePrefix()) + && !"".equals(element.getNamespace().getPrefix())) { + // we need a prefix. It's impossible to have a namespaced + // attribute if there is no prefix for that attribute. + attNS = p.getNamespace(); + break uploop; + } + overrides.add(p.getNamespacePrefix()); + for (Iterator it = p.getAdditionalNamespaces().iterator(); + it.hasNext(); ) { + Namespace tns = (Namespace)it.next(); + if (!overrides.contains(tns.getPrefix()) + && attURI.equals(tns.getURI())) { + attNS = tns; + break uploop; + } + overrides.add(tns.getPrefix()); + } + p = p.getParentElement(); + } while (p != null); + if (attNS == null) { + // we cannot find a 'prevailing' namespace that has a prefix + // that is for this namespace. + // This basically means that there's an XMLSchema, for the + // DEFAULT namespace, and there's a defaulted/fixed + // attribute definition in the XMLSchema that's targeted + // for this namespace,... but, the user has either not + // declared a prefixed version of the namespace, or has + // re-declared the same prefix at a lower level with a + // different namespace. + // All of these things are possible. + // Create some sort of default prefix. + int cnt = 0; + String base = "attns"; + String pfx = base + cnt; + while (overrides.contains(pfx)) { + cnt++; + pfx = base + cnt; + } + attNS = Namespace.getNamespace(pfx, attURI); + } + } + } + + Attribute attribute = + factory.attribute(attLocalName, attvalue, attNS); + factory.setAttribute(element, attribute); + } + } + + // Recurse on child nodes + // The list should never be null nor should it ever contain + // null nodes, but some DOM impls are broken + NodeList children = node.getChildNodes(); + if (children != null) { + int size = children.getLength(); + for (int i = 0; i < size; i++) { + Node item = children.item(i); + if (item != null) { + buildTree(item, doc, element, false); + } + } + } + break; + + case Node.TEXT_NODE: + String data = node.getNodeValue(); + factory.addContent(current, factory.text(data)); + break; + + case Node.CDATA_SECTION_NODE: + String cdata = node.getNodeValue(); + factory.addContent(current, factory.cdata(cdata)); + break; + + + case Node.PROCESSING_INSTRUCTION_NODE: + if (atRoot) { + factory.addContent(doc, + factory.processingInstruction(node.getNodeName(), + node.getNodeValue())); + } else { + factory.addContent(current, + factory.processingInstruction(node.getNodeName(), + node.getNodeValue())); + } + break; + + case Node.COMMENT_NODE: + if (atRoot) { + factory.addContent(doc, factory.comment(node.getNodeValue())); + } else { + factory.addContent(current, factory.comment(node.getNodeValue())); + } + break; + + case Node.ENTITY_REFERENCE_NODE: + EntityRef entity = factory.entityRef(node.getNodeName()); + factory.addContent(current, entity); + break; + + case Node.ENTITY_NODE: + // ?? + break; + + case Node.DOCUMENT_TYPE_NODE: + DocumentType domDocType = (DocumentType)node; + String publicID = domDocType.getPublicId(); + String systemID = domDocType.getSystemId(); + String internalDTD = domDocType.getInternalSubset(); + + DocType docType = factory.docType(domDocType.getName()); + docType.setPublicID(publicID); + docType.setSystemID(systemID); + docType.setInternalSubset(internalDTD); + + factory.addContent(doc, docType); + break; + } + } +} Index: 3rdParty_sources/jdom/org/jdom/input/JAXPParserFactory.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/JAXPParserFactory.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/JAXPParserFactory.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,179 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import java.util.*; + +import javax.xml.parsers.*; + +import org.jdom.*; +import org.xml.sax.*; + +/** + * A non-public utility class to allocate JAXP SAX parsers. + * + * @version $Revision$, $Date$ + * @author Laurent Bihanic + */ +class JAXPParserFactory { // package protected + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** JAXP 1.2 schema language property id. */ + private static final String JAXP_SCHEMA_LANGUAGE_PROPERTY = + "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + + /** JAXP 1.2 schema location property id. */ + private static final String JAXP_SCHEMA_LOCATION_PROPERTY = + "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + /** + * Private constructor to forbid allocating instances of this utility + * class. + */ + private JAXPParserFactory() { + // Never called. + } + + /* Implementor's note regarding createParser() design: The features and + properties are normally set in SAXBuilder, but we take them in + createParser() as well because some features or properties may need to be + applied during the JAXP parser construction. Today, for example, properties + is used as it's the only way to configure schema validation: JAXP defines + schema validation properties but SAX does not. This reflects in the Apache + Xerces implementation where the SAXParser implementation supports the JAXP + properties but the XMLReader does not. Hence, configuring schema validation + must be done on the SAXParser object which is only visible in + JAXParserFactory. Features is also passed in case some future JAXP release + defines JAXP-specific features. + */ + + /** + * Creates a SAX parser allocated through the configured JAXP SAX + * parser factory. + * + * @param validating whether a validating parser is requested. + * @param features the user-defined SAX features. + * @param properties the user-defined SAX properties. + * + * @return a configured XMLReader. + * + * @throws JDOMException if any error occurred when allocating or + * configuring the JAXP SAX parser. + */ + public static XMLReader createParser(boolean validating, + Map features, Map properties) throws JDOMException { + try { + SAXParser parser = null; + + // Allocate and configure JAXP SAX parser factory. + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(validating); + factory.setNamespaceAware(true); + + try { + // Allocate parser. + parser = factory.newSAXParser(); + } + catch (ParserConfigurationException e) { + throw new JDOMException("Could not allocate JAXP SAX Parser", e); + } + + // Set user-defined JAXP properties (if any) + setProperty(parser, properties, JAXP_SCHEMA_LANGUAGE_PROPERTY); + setProperty(parser, properties, JAXP_SCHEMA_LOCATION_PROPERTY); + + // Return configured SAX XMLReader. + return parser.getXMLReader(); + } + catch (SAXException e) { + throw new JDOMException("Could not allocate JAXP SAX Parser", e); + } + } + + /** + * Sets a property on a JAXP SAX parser object if and only if it + * is declared in the user-defined properties. + * + * @param parser the JAXP SAX parser to configure. + * @param properties the user-defined SAX properties. + * @param name the name of the property to set. + * + * @throws JDOMException if any error occurred while configuring + * the property. + */ + private static void setProperty(SAXParser parser, + Map properties, String name) throws JDOMException { + try { + if (properties.containsKey(name)) { + parser.setProperty(name, properties.get(name)); + } + } + catch (SAXNotSupportedException e) { + throw new JDOMException( + name + " property not supported for JAXP parser " + + parser.getClass().getName()); + } + catch (SAXNotRecognizedException e) { + throw new JDOMException( + name + " property not recognized for JAXP parser " + + parser.getClass().getName()); + } + } +} + Index: 3rdParty_sources/jdom/org/jdom/input/JDOMParseException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/JDOMParseException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/JDOMParseException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,175 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import org.jdom.*; +import org.xml.sax.*; + +/** + * Thrown during parse errors, with information about where the parse error + * occurred as well as access to the partially built document. + * + * @version $Revision$, $Date$ + * @author Laurent Bihanic + */ +public class JDOMParseException extends JDOMException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * The portion of the document that was successfully built before + * the parse error occurred. + */ + private final Document partialDocument; + + /** + * This will create a parse Exception with the given + * message and wrap the Exception that cause a document + * parse to fail. + * + * @param message String message indicating + * the problem that occurred. + * @param cause Throwable that caused this + * to be thrown. + */ + public JDOMParseException(String message, Throwable cause) { + this(message, cause, null); + } + + /** + * This will create a parse Exception with the given + * message and the partial document and wrap the + * Exception that cause a document parse to fail. + * + * @param message String message indicating + * the problem that occurred. + * @param cause Throwable that caused this + * to be thrown. + * @param partialDocument Document the portion of + * the input XML document that was + * successfully built. + */ + public JDOMParseException(String message, Throwable cause, + Document partialDocument) { + super(message, cause); + this.partialDocument = partialDocument; + } + + /** + * Returns the partial document that was successfully built before + * the error occurred. + * + * @return the partial document or null if none. + */ + public Document getPartialDocument() { + return partialDocument; + } + + /** + * Returns the public identifier of the entity where the + * parse error occurred. + * + * @return a string containing the public identifier, or + * null if the information is not available. + */ + public String getPublicId() { + return (getCause() instanceof SAXParseException)? + ((SAXParseException)getCause()).getPublicId(): null; + } + + /** + * Returns the system identifier of the entity where the + * parse error occurred. + * + * @return a string containing the system identifier, or + * null if the information is not available. + */ + public String getSystemId() { + return (getCause() instanceof SAXParseException)? + ((SAXParseException)getCause()).getSystemId(): null; + } + + /** + * Returns the line number of the end of the text where the + * parse error occurred. + *

+ * The first line in the document is line 1.

+ * + * @return an integer representing the line number, or -1 + * if the information is not available. + */ + public int getLineNumber() { + return (getCause() instanceof SAXParseException)? + ((SAXParseException)getCause()).getLineNumber(): -1; + } + + /** + * Returns the column number of the end of the text where the + * parse error occurred. + *

+ * The first column in a line is position 1.

+ * + * @return an integer representing the column number, or -1 + * if the information is not available. + */ + public int getColumnNumber() { + return (getCause() instanceof SAXParseException)? + ((SAXParseException)getCause()).getColumnNumber(): -1; + } +} + Index: 3rdParty_sources/jdom/org/jdom/input/SAXBuilder.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/SAXBuilder.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/SAXBuilder.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,1105 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; + +import org.jdom.*; + +import org.xml.sax.*; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * Builds a JDOM document from files, streams, readers, URLs, or a SAX {@link + * org.xml.sax.InputSource} instance using a SAX parser. The builder uses a + * third-party SAX parser (chosen by JAXP by default, or you can choose + * manually) to handle the parsing duties and simply listens to the SAX events + * to construct a document. Details which SAX does not provide, such as + * whitespace outside the root element, are not represented in the JDOM + * document. Information about SAX can be found at http://www.saxproject.org. + *

+ * Known issues: Relative paths for a {@link DocType} or {@link EntityRef} may + * be converted by the SAX parser into absolute paths. + * + * @version $Revision$, $Date$ + * @author Jason Hunter + * @author Brett McLaughlin + * @author Dan Schaffer + * @author Philip Nelson + * @author Alex Rosen + */ +public class SAXBuilder { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Default parser class to use. This is used when no other parser + * is given and JAXP isn't available. + */ + private static final String DEFAULT_SAX_DRIVER = + "org.apache.xerces.parsers.SAXParser"; + + /** Whether validation should occur */ + private boolean validate; + + /** Whether expansion of entities should occur */ + private boolean expand = true; + + /** Adapter class to use */ + private String saxDriverClass; + + /** ErrorHandler class to use */ + private ErrorHandler saxErrorHandler = null; + + /** EntityResolver class to use */ + private EntityResolver saxEntityResolver = null; + + /** DTDHandler class to use */ + private DTDHandler saxDTDHandler = null; + + /** XMLFilter instance to use */ + private XMLFilter saxXMLFilter = null; + + /** The factory for creating new JDOM objects */ + private JDOMFactory factory = new DefaultJDOMFactory(); + + /** Whether to ignore ignorable whitespace */ + private boolean ignoringWhite = false; + + /** Whether to ignore all whitespace content */ + private boolean ignoringBoundaryWhite = false; + + /** User-specified features to be set on the SAX parser */ + private HashMap features = new HashMap(5); + + /** User-specified properties to be set on the SAX parser */ + private HashMap properties = new HashMap(5); + + /** Whether to use fast parser reconfiguration */ + private boolean fastReconfigure = false; + + /** Whether to try lexical reporting in fast parser reconfiguration */ + private boolean skipNextLexicalReportingConfig = false; + + /** Whether to to try entity expansion in fast parser reconfiguration */ + private boolean skipNextEntityExpandConfig = false; + + /** + * Whether parser reuse is allowed. + *

Default: true

+ */ + private boolean reuseParser = true; + + /** The current SAX parser, if parser reuse has been activated. */ + private XMLReader saxParser = null; + + /** + * Creates a new SAXBuilder which will attempt to first locate + * a parser via JAXP, then will try to use a set of default + * SAX Drivers. The underlying parser will not validate. + */ + public SAXBuilder() { + this(false); + } + + /** + * Creates a new SAXBuilder which will attempt to first locate + * a parser via JAXP, then will try to use a set of default + * SAX Drivers. The underlying parser will validate or not + * according to the given parameter. + * + * @param validate boolean indicating if + * validation should occur. + */ + public SAXBuilder(boolean validate) { + this.validate = validate; + } + + /** + * Creates a new SAXBuilder using the specified SAX parser. + * The underlying parser will not validate. + * + * @param saxDriverClass String name of SAX Driver + * to use for parsing. + */ + public SAXBuilder(String saxDriverClass) { + this(saxDriverClass, false); + } + + /** + * Creates a new SAXBuilder using the specified SAX parser. + * The underlying parser will validate or not + * according to the given parameter. + * + * @param saxDriverClass String name of SAX Driver + * to use for parsing. + * @param validate boolean indicating if + * validation should occur. + */ + public SAXBuilder(String saxDriverClass, boolean validate) { + this.saxDriverClass = saxDriverClass; + this.validate = validate; + } + + /** + * Returns the driver class assigned in the constructor, or null if none. + * + * @return the driver class assigned in the constructor + */ + public String getDriverClass() { + return saxDriverClass; + } + + /** + * Returns the current {@link org.jdom.JDOMFactory} in use. + * @return the factory in use + */ + public JDOMFactory getFactory() { + return factory; + } + + /** + * This sets a custom JDOMFactory for the builder. Use this to build + * the tree with your own subclasses of the JDOM classes. + * + * @param factory JDOMFactory to use + */ + public void setFactory(JDOMFactory factory) { + this.factory = factory; + } + + /** + * Returns whether validation is to be performed during the build. + * + * @return whether validation is to be performed during the build + */ + public boolean getValidation() { + return validate; + } + + /** + * This sets validation for the builder. + * + * @param validate boolean indicating whether validation + * should occur. + */ + public void setValidation(boolean validate) { + this.validate = validate; + } + + /** + * Returns the {@link ErrorHandler} assigned, or null if none. + * @return the ErrorHandler assigned, or null if none + */ + public ErrorHandler getErrorHandler() { + return saxErrorHandler; + } + + /** + * This sets custom ErrorHandler for the Builder. + * + * @param errorHandler ErrorHandler + */ + public void setErrorHandler(ErrorHandler errorHandler) { + saxErrorHandler = errorHandler; + } + + /** + * Returns the {@link EntityResolver} assigned, or null if none. + * + * @return the EntityResolver assigned + */ + public EntityResolver getEntityResolver() { + return saxEntityResolver; + } + + /** + * This sets custom EntityResolver for the Builder. + * + * @param entityResolver EntityResolver + */ + public void setEntityResolver(EntityResolver entityResolver) { + saxEntityResolver = entityResolver; + } + + /** + * Returns the {@link DTDHandler} assigned, or null if none. + * + * @return the DTDHandler assigned + */ + public DTDHandler getDTDHandler() { + return saxDTDHandler; + } + + /** + * This sets custom DTDHandler for the Builder. + * + * @param dtdHandler DTDHandler + */ + public void setDTDHandler(DTDHandler dtdHandler) { + saxDTDHandler = dtdHandler; + } + + /** + * Returns the {@link XMLFilter} used during parsing, or null if none. + * + * @return the XMLFilter used during parsing + */ + public XMLFilter getXMLFilter() { + return saxXMLFilter; + } + + /** + * This sets a custom {@link org.xml.sax.XMLFilter} for the builder. + * + * @param xmlFilter the filter to use + */ + public void setXMLFilter(XMLFilter xmlFilter) { + saxXMLFilter = xmlFilter; + } + + /** + * Returns whether element content whitespace is to be ignored during the + * build. + * + * @return whether element content whitespace is to be ignored during the + * build + */ + public boolean getIgnoringElementContentWhitespace() { + return ignoringWhite; + } + + /** + * Specifies whether or not the parser should elminate whitespace in + * element content (sometimes known as "ignorable whitespace") when + * building the document. Only whitespace which is contained within + * element content that has an element only content model will be + * eliminated (see XML Rec 3.2.1). For this setting to take effect + * requires that validation be turned on. The default value of this + * setting is false. + * + * @param ignoringWhite Whether to ignore ignorable whitespace + */ + public void setIgnoringElementContentWhitespace(boolean ignoringWhite) { + this.ignoringWhite = ignoringWhite; + } + + /** + * Returns whether or not the parser will elminate element content + * containing only whitespace. + * + * @return boolean - whether only whitespace content will + * be ignored during build. + * + * @see #setIgnoringBoundaryWhitespace + */ + public boolean getIgnoringBoundaryWhitespace() { + return ignoringBoundaryWhite; + } + + /** + * Specifies whether or not the parser should elminate boundary whitespace, + * a term that indicates whitespace-only text between element tags. This + * feature is a lot like {@link #setIgnoringElementContentWhitespace(boolean)} + * but this feature is more aggressive and doesn't require validation be + * turned on. The {@link #setIgnoringElementContentWhitespace(boolean)} + * call impacts the SAX parse process while this method impacts the JDOM + * build process, so it can be beneficial to turn both on for efficiency. + * For implementation efficiency, this method actually removes all + * whitespace-only text() nodes. That can, in some cases (like beteween an + * element tag and a comment), include whitespace that isn't just boundary + * whitespace. The default is false. + * + * @param ignoringBoundaryWhite Whether to ignore whitespace-only text + * noes + */ + public void setIgnoringBoundaryWhitespace(boolean ignoringBoundaryWhite) { + this.ignoringBoundaryWhite = ignoringBoundaryWhite; + } + + /** + * Returns whether the contained SAX parser instance is reused across + * multiple parses. The default is true. + * + * @return whether the contained SAX parser instance is reused across + * multiple parses + */ + public boolean getReuseParser() { + return reuseParser; + } + + /** + * Specifies whether this builder shall reuse the same SAX parser + * when performing subsequent parses or allocate a new parser for + * each parse. The default value of this setting is + * true (parser reuse). + *

+ * Note: As SAX parser instances are not thread safe, + * the parser reuse feature should not be used with SAXBuilder instances + * shared among threads.

+ * + * @param reuseParser Whether to reuse the SAX parser. + */ + public void setReuseParser(boolean reuseParser) { + this.reuseParser = reuseParser; + this.saxParser = null; + } + + /** + * Specifies whether this builder will do fast reconfiguration of the + * underlying SAX parser when reuseParser is true. This improves + * performance in cases where SAXBuilders are reused and lots of small + * documents are frequently parsed. This avoids attempting to set features + * on the SAX parser each time build() is called which result in + * SaxNotRecognizedExceptions. This should ONLY be set for builders where + * this specific case is an issue. The default value of this setting is + * false (no fast reconfiguration). If reuseParser is false, + * calling this has no effect. + * + * @param fastReconfigure Whether to do a fast reconfiguration of the parser + */ + public void setFastReconfigure(boolean fastReconfigure) { + if (this.reuseParser) { + this.fastReconfigure = fastReconfigure; + } + } + + /** + * This sets a feature on the SAX parser. See the SAX documentation for . + * more information. + *

+ *

+ * NOTE: SAXBuilder requires that some particular features of the SAX parser be + * set up in certain ways for it to work properly. The list of such features + * may change in the future. Therefore, the use of this method may cause + * parsing to break, and even if it doesn't break anything today it might + * break parsing in a future JDOM version, because what JDOM parsers require + * may change over time. Use with caution. + *

+ * + * @param name The feature name, which is a fully-qualified URI. + * @param value The requested state of the feature (true or false). + */ + public void setFeature(String name, boolean value) { + // Save the specified feature for later. + features.put(name, value ? Boolean.TRUE : Boolean.FALSE); + } + + /** + * This sets a property on the SAX parser. See the SAX documentation for + * more information. + *

+ * NOTE: SAXBuilder requires that some particular properties of the SAX parser be + * set up in certain ways for it to work properly. The list of such properties + * may change in the future. Therefore, the use of this method may cause + * parsing to break, and even if it doesn't break anything today it might + * break parsing in a future JDOM version, because what JDOM parsers require + * may change over time. Use with caution. + *

+ * + * @param name The property name, which is a fully-qualified URI. + * @param value The requested value for the property. + */ + public void setProperty(String name, Object value) { + // Save the specified property for later. + properties.put(name, value); + } + + /** + * This builds a document from the supplied + * input source. + * + * @param in InputSource to read from + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed + */ + public Document build(InputSource in) + throws JDOMException, IOException { + SAXHandler contentHandler = null; + + try { + // Create and configure the content handler. + contentHandler = createContentHandler(); + configureContentHandler(contentHandler); + + XMLReader parser = this.saxParser; + if (parser == null) { + // Create and configure the parser. + parser = createParser(); + + // Install optional filter + if (saxXMLFilter != null) { + // Connect filter chain to parser + XMLFilter root = saxXMLFilter; + while (root.getParent() instanceof XMLFilter) { + root = (XMLFilter)root.getParent(); + } + root.setParent(parser); + + // Read from filter + parser = saxXMLFilter; + } + + // Configure parser + configureParser(parser, contentHandler); + + if (reuseParser) { + this.saxParser = parser; + } + } + else { + // Reset content handler as SAXHandler instances cannot + // be reused + configureParser(parser, contentHandler); + } + + // Parse the document. + parser.parse(in); + + return contentHandler.getDocument(); + } + catch (SAXParseException e) { + Document doc = contentHandler.getDocument(); + if (doc.hasRootElement() == false) { + doc = null; + } + + String systemId = e.getSystemId(); + if (systemId != null) { + throw new JDOMParseException("Error on line " + + e.getLineNumber() + " of document " + systemId, e, doc); + } else { + throw new JDOMParseException("Error on line " + + e.getLineNumber(), e, doc); + } + } + catch (SAXException e) { + throw new JDOMParseException("Error in building: " + + e.getMessage(), e, contentHandler.getDocument()); + } + finally { + // Explicitly nullify the handler to encourage GC + // It's a stack var so this shouldn't be necessary, but it + // seems to help on some JVMs + contentHandler = null; + } + } + + /** + * This creates the SAXHandler that will be used to build the Document. + * + * @return SAXHandler - resultant SAXHandler object. + */ + protected SAXHandler createContentHandler() { + SAXHandler contentHandler = new SAXHandler(factory); + return contentHandler; + } + + /** + * This configures the SAXHandler that will be used to build the Document. + *

+ * The default implementation simply passes through some configuration + * settings that were set on the SAXBuilder: setExpandEntities() and + * setIgnoringElementContentWhitespace(). + *

+ * @param contentHandler The SAXHandler to configure + */ + protected void configureContentHandler(SAXHandler contentHandler) { + // Setup pass through behavior + contentHandler.setExpandEntities(expand); + contentHandler.setIgnoringElementContentWhitespace(ignoringWhite); + contentHandler.setIgnoringBoundaryWhitespace(ignoringBoundaryWhite); + } + + /** + * This creates the XMLReader to be used for reading the XML document. + *

+ * The default behavior is to (1) use the saxDriverClass, if it has been + * set, (2) try to obtain a parser from JAXP, if it is available, and + * (3) if all else fails, use a hard-coded default parser (currently + * the Xerces parser). Subclasses may override this method to determine + * the parser to use in a different way. + *

+ * + * @return XMLReader - resultant XMLReader object. + * @throws org.jdom.JDOMException + */ + protected XMLReader createParser() throws JDOMException { + XMLReader parser = null; + if (saxDriverClass != null) { + // The user knows that they want to use a particular class + try { + parser = XMLReaderFactory.createXMLReader(saxDriverClass); + + // Configure parser + setFeaturesAndProperties(parser, true); + } + catch (SAXException e) { + throw new JDOMException("Could not load " + saxDriverClass, e); + } + } else { + // Try using JAXP... + // Note we need JAXP 1.1, and if JAXP 1.0 is all that's + // available then the getXMLReader call fails and we skip + // to the hard coded default parser + try { + // Get factory class and method. + Class factoryClass = + Class.forName("org.jdom.input.JAXPParserFactory"); + + Method createParser = + factoryClass.getMethod("createParser", + new Class[] { boolean.class, Map.class, Map.class }); + + // Create SAX parser. + parser = (XMLReader)createParser.invoke(null, + new Object[] { validate ? Boolean.TRUE : Boolean.FALSE, + features, properties }); + + // Configure parser + setFeaturesAndProperties(parser, false); + } + catch (JDOMException e) { + throw e; + } + catch (NoClassDefFoundError e) { + // The class loader failed to resolve the dependencies + // of org.jdom.input.JAXPParserFactory. This probably means + // that no JAXP parser is present in its class path. + // => Ignore and try allocating default SAX parser instance. + } + catch (Exception e) { + // Ignore and try allocating default SAX parser instance. + } + } + + // Check to see if we got a parser yet, if not, try to use a + // hard coded default + if (parser == null) { + try { + parser = XMLReaderFactory.createXMLReader(DEFAULT_SAX_DRIVER); + // System.out.println("using default " + DEFAULT_SAX_DRIVER); + saxDriverClass = parser.getClass().getName(); + + // Configure parser + setFeaturesAndProperties(parser, true); + } + catch (SAXException e) { + throw new JDOMException("Could not load default SAX parser: " + + DEFAULT_SAX_DRIVER, e); + } + } + + return parser; + } + + /** + * This configures the XMLReader to be used for reading the XML document. + *

+ * The default implementation sets various options on the given XMLReader, + * such as validation, DTD resolution, entity handlers, etc., according + * to the options that were set (e.g. via setEntityResolver) + * and set various SAX properties and features that are required for JDOM + * internals. These features may change in future releases, so change this + * behavior at your own risk. + *

+ * @param parser + * @param contentHandler + * @throws org.jdom.JDOMException + */ + protected void configureParser(XMLReader parser, SAXHandler contentHandler) + throws JDOMException { + + // Setup SAX handlers. + + parser.setContentHandler(contentHandler); + + if (saxEntityResolver != null) { + parser.setEntityResolver(saxEntityResolver); + } + + if (saxDTDHandler != null) { + parser.setDTDHandler(saxDTDHandler); + } else { + parser.setDTDHandler(contentHandler); + } + + if (saxErrorHandler != null) { + parser.setErrorHandler(saxErrorHandler); + } else { + parser.setErrorHandler(new BuilderErrorHandler()); + } + + // If fastReconfigure is enabled and we failed in the previous attempt + // in configuring lexical reporting, then we skip this step. This + // saves the work of repeated exception handling on each parse. + if (!skipNextLexicalReportingConfig) { + boolean success = false; + + try { + parser.setProperty("http://xml.org/sax/handlers/LexicalHandler", + contentHandler); + success = true; + } catch (SAXNotSupportedException e) { + // No lexical reporting available + } catch (SAXNotRecognizedException e) { + // No lexical reporting available + } + + // Some parsers use alternate property for lexical handling (grr...) + if (!success) { + try { + parser.setProperty("http://xml.org/sax/properties/lexical-handler", + contentHandler); + success = true; + } catch (SAXNotSupportedException e) { + // No lexical reporting available + } catch (SAXNotRecognizedException e) { + // No lexical reporting available + } + } + + // If unable to configure this property and fastReconfigure is + // enabled, then setup to avoid this code path entirely next time. + if (!success && fastReconfigure) { + skipNextLexicalReportingConfig = true; + } + } + + // If fastReconfigure is enabled and we failed in the previous attempt + // in configuring entity expansion, then skip this step. This + // saves the work of repeated exception handling on each parse. + if (!skipNextEntityExpandConfig) { + boolean success = false; + + // Try setting the DeclHandler if entity expansion is off + if (!expand) { + try { + parser.setProperty("http://xml.org/sax/properties/declaration-handler", + contentHandler); + success = true; + } catch (SAXNotSupportedException e) { + // No lexical reporting available + } catch (SAXNotRecognizedException e) { + // No lexical reporting available + } + } + + /* If unable to configure this property and fastReconfigure is + * enabled, then setup to avoid this code path entirely next time. + */ + if (!success && fastReconfigure) { + skipNextEntityExpandConfig = true; + } + } + } + + private void setFeaturesAndProperties(XMLReader parser, + boolean coreFeatures) + throws JDOMException { + // Set any user-specified features on the parser. + Iterator iter = features.keySet().iterator(); + while (iter.hasNext()) { + String name = (String)iter.next(); + Boolean value = (Boolean)features.get(name); + internalSetFeature(parser, name, value.booleanValue(), name); + } + + // Set any user-specified properties on the parser. + iter = properties.keySet().iterator(); + while (iter.hasNext()) { + String name = (String)iter.next(); + internalSetProperty(parser, name, properties.get(name), name); + } + + if (coreFeatures) { + // Set validation. + try { + internalSetFeature(parser, + "http://xml.org/sax/features/validation", + validate, "Validation"); + } catch (JDOMException e) { + // If validation is not supported, and the user is requesting + // that we don't validate, that's fine - don't throw an + // exception. + if (validate) + throw e; + } + + // Setup some namespace features. + internalSetFeature(parser, + "http://xml.org/sax/features/namespaces", + true, "Namespaces"); + internalSetFeature(parser, + "http://xml.org/sax/features/namespace-prefixes", + true, "Namespace prefixes"); + } + + // Set entity expansion + // Note SAXHandler can work regardless of how this is set, but when + // entity expansion it's worth it to try to tell the parser not to + // even bother with external general entities. + // Apparently no parsers yet support this feature. + // XXX It might make sense to setEntityResolver() with a resolver + // that simply ignores external general entities + try { + if (parser.getFeature("http://xml.org/sax/features/external-general-entities") != expand) { + parser.setFeature("http://xml.org/sax/features/external-general-entities", expand); + } + } + catch (SAXNotRecognizedException e) { /* Ignore... */ } + catch (SAXNotSupportedException e) { /* Ignore... */ } + } + + /** + * Tries to set a feature on the parser. If the feature cannot be set, + * throws a JDOMException describing the problem. + */ + private void internalSetFeature(XMLReader parser, String feature, + boolean value, String displayName) throws JDOMException { + try { + parser.setFeature(feature, value); + } catch (SAXNotSupportedException e) { + throw new JDOMException( + displayName + " feature not supported for SAX driver " + parser.getClass().getName()); + } catch (SAXNotRecognizedException e) { + throw new JDOMException( + displayName + " feature not recognized for SAX driver " + parser.getClass().getName()); + } + } + + /** + *

+ * Tries to set a property on the parser. If the property cannot be set, + * throws a JDOMException describing the problem. + *

+ */ + private void internalSetProperty(XMLReader parser, String property, + Object value, String displayName) throws JDOMException { + try { + parser.setProperty(property, value); + } catch (SAXNotSupportedException e) { + throw new JDOMException( + displayName + " property not supported for SAX driver " + parser.getClass().getName()); + } catch (SAXNotRecognizedException e) { + throw new JDOMException( + displayName + " property not recognized for SAX driver " + parser.getClass().getName()); + } + } + + /** + *

+ * This builds a document from the supplied + * input stream. + *

+ * + * @param in InputStream to read from + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed. + */ + public Document build(InputStream in) + throws JDOMException, IOException { + return build(new InputSource(in)); + } + + /** + *

+ * This builds a document from the supplied + * filename. + *

+ * + * @param file File to read from + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed + */ + public Document build(File file) + throws JDOMException, IOException { + try { + URL url = fileToURL(file); + return build(url); + } catch (MalformedURLException e) { + throw new JDOMException("Error in building", e); + } + } + + /** + *

+ * This builds a document from the supplied + * URL. + *

+ * + * @param url URL to read from. + * @return Document - resultant Document object. + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed. + */ + public Document build(URL url) + throws JDOMException, IOException { + String systemID = url.toExternalForm(); + return build(new InputSource(systemID)); + } + + /** + *

+ * This builds a document from the supplied + * input stream. + *

+ * + * @param in InputStream to read from. + * @param systemId base for resolving relative URIs + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed + */ + public Document build(InputStream in, String systemId) + throws JDOMException, IOException { + + InputSource src = new InputSource(in); + src.setSystemId(systemId); + return build(src); + } + + /** + *

+ * This builds a document from the supplied + * Reader. It's the programmer's responsibility to make sure + * the reader matches the encoding of the file. It's often easier + * and safer to use an InputStream rather than a Reader, and to let the + * parser auto-detect the encoding from the XML declaration. + *

+ * + * @param characterStream Reader to read from + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed + */ + public Document build(Reader characterStream) + throws JDOMException, IOException { + return build(new InputSource(characterStream)); + } + + /** + *

+ * This builds a document from the supplied + * Reader. It's the programmer's responsibility to make sure + * the reader matches the encoding of the file. It's often easier + * and safer to use an InputStream rather than a Reader, and to let the + * parser auto-detect the encoding from the XML declaration. + *

+ * + * @param characterStream Reader to read from. + * @param systemId base for resolving relative URIs + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed + */ + public Document build(Reader characterStream, String systemId) + throws JDOMException, IOException { + + InputSource src = new InputSource(characterStream); + src.setSystemId(systemId); + return build(src); + } + + /** + *

+ * This builds a document from the supplied + * URI. + *

+ * @param systemId URI for the input + * @return Document resultant Document object + * @throws JDOMException when errors occur in parsing + * @throws IOException when an I/O error prevents a document + * from being fully parsed + */ + public Document build(String systemId) + throws JDOMException, IOException { + return build(new InputSource(systemId)); + } + +// /** +// * Imitation of File.toURL(), a JDK 1.2 method, reimplemented +// * here to work with JDK 1.1. +// * +// * @see java.io.File +// * +// * @param f the file to convert +// * @return the file path converted to a file: URL +// */ +// protected URL fileToURL(File f) throws MalformedURLException { +// String path = f.getAbsolutePath(); +// if (File.separatorChar != '/') { +// path = path.replace(File.separatorChar, '/'); +// } +// if (!path.startsWith("/")) { +// path = "/" + path; +// } +// if (!path.endsWith("/") && f.isDirectory()) { +// path = path + "/"; +// } +// return new URL("file", "", path); +// } + + /** Custom File.toUrl() implementation to handle special chars in file names + * + * @param file file object whose path will be converted + * @return URL form of the file, with special characters handled + * @throws MalformedURLException if there's a problem constructing a URL + */ + private static URL fileToURL(File file) throws MalformedURLException { + StringBuffer buffer = new StringBuffer(); + String path = file.getAbsolutePath(); + + // Convert non-URL style file separators + if (File.separatorChar != '/') { + path = path.replace(File.separatorChar, '/'); + } + + // Make sure it starts at root + if (!path.startsWith("/")) { + buffer.append('/'); + } + + // Copy, converting URL special characters as we go + int len = path.length(); + for (int i = 0; i < len; i++) { + char c = path.charAt(i); + if (c == ' ') + buffer.append("%20"); + else if (c == '#') + buffer.append("%23"); + else if (c == '%') + buffer.append("%25"); + else if (c == '&') + buffer.append("%26"); + else if (c == ';') + buffer.append("%3B"); + else if (c == '<') + buffer.append("%3C"); + else if (c == '=') + buffer.append("%3D"); + else if (c == '>') + buffer.append("%3E"); + else if (c == '?') + buffer.append("%3F"); + else if (c == '~') + buffer.append("%7E"); + else + buffer.append(c); + } + + // Make sure directories end with slash + if (!path.endsWith("/") && file.isDirectory()) { + buffer.append('/'); + } + + // Return URL + return new URL("file", "", buffer.toString()); + } + + /** + * Returns whether or not entities are being expanded into normal text + * content. + * + * @return whether entities are being expanded + */ + public boolean getExpandEntities() { + return expand; + } + + /** + *

+ * This sets whether or not to expand entities for the builder. + * A true means to expand entities as normal content. A false means to + * leave entities unexpanded as EntityRef objects. The + * default is true. + *

+ *

+ * When this setting is false, the internal DTD subset is retained; when + * this setting is true, the internal DTD subset is not retained. + *

+ *

+ * Note that Xerces (at least up to 1.4.4) has a bug where entities + * in attribute values will be misreported if this flag is turned off, + * resulting in entities to appear within element content. When turning + * entity expansion off either avoid entities in attribute values, or + * use another parser like Crimson. + * http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6111 + *

+ * + * @param expand boolean indicating whether entity expansion + * should occur. + */ + public void setExpandEntities(boolean expand) { + this.expand = expand; + } +} Index: 3rdParty_sources/jdom/org/jdom/input/SAXHandler.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/SAXHandler.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/SAXHandler.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,1129 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.jdom.Attribute; +import org.jdom.DefaultJDOMFactory; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.EntityRef; +import org.jdom.JDOMFactory; +import org.jdom.Namespace; +import org.jdom.Parent; +import org.xml.sax.Attributes; +import org.xml.sax.DTDHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.ext.DeclHandler; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.DefaultHandler; + +/** + * A support class for {@link SAXBuilder}. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Philip Nelson + * @author Bradley S. Huffman + * @author phil@triloggroup.com + */ +public class SAXHandler extends DefaultHandler implements LexicalHandler, + DeclHandler, + DTDHandler { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** Hash table to map SAX attribute type names to JDOM attribute types. */ + private static final Map attrNameToTypeMap = new HashMap(13); + + /** Document object being built */ + private Document document; + + /** Element object being built */ + private Element currentElement; + + /** Indicator of where in the document we are */ + private boolean atRoot; + + /** Indicator of whether we are in the DocType. Note that the DTD consists + * of both the internal subset (inside the tag) and the + * external subset (in a separate .dtd file). */ + private boolean inDTD = false; + + /** Indicator of whether we are in the internal subset */ + private boolean inInternalSubset = false; + + /** Indicator of whether we previously were in a CDATA */ + private boolean previousCDATA = false; + + /** Indicator of whether we are in a CDATA */ + private boolean inCDATA = false; + + /** Indicator of whether we should expand entities */ + private boolean expand = true; + + /** Indicator of whether we are actively suppressing (non-expanding) a + current entity */ + private boolean suppress = false; + + /** How many nested entities we're currently within */ + private int entityDepth = 0; // XXX may not be necessary anymore? + + /** Temporary holder for namespaces that have been declared with + * startPrefixMapping, but are not yet available on the element */ + private List declaredNamespaces; + + /** Temporary holder for the internal subset */ + private StringBuffer internalSubset = new StringBuffer(); + + /** Temporary holder for Text and CDATA */ + private TextBuffer textBuffer = new TextBuffer(); + + /** The external entities defined in this document */ + private Map externalEntities; + + /** The JDOMFactory used for JDOM object creation */ + private JDOMFactory factory; + + /** Whether to ignore ignorable whitespace */ + private boolean ignoringWhite = false; + + /** Whether to ignore text containing all whitespace */ + private boolean ignoringBoundaryWhite = false; + + /** The SAX Locator object provided by the parser */ + private Locator locator; + + /** + * Class initializer: Populate a table to translate SAX attribute + * type names into JDOM attribute type value (integer). + *

+ * Note that all the mappings defined below are compliant with + * the SAX 2.0 specification exception for "ENUMERATION" with is + * specific to Crimson 1.1.X and Xerces 2.0.0-betaX which report + * attributes of enumerated types with a type "ENUMERATION" + * instead of the expected "NMTOKEN". + *

+ *

+ * Note also that Xerces 1.4.X is not SAX 2.0 compliant either + * but handling its case requires + * {@link #getAttributeType specific code}. + *

+ */ + static { + attrNameToTypeMap.put("CDATA", + new Integer(Attribute.CDATA_TYPE)); + attrNameToTypeMap.put("ID", + new Integer(Attribute.ID_TYPE)); + attrNameToTypeMap.put("IDREF", + new Integer(Attribute.IDREF_TYPE)); + attrNameToTypeMap.put("IDREFS", + new Integer(Attribute.IDREFS_TYPE)); + attrNameToTypeMap.put("ENTITY", + new Integer(Attribute.ENTITY_TYPE)); + attrNameToTypeMap.put("ENTITIES", + new Integer(Attribute.ENTITIES_TYPE)); + attrNameToTypeMap.put("NMTOKEN", + new Integer(Attribute.NMTOKEN_TYPE)); + attrNameToTypeMap.put("NMTOKENS", + new Integer(Attribute.NMTOKENS_TYPE)); + attrNameToTypeMap.put("NOTATION", + new Integer(Attribute.NOTATION_TYPE)); + attrNameToTypeMap.put("ENUMERATION", + new Integer(Attribute.ENUMERATED_TYPE)); + } + + /** + * This will create a new SAXHandler that listens to SAX + * events and creates a JDOM Document. The objects will be constructed + * using the default factory. + */ + public SAXHandler() { + this(null); + } + + /** + * This will create a new SAXHandler that listens to SAX + * events and creates a JDOM Document. The objects will be constructed + * using the provided factory. + * + * @param factory JDOMFactory to be used for constructing + * objects + */ + public SAXHandler(JDOMFactory factory) { + if (factory != null) { + this.factory = factory; + } else { + this.factory = new DefaultJDOMFactory(); + } + + atRoot = true; + declaredNamespaces = new ArrayList(); + externalEntities = new HashMap(); + + document = this.factory.document(null); + } + + /** + * Pushes an element onto the tree under construction. Allows subclasses + * to put content under a dummy root element which is useful for building + * content that would otherwise be a non-well formed document. + * + * @param element root element under which content will be built + */ + protected void pushElement(Element element) { + if (atRoot) { + document.setRootElement(element); // XXX should we use a factory call? + atRoot = false; + } + else { + factory.addContent(currentElement, element); + } + currentElement = element; + } + + /** + * Returns the document. Should be called after parsing is complete. + * + * @return Document - Document that was built + */ + public Document getDocument() { + return document; + } + + /** + * Returns the factory used for constructing objects. + * + * @return JDOMFactory - the factory used for + * constructing objects. + * + * @see #SAXHandler(org.jdom.JDOMFactory) + */ + public JDOMFactory getFactory() { + return factory; + } + + /** + * This sets whether or not to expand entities during the build. + * A true means to expand entities as normal content. A false means to + * leave entities unexpanded as EntityRef objects. The + * default is true. + * + * @param expand boolean indicating whether entity expansion + * should occur. + */ + public void setExpandEntities(boolean expand) { + this.expand = expand; + } + + /** + * Returns whether or not entities will be expanded during the + * build. + * + * @return boolean - whether entity expansion + * will occur during build. + * + * @see #setExpandEntities + */ + public boolean getExpandEntities() { + return expand; + } + + /** + * Specifies whether or not the parser should elminate whitespace in + * element content (sometimes known as "ignorable whitespace") when + * building the document. Only whitespace which is contained within + * element content that has an element only content model will be + * eliminated (see XML Rec 3.2.1). For this setting to take effect + * requires that validation be turned on. The default value of this + * setting is false. + * + * @param ignoringWhite Whether to ignore ignorable whitespace + */ + public void setIgnoringElementContentWhitespace(boolean ignoringWhite) { + this.ignoringWhite = ignoringWhite; + } + + /** + * Specifies whether or not the parser should elminate text() nodes + * containing only whitespace when building the document. See + * {@link SAXBuilder#setIgnoringBoundaryWhitespace(boolean)}. + * + * @param ignoringBoundaryWhite Whether to ignore only whitespace content + */ + public void setIgnoringBoundaryWhitespace(boolean ignoringBoundaryWhite) { + this.ignoringBoundaryWhite = ignoringBoundaryWhite; + } + + /** + * Returns whether or not the parser will elminate element content + * containing only whitespace. + * + * @return boolean - whether only whitespace content will + * be ignored during build. + * + * @see #setIgnoringBoundaryWhitespace + */ + public boolean getIgnoringBoundaryWhitespace() { + return ignoringBoundaryWhite; + } + + /** + * Returns whether or not the parser will elminate whitespace in + * element content (sometimes known as "ignorable whitespace") when + * building the document. + * + * @return boolean - whether ignorable whitespace will + * be ignored during build. + * + * @see #setIgnoringElementContentWhitespace + */ + public boolean getIgnoringElementContentWhitespace() { + return ignoringWhite; + } + + public void startDocument() { + if (locator != null) { + document.setBaseURI(locator.getSystemId()); + } + } + + /** + * This is called when the parser encounters an external entity + * declaration. + * + * @param name entity name + * @param publicID public id + * @param systemID system id + * @throws SAXException when things go wrong + */ + public void externalEntityDecl(String name, + String publicID, String systemID) + throws SAXException { + // Store the public and system ids for the name + externalEntities.put(name, new String[]{publicID, systemID}); + + if (!inInternalSubset) return; + + internalSubset.append(" \n"); + } + + /** + * This handles an attribute declaration in the internal subset. + * + * @param eName String element name of attribute + * @param aName String attribute name + * @param type String attribute type + * @param valueDefault String default value of attribute + * @param value String value of attribute + * @throws SAXException + */ + public void attributeDecl(String eName, String aName, String type, + String valueDefault, String value) + throws SAXException { + + if (!inInternalSubset) return; + + internalSubset.append(" \n"); + } + + /** + * Handle an element declaration in a DTD. + * + * @param name String name of element + * @param model String model of the element in DTD syntax + * @throws SAXException + */ + public void elementDecl(String name, String model) throws SAXException { + // Skip elements that come from the external subset + if (!inInternalSubset) return; + + internalSubset.append(" \n"); + } + + /** + * Handle an internal entity declaration in a DTD. + * + * @param name String name of entity + * @param value String value of the entity + * @throws SAXException + */ + public void internalEntityDecl(String name, String value) + throws SAXException { + + // Skip entities that come from the external subset + if (!inInternalSubset) return; + + internalSubset.append(" \n"); + } + + /** + * This will indicate that a processing instruction has been encountered. + * (The XML declaration is not a processing instruction and will not + * be reported.) + * + * @param target String target of PI + * @param data String containing all data sent to the PI. + * This typically looks like one or more attribute value + * pairs. + * @throws SAXException when things go wrong + */ + public void processingInstruction(String target, String data) + throws SAXException { + + if (suppress) return; + + flushCharacters(); + + if (atRoot) { + factory.addContent(document, factory.processingInstruction(target, data)); + } else { + factory.addContent(getCurrentElement(), + factory.processingInstruction(target, data)); + } + } + + /** + * This indicates that an unresolvable entity reference has been + * encountered, normally because the external DTD subset has not been + * read. + * + * @param name String name of entity + * @throws SAXException when things go wrong + */ + public void skippedEntity(String name) + throws SAXException { + + // We don't handle parameter entity references. + if (name.startsWith("%")) return; + + flushCharacters(); + + factory.addContent(getCurrentElement(), factory.entityRef(name)); + } + + /** + * This will add the prefix mapping to the JDOM + * Document object. + * + * @param prefix String namespace prefix. + * @param uri String namespace URI. + */ + public void startPrefixMapping(String prefix, String uri) + throws SAXException { + + if (suppress) return; + + Namespace ns = Namespace.getNamespace(prefix, uri); + declaredNamespaces.add(ns); + } + + /** + * This reports the occurrence of an actual element. It will include + * the element's attributes, with the exception of XML vocabulary + * specific attributes, such as + * xmlns:[namespace prefix] and + * xsi:schemaLocation. + * + * @param namespaceURI String namespace URI this element + * is associated with, or an empty + * String + * @param localName String name of element (with no + * namespace prefix, if one is present) + * @param qName String XML 1.0 version of element name: + * [namespace prefix]:[localName] + * @param atts Attributes list for this element + * @throws SAXException when things go wrong + */ + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) + throws SAXException { + if (suppress) return; + String prefix = ""; + + // If QName is set, then set prefix and local name as necessary + if (!"".equals(qName)) { + int colon = qName.indexOf(':'); + + if (colon > 0) { + prefix = qName.substring(0, colon); + } + + // If local name is not set, try to get it from the QName + if ((localName == null) || (localName.equals(""))) { + localName = qName.substring(colon + 1); + } + } + // At this point either prefix and localName are set correctly or + // there is an error in the parser. + + Namespace namespace = Namespace.getNamespace(prefix, namespaceURI); + Element element = factory.element(localName, namespace); + + // Take leftover declared namespaces and add them to this element's + // map of namespaces + if (declaredNamespaces.size() > 0) { + transferNamespaces(element); + } + + flushCharacters(); + + if (atRoot) { + document.setRootElement(element); // XXX should we use a factory call? + atRoot = false; + } else { + factory.addContent(getCurrentElement(), element); + } + currentElement = element; + + // Handle attributes + for (int i=0, len=atts.getLength(); i 0) { + attPrefix = attQName.substring(0, attColon); + } + + // If localName is not set, try to get it from the QName + if ("".equals(attLocalName)) { + attLocalName = attQName.substring(attColon + 1); + } + } + // At this point either attPrefix and attLocalName are set + // correctly or there is an error in the parser. + + int attType = getAttributeType(atts.getType(i)); + String attValue = atts.getValue(i); + String attURI = atts.getURI(i); + + if ("xmlns".equals(attLocalName) || + "xmlns".equals(attPrefix) || + "http://www.w3.org/2000/xmlns/".equals(attURI)) { + // use the actual Namespace to check too, because, in theory, a + // namespace-aware parser does not need to set the qName unless + // the namespace-prefixes feature is set as well. + continue; + } + + // just one thing to sort out.... + // the prefix for the namespace. + if (!"".equals(attURI) && "".equals(attPrefix)) { + // the localname and qName are the same, but there is a + // Namspace URI. We need to figure out the namespace prefix. + // this is an unusual condition. Currently the only known trigger + // is when there is a fixed/defaulted attribute from a validating + // XMLSchema, and the attribute is in a different namespace + // than the rest of the document, this happens whenever there + // is an attribute definition that has form="qualified". + // + // or the schema sets attributeFormDefault="qualified" + Element p = element; + // We need to ensure that a particular prefix has not been + // overridden at a lower level than what we are expecting. + // track all prefixes to ensure they are not changed lower + // down. + HashSet overrides = new HashSet(); + uploop: do { + // Search up the Element tree looking for a prefixed namespace + // matching our attURI + if (p.getNamespace().getURI().equals(attURI) + && !overrides.contains(p.getNamespacePrefix()) + && !"".equals(element.getNamespace().getPrefix())) { + // we need a prefix. It's impossible to have a namespaced + // attribute if there is no prefix for that attribute. + attPrefix = p.getNamespacePrefix(); + break uploop; + } + overrides.add(p.getNamespacePrefix()); + for (Iterator it = p.getAdditionalNamespaces().iterator(); + it.hasNext(); ) { + Namespace ns = (Namespace)it.next(); + if (!overrides.contains(ns.getPrefix()) + && attURI.equals(ns.getURI())) { + attPrefix = ns.getPrefix(); + break uploop; + } + overrides.add(ns.getPrefix()); + } + for (Iterator it = p.getAttributes().iterator(); + it.hasNext(); ) { + Namespace ns = ((Attribute)it.next()).getNamespace(); + if (!overrides.contains(ns.getPrefix()) + && attURI.equals(ns.getURI())) { + attPrefix = ns.getPrefix(); + break uploop; + } + overrides.add(ns.getPrefix()); + } + p = p.getParentElement(); + } while (p != null); + if ("".equals(attPrefix)) { + // we cannot find a 'prevailing' namespace that has a prefix + // that is for this namespace. + // This basically means that there's an XMLSchema, for the + // DEFAULT namespace, and there's a defaulted/fixed + // attribute definition in the XMLSchema that's targeted + // for this namespace,... but, the user has either not + // declared a prefixed version of the namespace, or has + // re-declared the same prefix at a lower level with a + // different namespace. + // All of these things are possible. + // Create some sort of default prefix. + int cnt = 0; + String base = "attns"; + String pfx = base + cnt; + while (overrides.contains(pfx)) { + cnt++; + pfx = base + cnt; + } + attPrefix = pfx; + } + } + Namespace attNs = Namespace.getNamespace(attPrefix, attURI); + + Attribute attribute = factory.attribute(attLocalName, attValue, + attType, attNs); + factory.setAttribute(element, attribute); + } + } + + /** + * This will take the supplied {@link Element} and + * transfer its namespaces to the global namespace storage. + * + * @param element Element to read namespaces from. + */ + private void transferNamespaces(Element element) { + Iterator i = declaredNamespaces.iterator(); + while (i.hasNext()) { + Namespace ns = (Namespace)i.next(); + if (ns != element.getNamespace()) { + element.addNamespaceDeclaration(ns); + } + } + declaredNamespaces.clear(); + } + + /** + * This will report character data (within an element). + * + * @param ch char[] character array with character data + * @param start int index in array where data starts. + * @param length int length of data. + * @throws SAXException + */ + public void characters(char[] ch, int start, int length) + throws SAXException { + + if (suppress || (length == 0)) + return; + + if (previousCDATA != inCDATA) { + flushCharacters(); + } + + textBuffer.append(ch, start, length); + } + + /** + * Capture ignorable whitespace as text. If + * setIgnoringElementContentWhitespace(true) has been called then this + * method does nothing. + * + * @param ch [] - char array of ignorable whitespace + * @param start int - starting position within array + * @param length int - length of whitespace after start + * @throws SAXException when things go wrong + */ + public void ignorableWhitespace(char[] ch, int start, int length) + throws SAXException { + if (!ignoringWhite) { + characters(ch, start, length); + } + } + + /** + * This will flush any characters from SAX character calls we've + * been buffering. + * + * @throws SAXException when things go wrong + */ + protected void flushCharacters() throws SAXException { + if (ignoringBoundaryWhite) { + if (!textBuffer.isAllWhitespace()) { + flushCharacters(textBuffer.toString()); + } + } + else { + flushCharacters(textBuffer.toString()); + } + textBuffer.clear(); + } + + /** + * Flush the given string into the document. This is a protected method + * so subclassers can control text handling without knowledge of the + * internals of this class. + * + * @param data string to flush + */ + protected void flushCharacters(String data) throws SAXException { + if (data.length() == 0) { + previousCDATA = inCDATA; + return; + } + +/** + * This is commented out because of some problems with + * the inline DTDs that Xerces seems to have. +if (!inDTD) { + if (inEntity) { + getCurrentElement().setContent(factory.text(data)); + } else { + getCurrentElement().addContent(factory.text(data)); +} +*/ + + if (previousCDATA) { + factory.addContent(getCurrentElement(), factory.cdata(data)); + } + else { + factory.addContent(getCurrentElement(), factory.text(data)); + } + + previousCDATA = inCDATA; + } + + /** + * Indicates the end of an element + * (</[element name]>) is reached. Note that + * the parser does not distinguish between empty + * elements and non-empty elements, so this will occur uniformly. + * + * @param namespaceURI String URI of namespace this + * element is associated with + * @param localName String name of element without prefix + * @param qName String name of element in XML 1.0 form + * @throws SAXException when things go wrong + */ + public void endElement(String namespaceURI, String localName, + String qName) throws SAXException { + + if (suppress) return; + + flushCharacters(); + + if (!atRoot) { + Parent p = currentElement.getParent(); + if (p instanceof Document) { + atRoot = true; + } + else { + currentElement = (Element) p; + } + } + else { + throw new SAXException( + "Ill-formed XML document (missing opening tag for " + + localName + ")"); + } + } + + /** + * This will signify that a DTD is being parsed, and can be + * used to ensure that comments and other lexical structures + * in the DTD are not added to the JDOM Document + * object. + * + * @param name String name of element listed in DTD + * @param publicID String public ID of DTD + * @param systemID String system ID of DTD + */ + public void startDTD(String name, String publicID, String systemID) + throws SAXException { + + flushCharacters(); // Is this needed here? + + factory.addContent(document, factory.docType(name, publicID, systemID)); + inDTD = true; + inInternalSubset = true; + } + + /** + * This signifies that the reading of the DTD is complete. + * + * @throws SAXException + */ + public void endDTD() throws SAXException { + + document.getDocType().setInternalSubset(internalSubset.toString()); + inDTD = false; + inInternalSubset = false; + } + + public void startEntity(String name) throws SAXException { + entityDepth++; + + if (expand || entityDepth > 1) { + // Short cut out if we're expanding or if we're nested + return; + } + + // A "[dtd]" entity indicates the beginning of the external subset + if (name.equals("[dtd]")) { + inInternalSubset = false; + return; + } + + // Ignore DTD references, and translate the standard 5 + if ((!inDTD) && + (!name.equals("amp")) && + (!name.equals("lt")) && + (!name.equals("gt")) && + (!name.equals("apos")) && + (!name.equals("quot"))) { + + if (!expand) { + String pub = null; + String sys = null; + String[] ids = (String[]) externalEntities.get(name); + if (ids != null) { + pub = ids[0]; // may be null, that's OK + sys = ids[1]; // may be null, that's OK + } + /** + * if no current element, this entity belongs to an attribute + * in these cases, it is an error on the part of the parser + * to call startEntity but this will help in some cases. + * See org/xml/sax/ext/LexicalHandler.html#startEntity(java.lang.String) + * for more information + */ + if (!atRoot) { + flushCharacters(); + EntityRef entity = factory.entityRef(name, pub, sys); + + // no way to tell if the entity was from an attribute or element so just assume element + factory.addContent(getCurrentElement(), entity); + } + suppress = true; + } + } + } + + public void endEntity(String name) throws SAXException { + entityDepth--; + if (entityDepth == 0) { + // No way are we suppressing if not in an entity, + // regardless of the "expand" value + suppress = false; + } + if (name.equals("[dtd]")) { + inInternalSubset = true; + } + } + + /** + * Report a CDATA section + * + * @throws SAXException + */ + public void startCDATA() throws SAXException { + if (suppress) return; + + inCDATA = true; + } + + /** + * Report a CDATA section + */ + public void endCDATA() throws SAXException { + if (suppress) return; + + previousCDATA = true; + inCDATA = false; + } + + /** + * This reports that a comments is parsed. If not in the + * DTD, this comment is added to the current JDOM + * Element, or the Document itself + * if at that level. + * + * @param ch ch[] array of comment characters. + * @param start int index to start reading from. + * @param length int length of data. + * @throws SAXException + */ + public void comment(char[] ch, int start, int length) + throws SAXException { + + if (suppress) return; + + flushCharacters(); + + String commentText = new String(ch, start, length); + if (inDTD && inInternalSubset && (expand == false)) { + internalSubset.append(" \n"); + return; + } + if ((!inDTD) && (!commentText.equals(""))) { + if (atRoot) { + factory.addContent(document, factory.comment(commentText)); + } else { + factory.addContent(getCurrentElement(), factory.comment(commentText)); + } + } + } + + /** + * Handle the declaration of a Notation in a DTD + * + * @param name name of the notation + * @param publicID the public ID of the notation + * @param systemID the system ID of the notation + */ + public void notationDecl(String name, String publicID, String systemID) + throws SAXException { + + if (!inInternalSubset) return; + + internalSubset.append(" \n"); + } + + /** + * Handler for unparsed entity declarations in the DTD + * + * @param name String of the unparsed entity decl + * @param publicID String of the unparsed entity decl + * @param systemID String of the unparsed entity decl + * @param notationName String of the unparsed entity decl + */ + public void unparsedEntityDecl(String name, String publicID, + String systemID, String notationName) + throws SAXException { + + if (!inInternalSubset) return; + + internalSubset.append(" \n"); + } + + /** + * Appends an external ID to the internal subset buffer. Either publicID + * or systemID may be null, but not both. + * + * @param publicID the public ID + * @param systemID the system ID + */ + private void appendExternalId(String publicID, String systemID) { + if (publicID != null) { + internalSubset.append(" PUBLIC \"") + .append(publicID) + .append('\"'); + } + if (systemID != null) { + if (publicID == null) { + internalSubset.append(" SYSTEM "); + } + else { + internalSubset.append(' '); + } + internalSubset.append('\"') + .append(systemID) + .append('\"'); + } + } + + /** + * Returns the being-parsed element. + * + * @return Element - element being built. + * @throws SAXException + */ + public Element getCurrentElement() throws SAXException { + if (currentElement == null) { + throw new SAXException( + "Ill-formed XML document (multiple root elements detected)"); + } + return currentElement; + } + + /** + * Returns the the JDOM Attribute type value from the SAX 2.0 + * attribute type string provided by the parser. + * + * @param typeName String the SAX 2.0 attribute + * type string. + * + * @return int the JDOM attribute type. + * + * @see Attribute#setAttributeType + * @see Attributes#getType + */ + private static int getAttributeType(String typeName) { + Integer type = (Integer)(attrNameToTypeMap.get(typeName)); + if (type == null) { + if (typeName != null && typeName.length() > 0 && + typeName.charAt(0) == '(') { + // Xerces 1.4.X reports attributes of enumerated type with + // a type string equals to the enumeration definition, i.e. + // starting with a parenthesis. + return Attribute.ENUMERATED_TYPE; + } + else { + return Attribute.UNDECLARED_TYPE; + } + } else { + return type.intValue(); + } + } + + /** + * Receives an object for locating the origin of SAX document + * events. This method is invoked by the SAX parser. + *

+ * {@link org.jdom.JDOMFactory} implementations can use the + * {@link #getDocumentLocator} method to get access to the + * {@link Locator} during parse. + *

+ * + * @param locator Locator an object that can return + * the location of any SAX document event. + */ + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + /** + * Provides access to the {@link Locator} object provided by the + * SAX parser. + * + * @return Locator an object that can return + * the location of any SAX document event. + */ + public Locator getDocumentLocator() { + return locator; + } +} Index: 3rdParty_sources/jdom/org/jdom/input/TextBuffer.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/TextBuffer.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/TextBuffer.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,186 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.input; + +import org.jdom.*; + +/** + * A non-public utility class similar to StringBuffer but optimized for XML + * parsing where the common case is that you get only one chunk of characters + * per text section. TextBuffer stores the first chunk of characters in a + * String, which can just be returned directly if no second chunk is received. + * Subsequent chunks are stored in a supplemental char array (like StringBuffer + * uses). In this case, the returned text will be the first String chunk, + * concatenated with the subsequent chunks stored in the char array. This + * provides optimal performance in the common case, while still providing very + * good performance in the uncommon case. Furthermore, avoiding StringBuffer + * means that no extra unused char array space will be kept around after parsing + * is through. + * + * @version $Revision$, $Date$ + * @author Bradley S. Huffman + * @author Alex Rosen + */ +class TextBuffer { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The first part of the text value (the "prefix"). If null, the + * text value is the empty string. */ + private String prefixString; + + /** The rest of the text value (the "suffix"). Only the first + * code>arraySize
characters are valid. */ + private char[] array; + + /** The size of the rest of the text value. If zero, then only + * code>prefixString contains the text value. */ + private int arraySize; + + /** Constructor */ + TextBuffer() { + array = new char[4096]; // initial capacity + arraySize = 0; + } + + /** Append the specified text to the text value of this buffer. */ + void append(char[] source, int start, int count) { + if (prefixString == null) { + // This is the first chunk, so we'll store it in the prefix string + prefixString = new String(source, start, count); + } + else { + // This is a subsequent chunk, so we'll add it to the char array + ensureCapacity(arraySize + count); + System.arraycopy(source, start, array, arraySize, count); + arraySize += count; + } + } + + /** Returns the size of the text value. */ + int size() { + if (prefixString == null) { + return 0; + } + else { + return prefixString.length() + arraySize; + } + } + + /** Clears the text value and prepares the TextBuffer for reuse. */ + void clear() { + arraySize = 0; + prefixString = null; + } + + boolean isAllWhitespace() { + if ((prefixString == null) || (prefixString.length() == 0)) { + return true; + } + + int size = prefixString.length(); + for(int i = 0; i < size; i++) { + if ( !Verifier.isXMLWhitespace(prefixString.charAt(i))) { + return false; + } + } + + for(int i = 0; i < arraySize; i++) { + if ( !Verifier.isXMLWhitespace(array[i])) { + return false; + } + } + return true; + } + + /** Returns the text value stored in the buffer. */ + public String toString() { + if (prefixString == null) { + return ""; + } + + String str = ""; + if (arraySize == 0) { + // Char array is empty, so the text value is just prefixString. + str = prefixString; + } + else { + // Char array is not empty, so the text value is prefixString + // plus the char array. + str = new StringBuffer(prefixString.length() + arraySize) + .append(prefixString) + .append(array, 0, arraySize) + .toString(); + } + return str; + } + + // Ensure that the char array has room for at least "csize" characters. + private void ensureCapacity(int csize) { + int capacity = array.length; + if (csize > capacity) { + char[] old = array; + int nsize = capacity; + while (csize > nsize) { + nsize += (capacity/2); + } + array = new char[nsize]; + System.arraycopy(old, 0, array, 0, arraySize); + } + } +} Index: 3rdParty_sources/jdom/org/jdom/input/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/input/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/input/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,10 @@ + + +Classes to build JDOM documents from various sources. The most common builder +class is SAXBuilder which constructs a JDOM document using a SAX parser and +can pull content from files, streams, sockets, readers, and so on. It can use +any underlying SAX parser to handle the parsing chores. SAXHandler provides +support for SAXBuilder. DOMBuilder lets you build from a pre-existing DOM +tree. + + Index: 3rdParty_sources/jdom/org/jdom/output/DOMOutputter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/DOMOutputter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/DOMOutputter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,454 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + + +package org.jdom.output; + +import java.util.*; + +import org.jdom.*; +import org.jdom.adapters.*; + + +/** + * Outputs a JDOM {@link org.jdom.Document org.jdom.Document} as a DOM {@link + * org.w3c.dom.Document org.w3c.dom.Document}. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Matthew Merlo + * @author Dan Schaffer + * @author Yusuf Goolamabbas + * @author Bradley S. Huffman + */ +public class DOMOutputter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** Default adapter class */ + private static final String DEFAULT_ADAPTER_CLASS = + "org.jdom.adapters.XercesDOMAdapter"; + + /** Adapter to use for interfacing with the DOM implementation */ + private String adapterClass; + + /** Output a DOM with namespaces but just the empty namespace */ + private boolean forceNamespaceAware; + + /** + * This creates a new DOMOutputter which will attempt to first locate + * a DOM implementation to use via JAXP, and if JAXP does not exist or + * there's a problem, will fall back to the default parser. + */ + public DOMOutputter() { + // nothing + } + + /** + * This creates a new DOMOutputter using the specified DOMAdapter + * implementation as a way to choose the underlying parser. + * + * @param adapterClass String name of class + * to use for DOM output + */ + public DOMOutputter(String adapterClass) { + this.adapterClass = adapterClass; + } + + /** + * Controls how NO_NAMESPACE nodes are handeled. If true the outputter + * always creates a namespace aware DOM. + * @param flag + */ + public void setForceNamespaceAware(boolean flag) { + this.forceNamespaceAware = flag; + } + + /** + * Returns whether DOMs will be constructed with namespaces even when + * the source document has elements all in the empty namespace. + * @return the forceNamespaceAware flag value + */ + public boolean getForceNamespaceAware() { + return forceNamespaceAware; + } + + /** + * This converts the JDOM Document parameter to a + * DOM Document, returning the DOM version. The DOM implementation + * is the one chosen in the constructor. + * + * @param document Document to output. + * @return an org.w3c.dom.Document version + */ + public org.w3c.dom.Document output(Document document) + throws JDOMException { + NamespaceStack namespaces = new NamespaceStack(); + + org.w3c.dom.Document domDoc = null; + try { + // Assign DOCTYPE during construction + DocType dt = document.getDocType(); + domDoc = createDOMDocument(dt); + + // Check for existing root element which may have been + // automatically added by the DOM Document construction + // (if there is a DocType) + org.w3c.dom.Element autoroot = domDoc.getDocumentElement(); + if (autoroot != null) { + // remove the automatically added root element. + // If we leave this attached it will/may mess up the order + // of content on the DOM Document node. + domDoc.removeChild(autoroot); + } + + // Add content + Iterator itr = document.getContent().iterator(); + while (itr.hasNext()) { + Object node = itr.next(); + + if (node instanceof Element) { + org.w3c.dom.Element domElement = + output((Element) node, domDoc, namespaces); + domDoc.appendChild(domElement); // normal case + } + else if (node instanceof Comment) { + Comment comment = (Comment) node; + org.w3c.dom.Comment domComment = + domDoc.createComment(comment.getText()); + domDoc.appendChild(domComment); + } + else if (node instanceof ProcessingInstruction) { + ProcessingInstruction pi = + (ProcessingInstruction) node; + org.w3c.dom.ProcessingInstruction domPI = + domDoc.createProcessingInstruction( + pi.getTarget(), pi.getData()); + domDoc.appendChild(domPI); + } + else if (node instanceof DocType) { + // We already dealt with the DocType above + } + else { + throw new JDOMException( + "Document contained top-level content with type:" + + node.getClass().getName()); + } + } + } + catch (Throwable e) { + throw new JDOMException("Exception outputting Document", e); + } + + return domDoc; + } + + private org.w3c.dom.Document createDOMDocument(DocType dt) + throws JDOMException { + if (adapterClass != null) { + // The user knows that they want to use a particular impl + try { + DOMAdapter adapter = + (DOMAdapter)Class.forName(adapterClass).newInstance(); + // System.out.println("using specific " + adapterClass); + return adapter.createDocument(dt); + } + catch (ClassNotFoundException e) { + // e.printStackTrace(); + } + catch (IllegalAccessException e) { + // e.printStackTrace(); + } + catch (InstantiationException e) { + // e.printStackTrace(); + } + } + else { + // Try using JAXP... + try { + DOMAdapter adapter = + (DOMAdapter)Class.forName( + "org.jdom.adapters.JAXPDOMAdapter").newInstance(); + // System.out.println("using JAXP"); + return adapter.createDocument(dt); + } + catch (ClassNotFoundException e) { + // e.printStackTrace(); + } + catch (IllegalAccessException e) { + // e.printStackTrace(); + } + catch (InstantiationException e) { + // e.printStackTrace(); + } + } + + // If no DOM doc yet, try to use a hard coded default + try { + DOMAdapter adapter = (DOMAdapter) + Class.forName(DEFAULT_ADAPTER_CLASS).newInstance(); + return adapter.createDocument(dt); + // System.out.println("Using default " + + // DEFAULT_ADAPTER_CLASS); + } + catch (ClassNotFoundException e) { + // e.printStackTrace(); + } + catch (IllegalAccessException e) { + // e.printStackTrace(); + } + catch (InstantiationException e) { + // e.printStackTrace(); + } + + throw new JDOMException("No JAXP or default parser available"); + + } + + private org.w3c.dom.Element output(Element element, + org.w3c.dom.Document domDoc, + NamespaceStack namespaces) + throws JDOMException { + try { + int previouslyDeclaredNamespaces = namespaces.size(); + + org.w3c.dom.Element domElement = null; + if (element.getNamespace() == Namespace.NO_NAMESPACE) { + // No namespace, use createElement + domElement = forceNamespaceAware ? + domDoc.createElementNS(null, element.getQualifiedName()) + : domDoc.createElement(element.getQualifiedName()); } + else { + domElement = domDoc.createElementNS( + element.getNamespaceURI(), + element.getQualifiedName()); + } + + // Add namespace attributes, beginning with the element's own + // Do this only if it's not the XML namespace and it's + // not the NO_NAMESPACE with the prefix "" not yet mapped + // (we do output xmlns="" if the "" prefix was already used + // and we need to reclaim it for the NO_NAMESPACE) + Namespace ns = element.getNamespace(); + if (ns != Namespace.XML_NAMESPACE && + !(ns == Namespace.NO_NAMESPACE && + namespaces.getURI("") == null)) { + String prefix = ns.getPrefix(); + String uri = namespaces.getURI(prefix); + if (!ns.getURI().equals(uri)) { // output a new namespace decl + namespaces.push(ns); + String attrName = getXmlnsTagFor(ns); + domElement.setAttribute(attrName, ns.getURI()); + } + } + + // Add additional namespaces also + Iterator itr = element.getAdditionalNamespaces().iterator(); + while (itr.hasNext()) { + Namespace additional = (Namespace)itr.next(); + String prefix = additional.getPrefix(); + String uri = namespaces.getURI(prefix); + if (!additional.getURI().equals(uri)) { + String attrName = getXmlnsTagFor(additional); + domElement.setAttribute(attrName, additional.getURI()); + namespaces.push(additional); + } + } + + // Add attributes to the DOM element + itr = element.getAttributes().iterator(); + while (itr.hasNext()) { + Attribute attribute = (Attribute) itr.next(); + domElement.setAttributeNode(output(attribute, domDoc)); + Namespace ns1 = attribute.getNamespace(); + if ((ns1 != Namespace.NO_NAMESPACE) && + (ns1 != Namespace.XML_NAMESPACE)) { + String prefix = ns1.getPrefix(); + String uri = namespaces.getURI(prefix); + if (!ns1.getURI().equals(uri)) { // output a new decl + String attrName = getXmlnsTagFor(ns1); + domElement.setAttribute(attrName, ns1.getURI()); + namespaces.push(ns1); + } + } + // Crimson doesn't like setAttributeNS() for non-NS attribs + if (attribute.getNamespace() == Namespace.NO_NAMESPACE) { + // No namespace, use setAttribute + if (forceNamespaceAware) { + domElement.setAttributeNS(null, + attribute.getQualifiedName(), + attribute.getValue()); + } else { + domElement.setAttribute(attribute.getQualifiedName(), + attribute.getValue()); + } + } + else { + domElement.setAttributeNS(attribute.getNamespaceURI(), + attribute.getQualifiedName(), + attribute.getValue()); + } + } + + // Add content to the DOM element + itr = element.getContent().iterator(); + while (itr.hasNext()) { + Object node = itr.next(); + + if (node instanceof Element) { + Element e = (Element) node; + org.w3c.dom.Element domElt = output(e, domDoc, namespaces); + domElement.appendChild(domElt); + } + else if (node instanceof String) { + String str = (String) node; + org.w3c.dom.Text domText = domDoc.createTextNode(str); + domElement.appendChild(domText); + } + else if (node instanceof CDATA) { + CDATA cdata = (CDATA) node; + org.w3c.dom.CDATASection domCdata = + domDoc.createCDATASection(cdata.getText()); + domElement.appendChild(domCdata); + } + else if (node instanceof Text) { + Text text = (Text) node; + org.w3c.dom.Text domText = + domDoc.createTextNode(text.getText()); + domElement.appendChild(domText); + } + else if (node instanceof Comment) { + Comment comment = (Comment) node; + org.w3c.dom.Comment domComment = + domDoc.createComment(comment.getText()); + domElement.appendChild(domComment); + } + else if (node instanceof ProcessingInstruction) { + ProcessingInstruction pi = + (ProcessingInstruction) node; + org.w3c.dom.ProcessingInstruction domPI = + domDoc.createProcessingInstruction( + pi.getTarget(), pi.getData()); + domElement.appendChild(domPI); + } + else if (node instanceof EntityRef) { + EntityRef entity = (EntityRef) node; + org.w3c.dom.EntityReference domEntity = + domDoc.createEntityReference(entity.getName()); + domElement.appendChild(domEntity); + } + else { + throw new JDOMException( + "Element contained content with type:" + + node.getClass().getName()); + } + } + + // Remove declared namespaces from stack + while (namespaces.size() > previouslyDeclaredNamespaces) { + namespaces.pop(); + } + + return domElement; + } + catch (Exception e) { + throw new JDOMException("Exception outputting Element " + + element.getQualifiedName(), e); + } + } + + private org.w3c.dom.Attr output(Attribute attribute, + org.w3c.dom.Document domDoc) + throws JDOMException { + org.w3c.dom.Attr domAttr = null; + try { + if (attribute.getNamespace() == Namespace.NO_NAMESPACE) { + // No namespace, use createAttribute + if (forceNamespaceAware) { + domAttr = domDoc.createAttributeNS(null, attribute.getQualifiedName()); + } else { + domAttr = domDoc.createAttribute(attribute.getQualifiedName()); + } + } + else { + domAttr = domDoc.createAttributeNS(attribute.getNamespaceURI(), + attribute.getQualifiedName()); + } + domAttr.setValue(attribute.getValue()); + } catch (Exception e) { + throw new JDOMException("Exception outputting Attribute " + + attribute.getQualifiedName(), e); + } + return domAttr; + } + + /** + * This will handle adding any {@link Namespace} + * attributes to the DOM tree. + * + * @param ns Namespace to add definition of + */ + private static String getXmlnsTagFor(Namespace ns) { + String attrName = "xmlns"; + if (!ns.getPrefix().equals("")) { + attrName += ":"; + attrName += ns.getPrefix(); + } + return attrName; + } +} Index: 3rdParty_sources/jdom/org/jdom/output/EscapeStrategy.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/EscapeStrategy.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/EscapeStrategy.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,76 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.output; + +/** + * Logic to determine which characters should be formatted as character + * entities. + * + * @version $Revision$, $Date$ + * @author Alex Rosen + * @author Bradley S. Huffman + * @author Jason Hunter + */ +public interface EscapeStrategy { + + /** + * Test whether the supplied character should be formatted literally + * or as a character entity. + */ + public boolean shouldEscape(char ch); +} + Index: 3rdParty_sources/jdom/org/jdom/output/Format.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/Format.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/Format.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,615 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.output; + +import java.lang.reflect.Method; +import org.jdom.Verifier; + +/** + * Class to encapsulate XMLOutputter format options. + * Typical users can use the standard format configurations obtained by + * {@link #getRawFormat} (no whitespace changes), + * {@link #getPrettyFormat} (whitespace beautification), and + * {@link #getCompactFormat} (whitespace normalization). + *

+ * Several modes are available to effect the way textual content is printed. + * See the documentation for {@link TextMode} for details. + * + * @version $Revision$, $Date$ + * @author Jason Hunter + */ +public class Format implements Cloneable { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * Returns a new Format object that performs no whitespace changes, uses + * the UTF-8 encoding, doesn't expand empty elements, includes the + * declaration and encoding, and uses the default entity escape strategy. + * Tweaks can be made to the returned Format instance without affecting + * other instances. + + * @return a Format with no whitespace changes + */ + public static Format getRawFormat() { + return new Format(); + } + + /** + * Returns a new Format object that performs whitespace beautification with + * 2-space indents, uses the UTF-8 encoding, doesn't expand empty elements, + * includes the declaration and encoding, and uses the default entity + * escape strategy. + * Tweaks can be made to the returned Format instance without affecting + * other instances. + * + * @return a Format with whitespace beautification + */ + public static Format getPrettyFormat() { + Format f = new Format(); + f.setIndent(STANDARD_INDENT); + f.setTextMode(TextMode.TRIM); + return f; + } + + /** + * Returns a new Format object that performs whitespace normalization, uses + * the UTF-8 encoding, doesn't expand empty elements, includes the + * declaration and encoding, and uses the default entity escape strategy. + * Tweaks can be made to the returned Format instance without affecting + * other instances. + * + * @return a Format with whitespace normalization + */ + public static Format getCompactFormat() { + Format f = new Format(); + f.setTextMode(TextMode.NORMALIZE); + return f; + } + + /** standard value to indent by, if we are indenting */ + private static final String STANDARD_INDENT = " "; + + /** standard string with which to end a line */ + private static final String STANDARD_LINE_SEPARATOR = "\r\n"; + + /** standard encoding */ + private static final String STANDARD_ENCODING = "UTF-8"; + + + /** The default indent is no spaces (as original document) */ + String indent = null; + + /** New line separator */ + String lineSeparator = STANDARD_LINE_SEPARATOR; + + /** The encoding format */ + String encoding = STANDARD_ENCODING; + + /** Whether or not to output the XML declaration + * - default is false */ + boolean omitDeclaration = false; + + /** Whether or not to output the encoding in the XML declaration + * - default is false */ + boolean omitEncoding = false; + + /** Whether or not to expand empty elements to + * <tagName></tagName> - default is false */ + boolean expandEmptyElements = false; + + /** Whether TrAX output escaping disabling/enabling PIs are ignored + * or processed - default is false */ + boolean ignoreTrAXEscapingPIs = false; + + /** text handling mode */ + TextMode mode = TextMode.PRESERVE; + + /** entity escape logic */ + EscapeStrategy escapeStrategy = new DefaultEscapeStrategy(encoding); + + /** + * Creates a new Format instance with default (raw) behavior. + */ + private Format() { } + + /** + * Sets the {@link EscapeStrategy} to use for character escaping. + * + * @param strategy the EscapeStrategy to use + * @return a pointer to this Format for chaining + */ + public Format setEscapeStrategy(EscapeStrategy strategy) { + escapeStrategy = strategy; + return this; + } + + /** + * Returns the current escape strategy + * + * @return the current escape strategy + */ + public EscapeStrategy getEscapeStrategy() { + return escapeStrategy; + } + + /** + * This will set the newline separator (lineSeparator). + * The default is \r\n. To make it output + * the system default line ending string, call + * setLineSeparator(System.getProperty("line.separator")). + * + *

+ * To output "UNIX-style" documents, call + * setLineSeparator("\n"). To output "Mac-style" + * documents, call setLineSeparator("\r"). DOS-style + * documents use CR-LF ("\r\n"), which is the default. + *

+ * + *

+ * Note that this only applies to newlines generated by the + * outputter. If you parse an XML document that contains newlines + * embedded inside a text node, and you do not set TextMode.NORMALIZE, + * then the newlines will be output + * verbatim, as "\n" which is how parsers normalize them. + *

+ * + *

+ * If the format's "indent" property is null (as is the default + * for the Raw and Compact formats), then this value only effects the + * newlines written after the declaration and doctype. + *

+ * + * @see #setTextMode + * + * @param separator String line separator to use. + * @return a pointer to this Format for chaining + */ + public Format setLineSeparator(String separator) { + this.lineSeparator = separator; + return this; + } + + /** + * Returns the current line separator. + * + * @return the current line separator + */ + public String getLineSeparator() { + return lineSeparator; + } + + /** + * This will set whether the XML declaration + * (<?xml version="1.0" + * encoding="UTF-8"?>) + * includes the encoding of the document. It is common to omit + * this in uses such as WML and other wireless device protocols. + * + * @param omitEncoding boolean indicating whether or not + * the XML declaration should indicate the document encoding. + * @return a pointer to this Format for chaining + */ + public Format setOmitEncoding(boolean omitEncoding) { + this.omitEncoding = omitEncoding; + return this; + } + + /** + * Returns whether the XML declaration encoding will be omitted. + * + * @return whether the XML declaration encoding will be omitted + */ + public boolean getOmitEncoding() { + return omitEncoding; + } + + /** + * This will set whether the XML declaration + * (<?xml version="1.0"?gt;) + * will be omitted or not. It is common to omit this in uses such + * as SOAP and XML-RPC calls. + * + * @param omitDeclaration boolean indicating whether or not + * the XML declaration should be omitted. + * @return a pointer to this Format for chaining + */ + public Format setOmitDeclaration(boolean omitDeclaration) { + this.omitDeclaration = omitDeclaration; + return this; + } + + /** + * Returns whether the XML declaration will be omitted. + * + * @return whether the XML declaration will be omitted + */ + public boolean getOmitDeclaration() { + return omitDeclaration; + } + + /** + * This will set whether empty elements are expanded from + * <tagName/> to + * <tagName></tagName>. + * + * @param expandEmptyElements boolean indicating whether or not + * empty elements should be expanded. + * @return a pointer to this Format for chaining + */ + public Format setExpandEmptyElements(boolean expandEmptyElements) { + this.expandEmptyElements = expandEmptyElements; + return this; + } + + /** + * Returns whether empty elements are expanded. + * + * @return whether empty elements are expanded + */ + public boolean getExpandEmptyElements() { + return expandEmptyElements; + } + + /** + * This will set whether JAXP TrAX processing instructions for + * disabling/enabling output escaping are ignored. Disabling + * output escaping allows using XML text as element content and + * outputing it verbatim, i.e. as element children would be. + *

+ * When processed, these processing instructions are removed from + * the generated XML text and control whether the element text + * content is output verbatim or with escaping of the pre-defined + * entities in XML 1.0. The text to be output verbatim shall be + * surrounded by the + * <?javax.xml.transform.disable-output-escaping ?> + * and <?javax.xml.transform.enable-output-escaping ?> + * PIs.

+ *

+ * When ignored, the processing instructions are present in the + * generated XML text and the pre-defined entities in XML 1.0 are + * escaped. + *

+ * Default: false.

+ * + * @param ignoreTrAXEscapingPIs boolean indicating + * whether or not TrAX ouput escaping PIs are ignored. + * + * @see javax.xml.transform.Result#PI_ENABLE_OUTPUT_ESCAPING + * @see javax.xml.transform.Result#PI_DISABLE_OUTPUT_ESCAPING + */ + public void setIgnoreTrAXEscapingPIs(boolean ignoreTrAXEscapingPIs) { + this.ignoreTrAXEscapingPIs = ignoreTrAXEscapingPIs; + } + + /** + * Returns whether JAXP TrAX processing instructions for + * disabling/enabling output escaping are ignored. + * + * @return whether or not TrAX ouput escaping PIs are ignored. + */ + public boolean getIgnoreTrAXEscapingPIs() { + return ignoreTrAXEscapingPIs; + } + + /** + * This sets the text output style. Options are available as static + * {@link TextMode} instances. The default is {@link TextMode#PRESERVE}. + * + * @return a pointer to this Format for chaining + */ + public Format setTextMode(Format.TextMode mode) { + this.mode = mode; + return this; + } + + /** + * Returns the current text output style. + * + * @return the current text output style + */ + public Format.TextMode getTextMode() { + return mode; + } + + /** + * This will set the indent String to use; this + * is usually a String of empty spaces. If you pass + * the empty string (""), then no indentation will happen but newlines + * will still be generated. Passing null will result in no indentation + * and no newlines generated. Default: none (null) + * + * @param indent String to use for indentation. + * @return a pointer to this Format for chaining + */ + public Format setIndent(String indent) { + this.indent = indent; + return this; + } + + /** + * Returns the indent string in use. + * + * @return the indent string in use + */ + public String getIndent() { + return indent; + } + + /** + * Sets the output encoding. The name should be an accepted XML + * encoding. + * + * @param encoding the encoding format. Use XML-style names like + * "UTF-8" or "ISO-8859-1" or "US-ASCII" + * @return a pointer to this Format for chaining + */ + public Format setEncoding(String encoding) { + this.encoding = encoding; + escapeStrategy = new DefaultEscapeStrategy(encoding); + return this; + } + + /** + * Returns the configured output encoding. + * + * @return the output encoding + */ + public String getEncoding() { + return encoding; + } + + public Object clone() { + Format format = null; + + try { + format = (Format) super.clone(); + } + catch (CloneNotSupportedException ce) { + } + + return format; + } + + + /** + * Handle common charsets quickly and easily. Use reflection + * to query the JDK 1.4 CharsetEncoder class for unknown charsets. + * If JDK 1.4 isn't around, default to no special encoding. + */ + class DefaultEscapeStrategy implements EscapeStrategy { + private int bits; + Object encoder; + Method canEncode; + + public DefaultEscapeStrategy(String encoding) { + if ("UTF-8".equalsIgnoreCase(encoding) || + "UTF-16".equalsIgnoreCase(encoding)) { + bits = 16; + } + else if ("ISO-8859-1".equalsIgnoreCase(encoding) || + "Latin1".equalsIgnoreCase(encoding)) { + bits = 8; + } + else if ("US-ASCII".equalsIgnoreCase(encoding) || + "ASCII".equalsIgnoreCase(encoding)) { + bits = 7; + } + else { + bits = 0; + //encoder = Charset.forName(encoding).newEncoder(); + try { + Class charsetClass = Class.forName("java.nio.charset.Charset"); + Class encoderClass = Class.forName("java.nio.charset.CharsetEncoder"); + Method forName = charsetClass.getMethod("forName", new Class[]{String.class}); + Object charsetObj = forName.invoke(null, new Object[]{encoding}); + Method newEncoder = charsetClass.getMethod("newEncoder", null); + encoder = newEncoder.invoke(charsetObj, null); + canEncode = encoderClass.getMethod("canEncode", new Class[]{char.class}); + } + catch (Exception ignored) { + } + } + } + + public boolean shouldEscape(char ch) { + if (bits == 16) { + if (Verifier.isHighSurrogate(ch)) + return true; // Safer this way per http://unicode.org/faq/utf_bom.html#utf8-4 + else + return false; + } + if (bits == 8) { + if ((int) ch > 255) + return true; + else + return false; + } + if (bits == 7) { + if ((int) ch > 127) + return true; + else + return false; + } + else { + if (Verifier.isHighSurrogate(ch)) + return true; // Safer this way per http://unicode.org/faq/utf_bom.html#utf8-4 + + if (canEncode != null && encoder != null) { + try { + Boolean val = (Boolean) canEncode.invoke(encoder, new Object[]{new Character(ch)}); + return !val.booleanValue(); + } + catch (Exception ignored) { + } + } + // Return false if we don't know. This risks not escaping + // things which should be escaped, but also means people won't + // start getting loads of unnecessary escapes. + return false; + } + } + } + + + /** + * Class to signify how text should be handled on output. The following + * table provides details. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
+ * Text Mode + * + * Resulting behavior. + *
+ * PRESERVE (Default) + * + * All content is printed in the format it was created, no whitespace + * or line separators are are added or removed. + *
+ * TRIM_FULL_WHITE + * + * Content between tags consisting of all whitespace is not printed. + * If the content contains even one non-whitespace character, it is + * printed verbatim, whitespace and all. + *
+ * TRIM + * + * Same as TrimAllWhite, plus leading/trailing whitespace are + * trimmed. + *
+ * NORMALIZE + * + * Same as TextTrim, plus addition interior whitespace is compressed + * to a single space. + *
+ * + * In most cases textual content is aligned with the surrounding tags + * (after the appropriate text mode is applied). In the case where the only + * content between the start and end tags is textual, the start tag, text, + * and end tag are all printed on the same line. If the document being + * output already has whitespace, it's wise to turn on TRIM mode so the + * pre-existing whitespace can be trimmed before adding new whitespace. + *

+ * When a element has a xml:space attribute with the value of "preserve", + * all formating is turned off and reverts back to the default until the + * element and its contents have been printed. If a nested element contains + * another xml:space with the value "default" formatting is turned back on + * for the child element and then off for the remainder of the parent + * element. + */ + public static class TextMode { + /** + * Mode for literal text preservation. + */ + public static final TextMode PRESERVE = new TextMode("PRESERVE"); + + /** + * Mode for text trimming (left and right trim). + */ + public static final TextMode TRIM = new TextMode("TRIM"); + + /** + * Mode for text normalization (left and right trim plus internal + * whitespace is normalized to a single space. + * @see org.jdom.Element#getTextNormalize + */ + public static final TextMode NORMALIZE = new TextMode("NORMALIZE"); + + /** + * Mode for text trimming of content consisting of nothing but + * whitespace but otherwise not changing output. + */ + public static final TextMode TRIM_FULL_WHITE = + new TextMode("TRIM_FULL_WHITE"); + + private final String name; + + private TextMode(String name) { + this.name = name; + } + + public String toString() { + return name; + } + } +} Index: 3rdParty_sources/jdom/org/jdom/output/JDOMLocator.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/JDOMLocator.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/JDOMLocator.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,118 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.output; + +import org.xml.sax.*; +import org.xml.sax.helpers.*; + +/** + * An implementation of the SAX {@link Locator} interface that + * exposes the JDOM node being processed by SAXOutputter. + * + * @author Laurent Bihanic + * + * @version $Revision$, $Date$ + */ +public class JDOMLocator extends LocatorImpl { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The JDOM node being processed by SAXOutputter. */ + private Object node; + + /** + * Default no-arg constructor. + */ + JDOMLocator() { // package protected + super(); + } + + /** + * Copy contructor. + * + * @param locator Locator to copy location + * information from. + */ + JDOMLocator(Locator locator) { // package protected + super(locator); + + if (locator instanceof JDOMLocator) { + this.setNode(((JDOMLocator)locator).getNode()); + } + } + + /** + * Returns the JDOM node being processed by SAXOutputter. + * + * @return the JDOM node being processed by SAXOutputter. + */ + public Object getNode() { + return this.node; + } + + /** + * Sets the being-processed node. + * + * @param node Object node currently processed + * by SAXOutputter. + */ + void setNode(Object node) { // package protected + this.node = node; + } +} + Index: 3rdParty_sources/jdom/org/jdom/output/NamespaceStack.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/NamespaceStack.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/NamespaceStack.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,154 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ +package org.jdom.output; + +import java.util.*; + +import org.jdom.Namespace; + +/** + * A non-public utility class used by both {@link XMLOutputter} and + * {@link SAXOutputter} to manage namespaces in a JDOM Document + * during output. + * + * @version $Revision$, $Date$ + * @author Elliotte Rusty Harolde + * @author Fred Trimble + * @author Brett McLaughlin + */ +class NamespaceStack { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** The prefixes available */ + private Stack prefixes; + + /** The URIs available */ + private Stack uris; + + /** + * This creates the needed storage. + */ + NamespaceStack() { + prefixes = new Stack(); + uris = new Stack(); + } + + /** + * This will add a new {@link Namespace} + * to those currently available. + * + * @param ns Namespace to add. + */ + public void push(Namespace ns) { + prefixes.push(ns.getPrefix()); + uris.push(ns.getURI()); + } + + /** + * This will remove the topmost (most recently added) + * {@link Namespace}, and return its prefix. + * + * @return String - the popped namespace prefix. + */ + public String pop() { + String prefix = (String)prefixes.pop(); + uris.pop(); + + return prefix; + } + + /** + * This returns the number of available namespaces. + * + * @return int - size of the namespace stack. + */ + public int size() { + return prefixes.size(); + } + + /** + * Given a prefix, this will return the namespace URI most + * rencently (topmost) associated with that prefix. + * + * @param prefix String namespace prefix. + * @return String - the namespace URI for that prefix. + */ + public String getURI(String prefix) { + int index = prefixes.lastIndexOf(prefix); + if (index == -1) { + return null; + } + String uri = (String)uris.elementAt(index); + return uri; + } + + /** + * This will print out the size and current stack, from the + * most recently added {@link Namespace} to + * the "oldest," all to System.out. + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + String sep = System.getProperty("line.separator"); + buf.append("Stack: " + prefixes.size() + sep); + for (int i = 0; i < prefixes.size(); i++) { + buf.append(prefixes.elementAt(i) + "&" + uris.elementAt(i) + sep); + } + return buf.toString(); + } +} Index: 3rdParty_sources/jdom/org/jdom/output/SAXOutputter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/SAXOutputter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/SAXOutputter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,1462 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.output; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import org.jdom.*; +import org.xml.sax.*; +import org.xml.sax.ext.*; +import org.xml.sax.helpers.*; + +/** + * Outputs a JDOM document as a stream of SAX2 events. + *

+ * Most ContentHandler callbacks are supported. Both + * ignorableWhitespace() and skippedEntity() have not + * been implemented. The {@link JDOMLocator} class returned by + * {@link #getLocator} exposes the current node being operated + * upon. + *

+ * At this time, it is not possible to access notations and unparsed entity + * references in a DTD from JDOM. Therefore, DTDHandler callbacks + * have not been implemented yet. + *

+ * The ErrorHandler callbacks have not been implemented, since + * these are supposed to be invoked when the document is parsed and at this + * point the document exists in memory and is known to have no errors.

+ * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Fred Trimble + * @author Bradley S. Huffman + */ +public class SAXOutputter { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** Shortcut for SAX namespaces core feature */ + private static final String NAMESPACES_SAX_FEATURE = + "http://xml.org/sax/features/namespaces"; + + /** Shortcut for SAX namespace-prefixes core feature */ + private static final String NS_PREFIXES_SAX_FEATURE = + "http://xml.org/sax/features/namespace-prefixes"; + + /** Shortcut for SAX validation core feature */ + private static final String VALIDATION_SAX_FEATURE = + "http://xml.org/sax/features/validation"; + + /** Shortcut for SAX-ext. lexical handler property */ + private static final String LEXICAL_HANDLER_SAX_PROPERTY = + "http://xml.org/sax/properties/lexical-handler"; + + /** Shortcut for SAX-ext. declaration handler property */ + private static final String DECL_HANDLER_SAX_PROPERTY = + "http://xml.org/sax/properties/declaration-handler"; + + /** + * Shortcut for SAX-ext. lexical handler alternate property. + * Although this property URI is not the one defined by the SAX + * "standard", some parsers use it instead of the official one. + */ + private static final String LEXICAL_HANDLER_ALT_PROPERTY = + "http://xml.org/sax/handlers/LexicalHandler"; + + /** Shortcut for SAX-ext. declaration handler alternate property */ + private static final String DECL_HANDLER_ALT_PROPERTY = + "http://xml.org/sax/handlers/DeclHandler"; + + /** + * Array to map JDOM attribute type (as entry index) to SAX + * attribute type names. + */ + private static final String[] attrTypeToNameMap = new String[] { + "CDATA", // Attribute.UNDEFINED_ATTRIBUTE, as per SAX 2.0 spec. + "CDATA", // Attribute.CDATA_TYPE + "ID", // Attribute.ID_TYPE + "IDREF", // Attribute.IDREF_TYPE + "IDREFS", // Attribute.IDREFS_TYPE + "ENTITY", // Attribute.ENTITY_TYPE + "ENTITIES", // Attribute.ENTITIES_TYPE + "NMTOKEN", // Attribute.NMTOKEN_TYPE + "NMTOKENS", // Attribute.NMTOKENS_TYPE + "NOTATION", // Attribute.NOTATION_TYPE + "NMTOKEN", // Attribute.ENUMERATED_TYPE, as per SAX 2.0 spec. + }; + + /** registered ContentHandler */ + private ContentHandler contentHandler; + + /** registered ErrorHandler */ + private ErrorHandler errorHandler; + + /** registered DTDHandler */ + private DTDHandler dtdHandler; + + /** registered EntityResolver */ + private EntityResolver entityResolver; + + /** registered LexicalHandler */ + private LexicalHandler lexicalHandler; + + /** registered DeclHandler */ + private DeclHandler declHandler; + + /** + * Whether to report attribute namespace declarations as xmlns attributes. + * Defaults to false as per SAX specifications. + * + * @see + * SAX namespace specifications + */ + private boolean declareNamespaces = false; + + /** + * Whether to report DTD events to DeclHandlers and LexicalHandlers. + * Defaults to true. + */ + private boolean reportDtdEvents = true; + + /** + * A SAX Locator that points at the JDOM node currently being + * outputted. + */ + private JDOMLocator locator = null; + + /** + * This will create a SAXOutputter without any + * registered handler. The application is then responsible for + * registering them using the setXxxHandler() methods. + */ + public SAXOutputter() { + } + + /** + * This will create a SAXOutputter with the + * specified ContentHandler. + * + * @param contentHandler contains ContentHandler + * callback methods + */ + public SAXOutputter(ContentHandler contentHandler) { + this(contentHandler, null, null, null, null); + } + + /** + * This will create a SAXOutputter with the + * specified SAX2 handlers. At this time, only ContentHandler + * and EntityResolver are supported. + * + * @param contentHandler contains ContentHandler + * callback methods + * @param errorHandler contains ErrorHandler callback methods + * @param dtdHandler contains DTDHandler callback methods + * @param entityResolver contains EntityResolver + * callback methods + */ + public SAXOutputter(ContentHandler contentHandler, + ErrorHandler errorHandler, + DTDHandler dtdHandler, + EntityResolver entityResolver) { + this(contentHandler, errorHandler, dtdHandler, entityResolver, null); + } + + /** + * This will create a SAXOutputter with the + * specified SAX2 handlers. At this time, only ContentHandler + * and EntityResolver are supported. + * + * @param contentHandler contains ContentHandler + * callback methods + * @param errorHandler contains ErrorHandler callback methods + * @param dtdHandler contains DTDHandler callback methods + * @param entityResolver contains EntityResolver + * callback methods + * @param lexicalHandler contains LexicalHandler callbacks. + */ + public SAXOutputter(ContentHandler contentHandler, + ErrorHandler errorHandler, + DTDHandler dtdHandler, + EntityResolver entityResolver, + LexicalHandler lexicalHandler) { + this.contentHandler = contentHandler; + this.errorHandler = errorHandler; + this.dtdHandler = dtdHandler; + this.entityResolver = entityResolver; + this.lexicalHandler = lexicalHandler; + } + + /** + * This will set the ContentHandler. + * + * @param contentHandler contains ContentHandler + * callback methods. + */ + public void setContentHandler(ContentHandler contentHandler) { + this.contentHandler = contentHandler; + } + + /** + * Returns the registered ContentHandler. + * + * @return the current ContentHandler or + * null if none was registered. + */ + public ContentHandler getContentHandler() { + return this.contentHandler; + } + + /** + * This will set the ErrorHandler. + * + * @param errorHandler contains ErrorHandler callback methods. + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Return the registered ErrorHandler. + * + * @return the current ErrorHandler or + * null if none was registered. + */ + public ErrorHandler getErrorHandler() { + return this.errorHandler; + } + + /** + * This will set the DTDHandler. + * + * @param dtdHandler contains DTDHandler callback methods. + */ + public void setDTDHandler(DTDHandler dtdHandler) { + this.dtdHandler = dtdHandler; + } + + /** + * Return the registered DTDHandler. + * + * @return the current DTDHandler or + * null if none was registered. + */ + public DTDHandler getDTDHandler() { + return this.dtdHandler; + } + + /** + * This will set the EntityResolver. + * + * @param entityResolver contains EntityResolver callback methods. + */ + public void setEntityResolver(EntityResolver entityResolver) { + this.entityResolver = entityResolver; + } + + /** + * Return the registered EntityResolver. + * + * @return the current EntityResolver or + * null if none was registered. + */ + public EntityResolver getEntityResolver() { + return this.entityResolver; + } + + /** + * This will set the LexicalHandler. + * + * @param lexicalHandler contains lexical callback methods. + */ + public void setLexicalHandler(LexicalHandler lexicalHandler) { + this.lexicalHandler = lexicalHandler; + } + + /** + * Return the registered LexicalHandler. + * + * @return the current LexicalHandler or + * null if none was registered. + */ + public LexicalHandler getLexicalHandler() { + return this.lexicalHandler; + } + + /** + * This will set the DeclHandler. + * + * @param declHandler contains declaration callback methods. + */ + public void setDeclHandler(DeclHandler declHandler) { + this.declHandler = declHandler; + } + + /** + * Return the registered DeclHandler. + * + * @return the current DeclHandler or + * null if none was registered. + */ + public DeclHandler getDeclHandler() { + return this.declHandler; + } + + /** + * Returns whether attribute namespace declarations shall be reported as + * "xmlns" attributes. + * + * @return whether attribute namespace declarations shall be reported as + * "xmlns" attributes. + */ + public boolean getReportNamespaceDeclarations() { + return declareNamespaces; + } + + /** + * This will define whether attribute namespace declarations shall be + * reported as "xmlns" attributes. This flag defaults to false + * and behaves as the "namespace-prefixes" SAX core feature. + * + * @param declareNamespaces whether attribute namespace declarations + * shall be reported as "xmlns" attributes. + */ + public void setReportNamespaceDeclarations(boolean declareNamespaces) { + this.declareNamespaces = declareNamespaces; + } + + /** + * Returns whether DTD events will be reported. + * + * @return whether DTD events will be reported + */ + public boolean getReportDTDEvents() { + return reportDtdEvents; + } + + /** + * This will define whether to report DTD events to SAX DeclHandlers + * and LexicalHandlers if these handlers are registered and the + * document to output includes a DocType declaration. + * + * @param reportDtdEvents whether to notify DTD events. + */ + public void setReportDTDEvents(boolean reportDtdEvents) { + this.reportDtdEvents = reportDtdEvents; + } + + /** + * This will set the state of a SAX feature. + *

+ * All XMLReaders are required to support setting to true and to false. + *

+ *

+ * SAXOutputter currently supports the following SAX core features: + *

+ *
http://xml.org/sax/features/namespaces
+ *
description: true indicates + * namespace URIs and unprefixed local names for element and + * attribute names will be available
+ *
access: read/write, but always + * true!
+ *
http://xml.org/sax/features/namespace-prefixes
+ *
description: true indicates + * XML 1.0 names (with prefixes) and attributes (including xmlns* + * attributes) will be available
+ *
access: read/write
+ *
http://xml.org/sax/features/validation
+ *
description: controls whether SAXOutputter + * is reporting DTD-related events; if true, the + * DocType internal subset will be parsed to fire DTD events
+ *
access: read/write, defaults to + * true
+ *
+ *

+ * + * @param name String the feature name, which is a + * fully-qualified URI. + * @param value boolean the requested state of the + * feature (true or false). + * + * @throws SAXNotRecognizedException when SAXOutputter does not + * recognize the feature name. + * @throws SAXNotSupportedException when SAXOutputter recognizes + * the feature name but cannot set the requested value. + */ + public void setFeature(String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException { + if (NS_PREFIXES_SAX_FEATURE.equals(name)) { + // Namespace prefix declarations. + this.setReportNamespaceDeclarations(value); + } + else { + if (NAMESPACES_SAX_FEATURE.equals(name)) { + if (value != true) { + // Namespaces feature always supported by SAXOutputter. + throw new SAXNotSupportedException(name); + } + // Else: true is OK! + } + else { + if (VALIDATION_SAX_FEATURE.equals(name)) { + // Report DTD events. + this.setReportDTDEvents(value); + } + else { + // Not a supported feature. + throw new SAXNotRecognizedException(name); + } + } + } + } + + /** + * This will look up the value of a SAX feature. + * + * @param name String the feature name, which is a + * fully-qualified URI. + * @return boolean the current state of the feature + * (true or false). + * + * @throws SAXNotRecognizedException when SAXOutputter does not + * recognize the feature name. + * @throws SAXNotSupportedException when SAXOutputter recognizes + * the feature name but determine its value at this time. + */ + public boolean getFeature(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + if (NS_PREFIXES_SAX_FEATURE.equals(name)) { + // Namespace prefix declarations. + return (this.declareNamespaces); + } + else { + if (NAMESPACES_SAX_FEATURE.equals(name)) { + // Namespaces feature always supported by SAXOutputter. + return (true); + } + else { + if (VALIDATION_SAX_FEATURE.equals(name)) { + // Report DTD events. + return (this.reportDtdEvents); + } + else { + // Not a supported feature. + throw new SAXNotRecognizedException(name); + } + } + } + } + + /** + * This will set the value of a SAX property. + * This method is also the standard mechanism for setting extended + * handlers. + *

+ * SAXOutputter currently supports the following SAX properties: + *

+ *
http://xml.org/sax/properties/lexical-handler
+ *
data type: + * org.xml.sax.ext.LexicalHandler
+ *
description: An optional extension handler for + * lexical events like comments.
+ *
access: read/write
+ *
http://xml.org/sax/properties/declaration-handler
+ *
data type: + * org.xml.sax.ext.DeclHandler
+ *
description: An optional extension handler for + * DTD-related events other than notations and unparsed entities.
+ *
access: read/write
+ *
+ *

+ * + * @param name String the property name, which is a + * fully-qualified URI. + * @param value Object the requested value for the property. + * + * @throws SAXNotRecognizedException when SAXOutputter does not recognize + * the property name. + * @throws SAXNotSupportedException when SAXOutputter recognizes the + * property name but cannot set the requested value. + */ + public void setProperty(String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException { + if ((LEXICAL_HANDLER_SAX_PROPERTY.equals(name)) || + (LEXICAL_HANDLER_ALT_PROPERTY.equals(name))) { + this.setLexicalHandler((LexicalHandler)value); + } + else { + if ((DECL_HANDLER_SAX_PROPERTY.equals(name)) || + (DECL_HANDLER_ALT_PROPERTY.equals(name))) { + this.setDeclHandler((DeclHandler)value); + } + else { + throw new SAXNotRecognizedException(name); + } + } + } + + /** + * This will look up the value of a SAX property. + * + * @param name String the property name, which is a + * fully-qualified URI. + * @return Object the current value of the property. + * + * @throws SAXNotRecognizedException when SAXOutputter does not recognize + * the property name. + * @throws SAXNotSupportedException when SAXOutputter recognizes the + * property name but cannot determine its value at this time. + */ + public Object getProperty(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + if ((LEXICAL_HANDLER_SAX_PROPERTY.equals(name)) || + (LEXICAL_HANDLER_ALT_PROPERTY.equals(name))) { + return this.getLexicalHandler(); + } + else { + if ((DECL_HANDLER_SAX_PROPERTY.equals(name)) || + (DECL_HANDLER_ALT_PROPERTY.equals(name))) { + return this.getDeclHandler(); + } + else { + throw new SAXNotRecognizedException(name); + } + } + } + + + /** + * This will output the JDOM Document, firing off the + * SAX events that have been registered. + * + * @param document JDOM Document to output. + * + * @throws JDOMException if any error occurred. + */ + public void output(Document document) throws JDOMException { + if (document == null) { + return; + } + + // contentHandler.setDocumentLocator() + documentLocator(document); + + // contentHandler.startDocument() + startDocument(); + + // Fire DTD events + if (this.reportDtdEvents) { + dtdEvents(document); + } + + // Handle root element, as well as any root level + // processing instructions and comments + Iterator i = document.getContent().iterator(); + while (i.hasNext()) { + Object obj = i.next(); + + // update locator + locator.setNode(obj); + + if (obj instanceof Element) { + // process root element and its content + element(document.getRootElement(), new NamespaceStack()); + } + else if (obj instanceof ProcessingInstruction) { + // contentHandler.processingInstruction() + processingInstruction((ProcessingInstruction) obj); + } + else if (obj instanceof Comment) { + // lexicalHandler.comment() + comment(((Comment) obj).getText()); + } + } + + // contentHandler.endDocument() + endDocument(); + } + + /** + * This will output a list of JDOM nodes as a document, firing + * off the SAX events that have been registered. + *

+ * Warning: This method may output ill-formed XML + * documents if the list contains top-level objects that are not + * legal at the document level (e.g. Text or CDATA nodes, multiple + * Element nodes, etc.). Thus, it should only be used to output + * document portions towards ContentHandlers capable of accepting + * such ill-formed documents (such as XSLT processors).

+ * + * @param nodes List of JDOM nodes to output. + * + * @throws JDOMException if any error occurred. + * + * @see #output(org.jdom.Document) + */ + public void output(List nodes) throws JDOMException { + if ((nodes == null) || (nodes.size() == 0)) { + return; + } + + // contentHandler.setDocumentLocator() + documentLocator(null); + + // contentHandler.startDocument() + startDocument(); + + // Process node list. + elementContent(nodes, new NamespaceStack()); + + // contentHandler.endDocument() + endDocument(); + } + + /** + * This will output a single JDOM element as a document, firing + * off the SAX events that have been registered. + * + * @param node the Element node to output. + * + * @throws JDOMException if any error occurred. + */ + public void output(Element node) throws JDOMException { + if (node == null) { + return; + } + + // contentHandler.setDocumentLocator() + documentLocator(null); + + // contentHandler.startDocument() + startDocument(); + + // Output node. + elementContent(node, new NamespaceStack()); + + // contentHandler.endDocument() + endDocument(); + } + + /** + * This will output a list of JDOM nodes as a fragment of an XML + * document, firing off the SAX events that have been registered. + *

+ * Warning: This method does not call the + * {@link ContentHandler#setDocumentLocator}, + * {@link ContentHandler#startDocument} and + * {@link ContentHandler#endDocument} callbacks on the + * {@link #setContentHandler ContentHandler}. The user shall + * invoke these methods directly prior/after outputting the + * document fragments.

+ * + * @param nodes List of JDOM nodes to output. + * + * @throws JDOMException if any error occurred. + * + * @see #outputFragment(org.jdom.Content) + */ + public void outputFragment(List nodes) throws JDOMException { + if ((nodes == null) || (nodes.size() == 0)) { + return; + } + + // Output node list as a document fragment. + elementContent(nodes, new NamespaceStack()); + } + + /** + * This will output a single JDOM nodes as a fragment of an XML + * document, firing off the SAX events that have been registered. + *

+ * Warning: This method does not call the + * {@link ContentHandler#setDocumentLocator}, + * {@link ContentHandler#startDocument} and + * {@link ContentHandler#endDocument} callbacks on the + * {@link #setContentHandler ContentHandler}. The user shall + * invoke these methods directly prior/after outputting the + * document fragments.

+ * + * @param node the Content node to output. + * + * @throws JDOMException if any error occurred. + * + * @see #outputFragment(java.util.List) + */ + public void outputFragment(Content node) throws JDOMException { + if (node == null) { + return; + } + + // Output single node as a document fragment. + elementContent(node, new NamespaceStack()); + } + + /** + * This parses a DTD declaration to fire the related events towards + * the registered handlers. + * + * @param document JDOM Document the DocType is to + * process. + */ + private void dtdEvents(Document document) throws JDOMException { + DocType docType = document.getDocType(); + + // Fire DTD-related events only if handlers have been registered. + if ((docType != null) && + ((dtdHandler != null) || (declHandler != null))) { + + // Build a dummy XML document that only references the DTD... + String dtdDoc = new XMLOutputter().outputString(docType); + + try { + // And parse it to fire DTD events. + createDTDParser().parse(new InputSource( + new StringReader(dtdDoc))); + + // We should never reach this point as the document is + // ill-formed; it does not have any root element. + } + catch (SAXParseException e) { + // Expected exception: There's no root element in document. + } + catch (SAXException e) { + throw new JDOMException("DTD parsing error", e); + } + catch (IOException e) { + throw new JDOMException("DTD parsing error", e); + } + } + } + + /** + *

+ * This method tells you the line of the XML file being parsed. + * For an in-memory document, it's meaningless. The location + * is only valid for the current parsing lifecycle, but + * the document has already been parsed. Therefore, it returns + * -1 for both line and column numbers. + *

+ * + * @param document JDOM Document. + */ + private void documentLocator(Document document) { + locator = new JDOMLocator(); + String publicID = null; + String systemID = null; + + if (document != null) { + DocType docType = document.getDocType(); + if (docType != null) { + publicID = docType.getPublicID(); + systemID = docType.getSystemID(); + } + } + locator.setPublicId(publicID); + locator.setSystemId(systemID); + locator.setLineNumber(-1); + locator.setColumnNumber(-1); + + contentHandler.setDocumentLocator(locator); + } + + /** + *

+ * This method is always the second method of all callbacks in + * all handlers to be invoked (setDocumentLocator is always first). + *

+ */ + private void startDocument() throws JDOMException { + try { + contentHandler.startDocument(); + } + catch (SAXException se) { + throw new JDOMException("Exception in startDocument", se); + } + } + + /** + *

+ * Always the last method of all callbacks in all handlers + * to be invoked. + *

+ */ + private void endDocument() throws JDOMException { + try { + contentHandler.endDocument(); + + // reset locator + locator = null; + } + catch (SAXException se) { + throw new JDOMException("Exception in endDocument", se); + } + } + + /** + *

+ * This will invoke the ContentHandler.processingInstruction + * callback when a processing instruction is encountered. + *

+ * + * @param pi ProcessingInstruction containing target and data. + */ + private void processingInstruction(ProcessingInstruction pi) + throws JDOMException { + if (pi != null) { + String target = pi.getTarget(); + String data = pi.getData(); + try { + contentHandler.processingInstruction(target, data); + } + catch (SAXException se) { + throw new JDOMException( + "Exception in processingInstruction", se); + } + } + } + + /** + *

+ * This will recursively invoke all of the callbacks for a particular + * element. + *

+ * + * @param element Element used in callbacks. + * @param namespaces List stack of Namespaces in scope. + */ + private void element(Element element, NamespaceStack namespaces) + throws JDOMException { + // used to check endPrefixMapping + int previouslyDeclaredNamespaces = namespaces.size(); + + // contentHandler.startPrefixMapping() + Attributes nsAtts = startPrefixMapping(element, namespaces); + + // contentHandler.startElement() + startElement(element, nsAtts); + + // handle content in the element + elementContent(element.getContent(), namespaces); + + // update locator + if (locator != null) { + locator.setNode(element); + } + + // contentHandler.endElement() + endElement(element); + + // contentHandler.endPrefixMapping() + endPrefixMapping(namespaces, previouslyDeclaredNamespaces); + } + + /** + *

+ * This will invoke the ContentHandler.startPrefixMapping + * callback + * when a new namespace is encountered in the Document. + *

+ * + * @param element Element used in callbacks. + * @param namespaces List stack of Namespaces in scope. + * + * @return Attributes declaring the namespaces local to + * element or null. + */ + private Attributes startPrefixMapping(Element element, + NamespaceStack namespaces) + throws JDOMException { + AttributesImpl nsAtts = null; // The namespaces as xmlns attributes + + Namespace ns = element.getNamespace(); + if (ns != Namespace.XML_NAMESPACE) { + String prefix = ns.getPrefix(); + String uri = namespaces.getURI(prefix); + if (!ns.getURI().equals(uri)) { + namespaces.push(ns); + nsAtts = this.addNsAttribute(nsAtts, ns); + try { + contentHandler.startPrefixMapping(prefix, ns.getURI()); + } + catch (SAXException se) { + throw new JDOMException( + "Exception in startPrefixMapping", se); + } + } + } + + // Fire additional namespace declarations + List additionalNamespaces = element.getAdditionalNamespaces(); + if (additionalNamespaces != null) { + Iterator itr = additionalNamespaces.iterator(); + while (itr.hasNext()) { + ns = (Namespace)itr.next(); + String prefix = ns.getPrefix(); + String uri = namespaces.getURI(prefix); + if (!ns.getURI().equals(uri)) { + namespaces.push(ns); + nsAtts = this.addNsAttribute(nsAtts, ns); + try { + contentHandler.startPrefixMapping(prefix, ns.getURI()); + } + catch (SAXException se) { + throw new JDOMException( + "Exception in startPrefixMapping", se); + } + } + } + } + + // Fire any namespace on Attributes that were not explicity added as additionals. + List attributes = element.getAttributes(); + if (attributes != null) { + Iterator itr = attributes.iterator(); + while (itr.hasNext()) { + Attribute att = (Attribute)itr.next(); + ns = att.getNamespace(); + String prefix = ns.getPrefix(); + String uri = namespaces.getURI(prefix); + if (!ns.getURI().equals(uri)) { + namespaces.push(ns); + nsAtts = this.addNsAttribute(nsAtts, ns); + try { + contentHandler.startPrefixMapping(prefix, ns.getURI()); + } + catch (SAXException se) { + throw new JDOMException( + "Exception in startPrefixMapping", se); + } + } + } + } + return nsAtts; + } + + /** + *

+ * This will invoke the endPrefixMapping callback in the + * ContentHandler when a namespace is goes out of scope + * in the Document. + *

+ * + * @param namespaces List stack of Namespaces in scope. + * @param previouslyDeclaredNamespaces number of previously declared + * namespaces + */ + private void endPrefixMapping(NamespaceStack namespaces, + int previouslyDeclaredNamespaces) + throws JDOMException { + while (namespaces.size() > previouslyDeclaredNamespaces) { + String prefix = namespaces.pop(); + try { + contentHandler.endPrefixMapping(prefix); + } + catch (SAXException se) { + throw new JDOMException("Exception in endPrefixMapping", se); + } + } + } + + /** + *

+ * This will invoke the startElement callback + * in the ContentHandler. + *

+ * + * @param element Element used in callbacks. + * @param nsAtts List of namespaces to declare with + * the element or null. + */ + private void startElement(Element element, Attributes nsAtts) + throws JDOMException { + String namespaceURI = element.getNamespaceURI(); + String localName = element.getName(); + String rawName = element.getQualifiedName(); + + // Allocate attribute list. + AttributesImpl atts = (nsAtts != null)? + new AttributesImpl(nsAtts): new AttributesImpl(); + + List attributes = element.getAttributes(); + Iterator i = attributes.iterator(); + while (i.hasNext()) { + Attribute a = (Attribute) i.next(); + atts.addAttribute(a.getNamespaceURI(), + a.getName(), + a.getQualifiedName(), + getAttributeTypeName(a.getAttributeType()), + a.getValue()); + } + + try { + contentHandler.startElement(namespaceURI, localName, rawName, atts); + } + catch (SAXException se) { + throw new JDOMException("Exception in startElement", se); + } + } + + /** + *

+ * This will invoke the endElement callback + * in the ContentHandler. + *

+ * + * @param element Element used in callbacks. + */ + private void endElement(Element element) throws JDOMException { + String namespaceURI = element.getNamespaceURI(); + String localName = element.getName(); + String rawName = element.getQualifiedName(); + + try { + contentHandler.endElement(namespaceURI, localName, rawName); + } + catch (SAXException se) { + throw new JDOMException("Exception in endElement", se); + } + } + + /** + *

+ * This will invoke the callbacks for the content of an element. + *

+ * + * @param content element content as a List of nodes. + * @param namespaces List stack of Namespaces in scope. + */ + private void elementContent(List content, NamespaceStack namespaces) + throws JDOMException { + for (Iterator i=content.iterator(); i.hasNext(); ) { + Object obj = i.next(); + + if (obj instanceof Content) { + this.elementContent((Content)obj, namespaces); + } + else { + // Not a valid element child. This could happen with + // application-provided lists which may contain non + // JDOM objects. + handleError(new JDOMException( + "Invalid element content: " + obj)); + } + } + } + + /** + *

+ * This will invoke the callbacks for the content of an element. + *

+ * + * @param node a Content node. + * @param namespaces List stack of Namespaces in scope. + */ + private void elementContent(Content node, NamespaceStack namespaces) + throws JDOMException { + // update locator + if (locator != null) { + locator.setNode(node); + } + + if (node instanceof Element) { + element((Element) node, namespaces); + } + else if (node instanceof CDATA) { + cdata(((CDATA) node).getText()); + } + else if (node instanceof Text) { + // contentHandler.characters() + characters(((Text) node).getText()); + } + else if (node instanceof ProcessingInstruction) { + // contentHandler.processingInstruction() + processingInstruction((ProcessingInstruction) node); + } + else if (node instanceof Comment) { + // lexicalHandler.comment() + comment(((Comment) node).getText()); + } + else if (node instanceof EntityRef) { + // contentHandler.skippedEntity() + entityRef((EntityRef) node); + } + else { + // Not a valid element child. This could happen with + // application-provided lists which may contain non + // JDOM objects. + handleError(new JDOMException("Invalid element content: " + node)); + } + } + + /** + *

+ * This will be called for each chunk of CDATA section encountered. + *

+ * + * @param cdataText all text in the CDATA section, including whitespace. + */ + private void cdata(String cdataText) throws JDOMException { + try { + if (lexicalHandler != null) { + lexicalHandler.startCDATA(); + characters(cdataText); + lexicalHandler.endCDATA(); + } + else { + characters(cdataText); + } + } + catch (SAXException se) { + throw new JDOMException("Exception in CDATA", se); + } + } + + /** + *

+ * This will be called for each chunk of character data encountered. + *

+ * + * @param elementText all text in an element, including whitespace. + */ + private void characters(String elementText) throws JDOMException { + char[] c = elementText.toCharArray(); + try { + contentHandler.characters(c, 0, c.length); + } + catch (SAXException se) { + throw new JDOMException("Exception in characters", se); + } + } + + /** + *

+ * This will be called for each chunk of comment data encontered. + *

+ * + * @param commentText all text in a comment, including whitespace. + */ + private void comment(String commentText) throws JDOMException { + if (lexicalHandler != null) { + char[] c = commentText.toCharArray(); + try { + lexicalHandler.comment(c, 0, c.length); + } catch (SAXException se) { + throw new JDOMException("Exception in comment", se); + } + } + } + + /** + *

+ * This will invoke the ContentHandler.skippedEntity + * callback when an entity reference is encountered. + *

+ * + * @param entity EntityRef. + */ + private void entityRef(EntityRef entity) throws JDOMException { + if (entity != null) { + try { + // No need to worry about appending a '%' character as + // we do not support parameter entities + contentHandler.skippedEntity(entity.getName()); + } + catch (SAXException se) { + throw new JDOMException("Exception in entityRef", se); + } + } + } + + + /** + *

+ * Appends a namespace declaration in the form of a xmlns attribute to + * an attribute list, crerating this latter if needed. + *

+ * + * @param atts AttributeImpl where to add the attribute. + * @param ns Namespace the namespace to declare. + * + * @return AttributeImpl the updated attribute list. + */ + private AttributesImpl addNsAttribute(AttributesImpl atts, Namespace ns) { + if (this.declareNamespaces) { + if (atts == null) { + atts = new AttributesImpl(); + } + + String prefix = ns.getPrefix(); + if (prefix.equals("")) { + atts.addAttribute("", // namespace + "", // local name + "xmlns", // qualified name + "CDATA", // type + ns.getURI()); // value + } + else { + atts.addAttribute("", // namespace + "", // local name + "xmlns:" + ns.getPrefix(), // qualified name + "CDATA", // type + ns.getURI()); // value + } + } + return atts; + } + + /** + *

+ * Returns the SAX 2.0 attribute type string from the type of + * a JDOM Attribute. + *

+ * + * @param type int the type of the JDOM attribute. + * + * @return String the SAX 2.0 attribute type string. + * + * @see org.jdom.Attribute#getAttributeType + * @see org.xml.sax.Attributes#getType + */ + private static String getAttributeTypeName(int type) { + if ((type < 0) || (type >= attrTypeToNameMap.length)) { + type = Attribute.UNDECLARED_TYPE; + } + return attrTypeToNameMap[type]; + } + + /** + *

+ * Notifies the registered {@link ErrorHandler SAX error handler} + * (if any) of an input processing error. The error handler can + * choose to absorb the error and let the processing continue. + *

+ * + * @param exception JDOMException containing the + * error information; will be wrapped in a + * {@link SAXParseException} when reported to + * the SAX error handler. + * + * @throws JDOMException if no error handler has been registered + * or if the error handler fired a + * {@link SAXException}. + */ + private void handleError(JDOMException exception) throws JDOMException { + if (errorHandler != null) { + try { + errorHandler.error(new SAXParseException( + exception.getMessage(), null, exception)); + } + catch (SAXException se) { + if (se.getException() instanceof JDOMException) { + throw (JDOMException)(se.getException()); + } + else { + throw new JDOMException(se.getMessage(), se); + } + } + } + else { + throw exception; + } + } + + /** + *

+ * Creates a SAX XMLReader. + *

+ * + * @return XMLReader a SAX2 parser. + * + * @throws Exception if no parser can be created. + */ + protected XMLReader createParser() throws Exception { + XMLReader parser = null; + + // Try using JAXP... + // Note we need JAXP 1.1, and if JAXP 1.0 is all that's + // available then the getXMLReader call fails and we skip + // to the hard coded default parser + try { + Class factoryClass = + Class.forName("javax.xml.parsers.SAXParserFactory"); + + // factory = SAXParserFactory.newInstance(); + Method newParserInstance = + factoryClass.getMethod("newInstance", null); + Object factory = newParserInstance.invoke(null, null); + + // jaxpParser = factory.newSAXParser(); + Method newSAXParser = factoryClass.getMethod("newSAXParser", null); + Object jaxpParser = newSAXParser.invoke(factory, null); + + // parser = jaxpParser.getXMLReader(); + Class parserClass = jaxpParser.getClass(); + Method getXMLReader = + parserClass.getMethod("getXMLReader", null); + parser = (XMLReader)getXMLReader.invoke(jaxpParser, null); + } catch (ClassNotFoundException e) { + //e.printStackTrace(); + } catch (InvocationTargetException e) { + //e.printStackTrace(); + } catch (NoSuchMethodException e) { + //e.printStackTrace(); + } catch (IllegalAccessException e) { + //e.printStackTrace(); + } + + // Check to see if we got a parser yet, if not, try to use a + // hard coded default + if (parser == null) { + parser = XMLReaderFactory.createXMLReader( + "org.apache.xerces.parsers.SAXParser"); + } + return parser; + } + + /** + *

+ * This will create a SAX XMLReader capable of parsing a DTD and + * configure it so that the DTD parsing events are routed to the + * handlers registered onto this SAXOutputter. + *

+ * + * @return XMLReader a SAX2 parser. + * + * @throws JDOMException if no parser can be created. + */ + private XMLReader createDTDParser() throws JDOMException { + XMLReader parser = null; + + // Get a parser instance + try + { + parser = createParser(); + } + catch (Exception ex1) { + throw new JDOMException("Error in SAX parser allocation", ex1); + } + + // Register handlers + if (this.getDTDHandler() != null) { + parser.setDTDHandler(this.getDTDHandler()); + } + if (this.getEntityResolver() != null) { + parser.setEntityResolver(this.getEntityResolver()); + } + if (this.getLexicalHandler() != null) { + try { + parser.setProperty(LEXICAL_HANDLER_SAX_PROPERTY, + this.getLexicalHandler()); + } + catch (SAXException ex1) { + try { + parser.setProperty(LEXICAL_HANDLER_ALT_PROPERTY, + this.getLexicalHandler()); + } catch (SAXException ex2) { + // Forget it! + } + } + } + if (this.getDeclHandler() != null) { + try { + parser.setProperty(DECL_HANDLER_SAX_PROPERTY, + this.getDeclHandler()); + } + catch (SAXException ex1) { + try { + parser.setProperty(DECL_HANDLER_ALT_PROPERTY, + this.getDeclHandler()); + } catch (SAXException ex2) { + // Forget it! + } + } + } + + // Absorb errors as much as possible, per Laurent + parser.setErrorHandler(new DefaultHandler()); + + return parser; + } + + /** + * Returns a JDOMLocator object referencing the node currently + * being processed by this outputter. The returned object is a + * snapshot of the location information and can thus safely be + * memorized for later use. + *

+ * This method allows direct access to the location information + * maintained by SAXOutputter without requiring to implement + * XMLFilter. (In SAX, locators are only available + * though the ContentHandler interface).

+ *

+ * Note that location information is only available while + * SAXOutputter is outputting nodes. Hence this method should + * only be used by objects taking part in the output processing + * such as ErrorHandlers. + * + * @return a JDOMLocator object referencing the node currently + * being processed or null if no output + * operation is being performed. + */ + public JDOMLocator getLocator() { + return (locator != null)? new JDOMLocator(locator): null; + } +} Index: 3rdParty_sources/jdom/org/jdom/output/XMLOutputter.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/XMLOutputter.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/XMLOutputter.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,1640 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.output; + +import java.io.*; +import java.util.*; + +import javax.xml.transform.Result; + +import org.jdom.*; + +/** + * Outputs a JDOM document as a stream of bytes. The outputter can manage many + * styles of document formatting, from untouched to pretty printed. The default + * is to output the document content exactly as created, but this can be changed + * by setting a new Format object. For pretty-print output, use + * {@link Format#getPrettyFormat()}. For whitespace-normalized + * output, use {@link Format#getCompactFormat()}. + *

+ * There are {@link #output output(...)} methods to print any of + * the standard JDOM classes, including Document and Element, to either a Writer + * or an OutputStream. Warning: When outputting to a Writer, make sure + * the writer's encoding matches the encoding setting in the Format object. This + * ensures the encoding in which the content is written (controlled by the + * Writer configuration) matches the encoding placed in the document's XML + * declaration (controlled by the XMLOutputter). Because a Writer cannot be + * queried for its encoding, the information must be passed to the Format + * manually in its constructor or via the + * {@link Format#setEncoding} method. The default encoding is + * UTF-8. + *

+ * The methods {@link #outputString outputString(...)} are for + * convenience only; for top performance you should call one of the {@link + * #output output(...)} methods and pass in your own Writer or + * OutputStream if possible. + *

+ * XML declarations are always printed on their own line followed by a line + * seperator (this doesn't change the semantics of the document). To omit + * printing of the declaration use + * {@link Format#setOmitDeclaration}. To omit printing of the + * encoding in the declaration use {@link Format#setOmitEncoding}. + * Unfortunatly there is currently no way to know the original encoding of the + * document. + *

+ * Empty elements are by default printed as <empty/>, but this can be + * configured with {@link Format#setExpandEmptyElements} to cause + * them to be expanded to <empty></empty>. + * + * @version $Revision$, $Date$ + * @author Brett McLaughlin + * @author Jason Hunter + * @author Jason Reid + * @author Wolfgang Werner + * @author Elliotte Rusty Harold + * @author David & Will (from Post Tool Design) + * @author Dan Schaffer + * @author Alex Chaffee + * @author Bradley S. Huffman + */ + +public class XMLOutputter implements Cloneable { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + // For normal output + private Format userFormat = Format.getRawFormat(); + + // For xml:space="preserve" + protected static final Format preserveFormat = Format.getRawFormat(); + + // What's currently in use + protected Format currentFormat = userFormat; + + /** Whether output escaping is enabled for the being processed + * Element - default is true */ + private boolean escapeOutput = true; + + // * * * * * * * * * * Constructors * * * * * * * * * * + // * * * * * * * * * * Constructors * * * * * * * * * * + + /** + * This will create an XMLOutputter with the default + * {@link Format} matching {@link Format#getRawFormat}. + */ + public XMLOutputter() { + } + + /** + * This will create an XMLOutputter with the specified + * format characteristics. Note the format object is cloned internally + * before use. + */ + public XMLOutputter(Format format) { + userFormat = (Format) format.clone(); + currentFormat = userFormat; + } + + /** + * This will create an XMLOutputter with all the + * options as set in the given XMLOutputter. Note + * that XMLOutputter two = (XMLOutputter)one.clone(); + * would work equally well. + * + * @param that the XMLOutputter to clone + */ + public XMLOutputter(XMLOutputter that) { + this.userFormat = (Format) that.userFormat.clone(); + currentFormat = userFormat; + } + + // * * * * * * * * * * Set parameters methods * * * * * * * * * * + // * * * * * * * * * * Set parameters methods * * * * * * * * * * + + /** + * Sets the new format logic for the outputter. Note the Format + * object is cloned internally before use. + * + * @param newFormat the format to use for output + */ + public void setFormat(Format newFormat) { + this.userFormat = (Format) newFormat.clone(); + this.currentFormat = userFormat; + } + + /** + * Returns the current format in use by the outputter. Note the + * Format object returned is a clone of the one used internally. + */ + public Format getFormat() { + return (Format) userFormat.clone(); + } + + // * * * * * * * * * * Output to a OutputStream * * * * * * * * * * + // * * * * * * * * * * Output to a OutputStream * * * * * * * * * * + + /** + * This will print the Document to the given output stream. + * The characters are printed using the encoding specified in the + * constructor, or a default of UTF-8. + * + * @param doc Document to format. + * @param out OutputStream to use. + * @throws IOException - if there's any problem writing. + */ + public void output(Document doc, OutputStream out) + throws IOException { + Writer writer = makeWriter(out); + output(doc, writer); // output() flushes + } + + /** + * Print out the {@link DocType}. + * + * @param doctype DocType to output. + * @param out OutputStream to use. + */ + public void output(DocType doctype, OutputStream out) throws IOException { + Writer writer = makeWriter(out); + output(doctype, writer); // output() flushes + } + + /** + * Print out an {@link Element}, including + * its {@link Attribute}s, and all + * contained (child) elements, etc. + * + * @param element Element to output. + * @param out Writer to use. + */ + public void output(Element element, OutputStream out) throws IOException { + Writer writer = makeWriter(out); + output(element, writer); // output() flushes + } + + /** + * This will handle printing out an {@link + * Element}'s content only, not including its tag, and + * attributes. This can be useful for printing the content of an + * element that contains HTML, like "<description>JDOM is + * <b>fun>!</description>". + * + * @param element Element to output. + * @param out OutputStream to use. + */ + public void outputElementContent(Element element, OutputStream out) + throws IOException { + Writer writer = makeWriter(out); + outputElementContent(element, writer); // output() flushes + } + + /** + * This will handle printing out a list of nodes. + * This can be useful for printing the content of an element that + * contains HTML, like "<description>JDOM is + * <b>fun>!</description>". + * + * @param list List of nodes. + * @param out OutputStream to use. + */ + public void output(List list, OutputStream out) + throws IOException { + Writer writer = makeWriter(out); + output(list, writer); // output() flushes + } + + /** + * Print out a {@link CDATA} node. + * + * @param cdata CDATA to output. + * @param out OutputStream to use. + */ + public void output(CDATA cdata, OutputStream out) throws IOException { + Writer writer = makeWriter(out); + output(cdata, writer); // output() flushes + } + + /** + * Print out a {@link Text} node. Perfoms + * the necessary entity escaping and whitespace stripping. + * + * @param text Text to output. + * @param out OutputStream to use. + */ + public void output(Text text, OutputStream out) throws IOException { + Writer writer = makeWriter(out); + output(text, writer); // output() flushes + } + + /** + * Print out a {@link Comment}. + * + * @param comment Comment to output. + * @param out OutputStream to use. + */ + public void output(Comment comment, OutputStream out) throws IOException { + Writer writer = makeWriter(out); + output(comment, writer); // output() flushes + } + + /** + * Print out a {@link ProcessingInstruction}. + * + * @param pi ProcessingInstruction to output. + * @param out OutputStream to use. + */ + public void output(ProcessingInstruction pi, OutputStream out) + throws IOException { + Writer writer = makeWriter(out); + output(pi, writer); // output() flushes + } + + /** + * Print out a {@link EntityRef}. + * + * @param entity EntityRef to output. + * @param out OutputStream to use. + */ + public void output(EntityRef entity, OutputStream out) throws IOException { + Writer writer = makeWriter(out); + output(entity, writer); // output() flushes + } + + /** + * Get an OutputStreamWriter, using prefered encoding + * (see {@link Format#setEncoding}). + */ + private Writer makeWriter(OutputStream out) + throws java.io.UnsupportedEncodingException { + return makeWriter(out, userFormat.encoding); + } + + /** + * Get an OutputStreamWriter, use specified encoding. + */ + private static Writer makeWriter(OutputStream out, String enc) + throws java.io.UnsupportedEncodingException { + // "UTF-8" is not recognized before JDK 1.1.6, so we'll translate + // into "UTF8" which works with all JDKs. + if ("UTF-8".equals(enc)) { + enc = "UTF8"; + } + + Writer writer = new BufferedWriter( + (new OutputStreamWriter( + new BufferedOutputStream(out), enc) + )); + return writer; + } + + // * * * * * * * * * * Output to a Writer * * * * * * * * * * + // * * * * * * * * * * Output to a Writer * * * * * * * * * * + + /** + * This will print the Document to the given Writer. + * + *

+ * Warning: using your own Writer may cause the outputter's + * preferred character encoding to be ignored. If you use + * encodings other than UTF-8, we recommend using the method that + * takes an OutputStream instead. + *

+ * + * @param doc Document to format. + * @param out Writer to use. + * @throws IOException - if there's any problem writing. + */ + public void output(Document doc, Writer out) throws IOException { + + printDeclaration(out, doc, userFormat.encoding); + + // Print out root element, as well as any root level + // comments and processing instructions, + // starting with no indentation + List content = doc.getContent(); + int size = content.size(); + for (int i = 0; i < size; i++) { + Object obj = content.get(i); + + if (obj instanceof Element) { + printElement(out, doc.getRootElement(), 0, + createNamespaceStack()); + } + else if (obj instanceof Comment) { + printComment(out, (Comment) obj); + } + else if (obj instanceof ProcessingInstruction) { + printProcessingInstruction(out, (ProcessingInstruction) obj); + } + else if (obj instanceof DocType) { + printDocType(out, doc.getDocType()); + // Always print line separator after declaration, helps the + // output look better and is semantically inconsequential + out.write(currentFormat.lineSeparator); + } + else { + // XXX if we get here then we have a illegal content, for + // now we'll just ignore it + } + + newline(out); + indent(out, 0); + } + + // Output final line separator + // We output this no matter what the newline flags say + out.write(currentFormat.lineSeparator); + + out.flush(); + } + + /** + * Print out the {@link DocType}. + * + * @param doctype DocType to output. + * @param out Writer to use. + */ + public void output(DocType doctype, Writer out) throws IOException { + printDocType(out, doctype); + out.flush(); + } + + /** + * Print out an {@link Element}, including + * its {@link Attribute}s, and all + * contained (child) elements, etc. + * + * @param element Element to output. + * @param out Writer to use. + */ + public void output(Element element, Writer out) throws IOException { + // If this is the root element we could pre-initialize the + // namespace stack with the namespaces + printElement(out, element, 0, createNamespaceStack()); + out.flush(); + } + + /** + * This will handle printing out an {@link + * Element}'s content only, not including its tag, and + * attributes. This can be useful for printing the content of an + * element that contains HTML, like "<description>JDOM is + * <b>fun>!</description>". + * + * @param element Element to output. + * @param out Writer to use. + */ + public void outputElementContent(Element element, Writer out) + throws IOException { + List content = element.getContent(); + printContentRange(out, content, 0, content.size(), + 0, createNamespaceStack()); + out.flush(); + } + + /** + * This will handle printing out a list of nodes. + * This can be useful for printing the content of an element that + * contains HTML, like "<description>JDOM is + * <b>fun>!</description>". + * + * @param list List of nodes. + * @param out Writer to use. + */ + public void output(List list, Writer out) + throws IOException { + printContentRange(out, list, 0, list.size(), + 0, createNamespaceStack()); + out.flush(); + } + + /** + * Print out a {@link CDATA} node. + * + * @param cdata CDATA to output. + * @param out Writer to use. + */ + public void output(CDATA cdata, Writer out) throws IOException { + printCDATA(out, cdata); + out.flush(); + } + + /** + * Print out a {@link Text} node. Perfoms + * the necessary entity escaping and whitespace stripping. + * + * @param text Text to output. + * @param out Writer to use. + */ + public void output(Text text, Writer out) throws IOException { + printText(out, text); + out.flush(); + } + + /** + * Print out a {@link Comment}. + * + * @param comment Comment to output. + * @param out Writer to use. + */ + public void output(Comment comment, Writer out) throws IOException { + printComment(out, comment); + out.flush(); + } + + /** + * Print out a {@link ProcessingInstruction}. + * + * @param pi ProcessingInstruction to output. + * @param out Writer to use. + */ + public void output(ProcessingInstruction pi, Writer out) + throws IOException { + boolean currentEscapingPolicy = currentFormat.ignoreTrAXEscapingPIs; + + // Output PI verbatim, disregarding TrAX escaping PIs. + currentFormat.setIgnoreTrAXEscapingPIs(true); + printProcessingInstruction(out, pi); + currentFormat.setIgnoreTrAXEscapingPIs(currentEscapingPolicy); + + out.flush(); + } + + /** + * Print out a {@link EntityRef}. + * + * @param entity EntityRef to output. + * @param out Writer to use. + */ + public void output(EntityRef entity, Writer out) throws IOException { + printEntityRef(out, entity); + out.flush(); + } + + // * * * * * * * * * * Output to a String * * * * * * * * * * + // * * * * * * * * * * Output to a String * * * * * * * * * * + + /** + * Return a string representing a document. Uses an internal + * StringWriter. Warning: a String is Unicode, which may not match + * the outputter's specified encoding. + * + * @param doc Document to format. + */ + public String outputString(Document doc) { + StringWriter out = new StringWriter(); + try { + output(doc, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing a DocType. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param doctype DocType to format. + */ + public String outputString(DocType doctype) { + StringWriter out = new StringWriter(); + try { + output(doctype, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing an element. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param element Element to format. + */ + public String outputString(Element element) { + StringWriter out = new StringWriter(); + try { + output(element, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing a list of nodes. The list is + * assumed to contain legal JDOM nodes. + * + * @param list List to format. + */ + public String outputString(List list) { + StringWriter out = new StringWriter(); + try { + output(list, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing a CDATA node. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param cdata CDATA to format. + */ + public String outputString(CDATA cdata) { + StringWriter out = new StringWriter(); + try { + output(cdata, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing a Text node. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param text Text to format. + */ + public String outputString(Text text) { + StringWriter out = new StringWriter(); + try { + output(text, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + + /** + * Return a string representing a comment. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param comment Comment to format. + */ + public String outputString(Comment comment) { + StringWriter out = new StringWriter(); + try { + output(comment, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing a PI. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param pi ProcessingInstruction to format. + */ + public String outputString(ProcessingInstruction pi) { + StringWriter out = new StringWriter(); + try { + output(pi, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + /** + * Return a string representing an entity. Warning: a String is + * Unicode, which may not match the outputter's specified + * encoding. + * + * @param entity EntityRef to format. + */ + public String outputString(EntityRef entity) { + StringWriter out = new StringWriter(); + try { + output(entity, out); // output() flushes + } catch (IOException e) { } + return out.toString(); + } + + // * * * * * * * * * * Internal printing methods * * * * * * * * * * + // * * * * * * * * * * Internal printing methods * * * * * * * * * * + + /** + * This will handle printing of the declaration. + * Assumes XML version 1.0 since we don't directly know. + * + * @param doc Document whose declaration to write. + * @param out Writer to use. + * @param encoding The encoding to add to the declaration + */ + protected void printDeclaration(Writer out, Document doc, + String encoding) throws IOException { + + // Only print the declaration if it's not being omitted + if (!userFormat.omitDeclaration) { + // Assume 1.0 version + out.write(""); + + // Print new line after decl always, even if no other new lines + // Helps the output look better and is semantically + // inconsequential + out.write(currentFormat.lineSeparator); + } + } + + /** + * This handle printing the DOCTYPE declaration if one exists. + * + * @param docType Document whose declaration to write. + * @param out Writer to use. + */ + protected void printDocType(Writer out, DocType docType) + throws IOException { + + String publicID = docType.getPublicID(); + String systemID = docType.getSystemID(); + String internalSubset = docType.getInternalSubset(); + boolean hasPublic = false; + + out.write(""); + } + + /** + * This will handle printing of comments. + * + * @param comment Comment to write. + * @param out Writer to use. + */ + protected void printComment(Writer out, Comment comment) + throws IOException { + out.write(""); + } + + /** + * This will handle printing of processing instructions. + * + * @param pi ProcessingInstruction to write. + * @param out Writer to use. + */ + protected void printProcessingInstruction(Writer out, ProcessingInstruction pi + ) throws IOException { + String target = pi.getTarget(); + boolean piProcessed = false; + + if (currentFormat.ignoreTrAXEscapingPIs == false) { + if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING)) { + escapeOutput = false; + piProcessed = true; + } + else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING)) { + escapeOutput = true; + piProcessed = true; + } + } + if (piProcessed == false) { + String rawData = pi.getData(); + + // Write or if no data then just + if (!"".equals(rawData)) { + out.write(""); + } + else { + out.write(""); + } + } + } + + /** + * This will handle printing a {@link EntityRef}. + * Only the entity reference such as &entity; + * will be printed. However, subclasses are free to override + * this method to print the contents of the entity instead. + * + * @param entity EntityRef to output. + * @param out Writer to use. */ + protected void printEntityRef(Writer out, EntityRef entity) + throws IOException { + out.write("&"); + out.write(entity.getName()); + out.write(";"); + } + + /** + * This will handle printing of {@link CDATA} text. + * + * @param cdata CDATA to output. + * @param out Writer to use. + */ + protected void printCDATA(Writer out, CDATA cdata) throws IOException { + String str = (currentFormat.mode == Format.TextMode.NORMALIZE) + ? cdata.getTextNormalize() + : ((currentFormat.mode == Format.TextMode.TRIM) ? + cdata.getText().trim() : cdata.getText()); + out.write(""); + } + + /** + * This will handle printing of {@link Text} strings. + * + * @param text Text to write. + * @param out Writer to use. + */ + protected void printText(Writer out, Text text) throws IOException { + String str = (currentFormat.mode == Format.TextMode.NORMALIZE) + ? text.getTextNormalize() + : ((currentFormat.mode == Format.TextMode.TRIM) ? + text.getText().trim() : text.getText()); + out.write(escapeElementEntities(str)); + } + + /** + * This will handle printing a string. Escapes the element entities, + * trims interior whitespace, etc. if necessary. + */ + private void printString(Writer out, String str) throws IOException { + if (currentFormat.mode == Format.TextMode.NORMALIZE) { + str = Text.normalizeString(str); + } + else if (currentFormat.mode == Format.TextMode.TRIM) { + str = str.trim(); + } + out.write(escapeElementEntities(str)); + } + + /** + * This will handle printing of a {@link Element}, + * its {@link Attribute}s, and all contained (child) + * elements, etc. + * + * @param element Element to output. + * @param out Writer to use. + * @param level int level of indention. + * @param namespaces List stack of Namespaces in scope. + */ + protected void printElement(Writer out, Element element, + int level, NamespaceStack namespaces) + throws IOException { + + List attributes = element.getAttributes(); + List content = element.getContent(); + + // Check for xml:space and adjust format settings + String space = null; + if (attributes != null) { + space = element.getAttributeValue("space", + Namespace.XML_NAMESPACE); + } + + Format previousFormat = currentFormat; + + if ("default".equals(space)) { + currentFormat = userFormat; + } + else if ("preserve".equals(space)) { + currentFormat = preserveFormat; + } + + // Print the beginning of the tag plus attributes and any + // necessary namespace declarations + out.write("<"); + printQualifiedName(out, element); + + // Mark our namespace starting point + int previouslyDeclaredNamespaces = namespaces.size(); + + // Print the element's namespace, if appropriate + printElementNamespace(out, element, namespaces); + + // Print out additional namespace declarations + printAdditionalNamespaces(out, element, namespaces); + + // Print out attributes + if (attributes != null) + printAttributes(out, attributes, element, namespaces); + + // Depending on the settings (newlines, textNormalize, etc), we may + // or may not want to print all of the content, so determine the + // index of the start of the content we're interested + // in based on the current settings. + + int start = skipLeadingWhite(content, 0); + int size = content.size(); + if (start >= size) { + // Case content is empty or all insignificant whitespace + if (currentFormat.expandEmptyElements) { + out.write(">"); + } + else { + out.write(" />"); + } + } + else { + out.write(">"); + + // For a special case where the content is only CDATA + // or Text we don't want to indent after the start or + // before the end tag. + + if (nextNonText(content, start) < size) { + // Case Mixed Content - normal indentation + newline(out); + printContentRange(out, content, start, size, + level + 1, namespaces); + newline(out); + indent(out, level); + } + else { + // Case all CDATA or Text - no indentation + printTextRange(out, content, start, size); + } + out.write(""); + } + + // remove declared namespaces from stack + while (namespaces.size() > previouslyDeclaredNamespaces) { + namespaces.pop(); + } + + // Restore our format settings + currentFormat = previousFormat; + } + + /** + * This will handle printing of content within a given range. + * The range to print is specified in typical Java fashion; the + * starting index is inclusive, while the ending index is + * exclusive. + * + * @param content List of content to output + * @param start index of first content node (inclusive. + * @param end index of last content node (exclusive). + * @param out Writer to use. + * @param level int level of indentation. + * @param namespaces List stack of Namespaces in scope. + */ + private void printContentRange(Writer out, List content, + int start, int end, int level, + NamespaceStack namespaces) + throws IOException { + boolean firstNode; // Flag for 1st node in content + Object next; // Node we're about to print + int first, index; // Indexes into the list of content + + index = start; + while (index < end) { + firstNode = (index == start) ? true : false; + next = content.get(index); + + // + // Handle consecutive CDATA, Text, and EntityRef nodes all at once + // + if ((next instanceof Text) || (next instanceof EntityRef)) { + first = skipLeadingWhite(content, index); + // Set index to next node for loop + index = nextNonText(content, first); + + // If it's not all whitespace - print it! + if (first < index) { + if (!firstNode) + newline(out); + indent(out, level); + printTextRange(out, content, first, index); + } + continue; + } + + // + // Handle other nodes + // + if (!firstNode) { + newline(out); + } + + indent(out, level); + + if (next instanceof Comment) { + printComment(out, (Comment)next); + } + else if (next instanceof Element) { + printElement(out, (Element)next, level, namespaces); + } + else if (next instanceof ProcessingInstruction) { + printProcessingInstruction(out, (ProcessingInstruction)next); + } + else { + // XXX if we get here then we have a illegal content, for + // now we'll just ignore it (probably should throw + // a exception) + } + + index++; + } /* while */ + } + + /** + * This will handle printing of a sequence of {@link CDATA} + * or {@link Text} nodes. It is an error to have any other + * pass this method any other type of node. + * + * @param content List of content to output + * @param start index of first content node (inclusive). + * @param end index of last content node (exclusive). + * @param out Writer to use. + */ + private void printTextRange(Writer out, List content, int start, int end + ) throws IOException { + String previous; // Previous text printed + Object node; // Next node to print + String next; // Next text to print + + previous = null; + + // Remove leading whitespace-only nodes + start = skipLeadingWhite(content, start); + + int size = content.size(); + if (start < size) { + // And remove trialing whitespace-only nodes + end = skipTrailingWhite(content, end); + + for (int i = start; i < end; i++) { + node = content.get(i); + + // Get the unmangled version of the text + // we are about to print + if (node instanceof Text) { + next = ((Text) node).getText(); + } + else if (node instanceof EntityRef) { + next = "&" + ((EntityRef) node).getValue() + ";"; + } + else { + throw new IllegalStateException("Should see only " + + "CDATA, Text, or EntityRef"); + } + + // This may save a little time + if (next == null || "".equals(next)) { + continue; + } + + // Determine if we need to pad the output (padding is + // only need in trim or normalizing mode) + if (previous != null) { // Not 1st node + if (currentFormat.mode == Format.TextMode.NORMALIZE || + currentFormat.mode == Format.TextMode.TRIM) { + if ((endsWithWhite(previous)) || + (startsWithWhite(next))) { + out.write(" "); + } + } + } + + // Print the node + if (node instanceof CDATA) { + printCDATA(out, (CDATA) node); + } + else if (node instanceof EntityRef) { + printEntityRef(out, (EntityRef) node); + } + else { + printString(out, next); + } + + previous = next; + } + } + } + + /** + * This will handle printing of any needed {@link Namespace} + * declarations. + * + * @param ns Namespace to print definition of + * @param out Writer to use. + */ + private void printNamespace(Writer out, Namespace ns, + NamespaceStack namespaces) + throws IOException { + String prefix = ns.getPrefix(); + String uri = ns.getURI(); + + // Already printed namespace decl? + if (uri.equals(namespaces.getURI(prefix))) { + return; + } + + out.write(" xmlns"); + if (!prefix.equals("")) { + out.write(":"); + out.write(prefix); + } + out.write("=\""); + out.write(escapeAttributeEntities(uri)); + out.write("\""); + namespaces.push(ns); + } + + /** + * This will handle printing of a {@link Attribute} list. + * + * @param attributes List of Attribute objcts + * @param out Writer to use + */ + protected void printAttributes(Writer out, List attributes, Element parent, + NamespaceStack namespaces) + throws IOException { + + // I do not yet handle the case where the same prefix maps to + // two different URIs. For attributes on the same element + // this is illegal; but as yet we don't throw an exception + // if someone tries to do this + // Set prefixes = new HashSet(); + for (int i = 0; i < attributes.size(); i++) { + Attribute attribute = (Attribute) attributes.get(i); + Namespace ns = attribute.getNamespace(); + if ((ns != Namespace.NO_NAMESPACE) && + (ns != Namespace.XML_NAMESPACE)) { + printNamespace(out, ns, namespaces); + } + + out.write(" "); + printQualifiedName(out, attribute); + out.write("="); + + out.write("\""); + out.write(escapeAttributeEntities(attribute.getValue())); + out.write("\""); + } + } + + private void printElementNamespace(Writer out, Element element, + NamespaceStack namespaces) + throws IOException { + // Add namespace decl only if it's not the XML namespace and it's + // not the NO_NAMESPACE with the prefix "" not yet mapped + // (we do output xmlns="" if the "" prefix was already used and we + // need to reclaim it for the NO_NAMESPACE) + Namespace ns = element.getNamespace(); + if (ns == Namespace.XML_NAMESPACE) { + return; + } + if ( !((ns == Namespace.NO_NAMESPACE) && + (namespaces.getURI("") == null))) { + printNamespace(out, ns, namespaces); + } + } + + private void printAdditionalNamespaces(Writer out, Element element, + NamespaceStack namespaces) + throws IOException { + List list = element.getAdditionalNamespaces(); + if (list != null) { + for (int i = 0; i < list.size(); i++) { + Namespace additional = (Namespace)list.get(i); + printNamespace(out, additional, namespaces); + } + } + } + + // * * * * * * * * * * Support methods * * * * * * * * * * + // * * * * * * * * * * Support methods * * * * * * * * * * + + /** + * This will print a newline only if indent is not null. + * + * @param out Writer to use + */ + private void newline(Writer out) throws IOException { + if (currentFormat.indent != null) { + out.write(currentFormat.lineSeparator); + } + } + + /** + * This will print indents only if indent is not null or the empty string. + * + * @param out Writer to use + * @param level current indent level + */ + private void indent(Writer out, int level) throws IOException { + if (currentFormat.indent == null || + currentFormat.indent.equals("")) { + return; + } + + for (int i = 0; i < level; i++) { + out.write(currentFormat.indent); + } + } + + // Returns the index of the first non-all-whitespace CDATA or Text, + // index = content.size() is returned if content contains + // all whitespace. + // @param start index to begin search (inclusive) + private int skipLeadingWhite(List content, int start) { + if (start < 0) { + start = 0; + } + + int index = start; + int size = content.size(); + if (currentFormat.mode == Format.TextMode.TRIM_FULL_WHITE + || currentFormat.mode == Format.TextMode.NORMALIZE + || currentFormat.mode == Format.TextMode.TRIM) { + while (index < size) { + if (!isAllWhitespace(content.get(index))) { + return index; + } + index++; + } + } + return index; + } + + // Return the index + 1 of the last non-all-whitespace CDATA or + // Text node, index < 0 is returned + // if content contains all whitespace. + // @param start index to begin search (exclusive) + private int skipTrailingWhite(List content, int start) { + int size = content.size(); + if (start > size) { + start = size; + } + + int index = start; + if (currentFormat.mode == Format.TextMode.TRIM_FULL_WHITE + || currentFormat.mode == Format.TextMode.NORMALIZE + || currentFormat.mode == Format.TextMode.TRIM) { + while (index >= 0) { + if (!isAllWhitespace(content.get(index - 1))) + break; + --index; + } + } + return index; + } + + // Return the next non-CDATA, non-Text, or non-EntityRef node, + // index = content.size() is returned if there is no more non-CDATA, + // non-Text, or non-EntiryRef nodes + // @param start index to begin search (inclusive) + private static int nextNonText(List content, int start) { + if (start < 0) { + start = 0; + } + + int index = start; + int size = content.size(); + while (index < size) { + Object node = content.get(index); + if (!((node instanceof Text) || (node instanceof EntityRef))) { + return index; + } + index++; + } + return size; + } + + // Determine if a Object is all whitespace + private boolean isAllWhitespace(Object obj) { + String str = null; + + if (obj instanceof String) { + str = (String) obj; + } + else if (obj instanceof Text) { + str = ((Text) obj).getText(); + } + else if (obj instanceof EntityRef) { + return false; + } + else { + return false; + } + + for (int i = 0; i < str.length(); i++) { + if (!Verifier.isXMLWhitespace(str.charAt(i))) + return false; + } + return true; + } + + // Determine if a string starts with a XML whitespace. + private boolean startsWithWhite(String str) { + if ((str != null) && + (str.length() > 0) && + Verifier.isXMLWhitespace(str.charAt(0))) { + return true; + } + return false; + } + + // Determine if a string ends with a XML whitespace. + private boolean endsWithWhite(String str) { + if ((str != null) && + (str.length() > 0) && + Verifier.isXMLWhitespace(str.charAt(str.length() - 1))) { + return true; + } + return false; + } + + /** + * This will take the pre-defined entities in XML 1.0 and + * convert their character representation to the appropriate + * entity reference, suitable for XML attributes. It does not convert + * the single quote (') because it's not necessary as the outputter + * writes attributes surrounded by double-quotes. + * + * @param str String input to escape. + * @return String with escaped content. + * @throws IllegalArgumentException if an entity can not be escaped + */ + public String escapeAttributeEntities(String str) { + StringBuffer buffer; + int ch, pos; + String entity; + EscapeStrategy strategy = currentFormat.escapeStrategy; + + buffer = null; + for (int i = 0; i < str.length(); i++) { + ch = str.charAt(i); + pos = i; + switch(ch) { + case '<' : + entity = "<"; + break; + case '>' : + entity = ">"; + break; +/* + case '\'' : + entity = "'"; + break; +*/ + case '\"' : + entity = """; + break; + case '&' : + entity = "&"; + break; + case '\r' : + entity = " "; + break; + case '\t' : + entity = " "; + break; + case '\n' : + entity = " "; + break; + default : + + if (strategy.shouldEscape((char) ch)) { + // Make sure what we are escaping is not the + // Beginning of a multi-byte character. + if (Verifier.isHighSurrogate((char) ch)) { + // This is a the high of a surrogate pair + i++; + if (i < str.length()) { + char low = str.charAt(i); + if(!Verifier.isLowSurrogate(low)) { + throw new IllegalDataException("Could not decode surrogate pair 0x" + + Integer.toHexString(ch) + " / 0x" + Integer.toHexString(low)); + } + ch = Verifier.decodeSurrogatePair((char) ch, low); + } else { + throw new IllegalDataException("Surrogate pair 0x" + + Integer.toHexString(ch) + " truncated"); + } + } + entity = "&#x" + Integer.toHexString(ch) + ";"; + } + else { + entity = null; + } + break; + } + if (buffer == null) { + if (entity != null) { + // An entity occurred, so we'll have to use StringBuffer + // (allocate room for it plus a few more entities). + buffer = new StringBuffer(str.length() + 20); + // Copy previous skipped characters and fall through + // to pickup current character + buffer.append(str.substring(0, pos)); + buffer.append(entity); + } + } + else { + if (entity == null) { + buffer.append((char) ch); + } + else { + buffer.append(entity); + } + } + } + + // If there were any entities, return the escaped characters + // that we put in the StringBuffer. Otherwise, just return + // the unmodified input string. + return (buffer == null) ? str : buffer.toString(); + } + + + /** + * This will take the three pre-defined entities in XML 1.0 + * (used specifically in XML elements) and convert their character + * representation to the appropriate entity reference, suitable for + * XML element content. + * + * @param str String input to escape. + * @return String with escaped content. + * @throws IllegalArgumentException if an entity can not be escaped + */ + public String escapeElementEntities(String str) { + if (escapeOutput == false) return str; + + StringBuffer buffer; + int ch, pos; + String entity; + EscapeStrategy strategy = currentFormat.escapeStrategy; + + buffer = null; + for (int i = 0; i < str.length(); i++) { + ch = str.charAt(i); + pos = i; + switch(ch) { + case '<' : + entity = "<"; + break; + case '>' : + entity = ">"; + break; + case '&' : + entity = "&"; + break; + case '\r' : + entity = " "; + break; + case '\n' : + entity = currentFormat.lineSeparator; + break; + default : + + if (strategy.shouldEscape((char) ch)) { + + //make sure what we are escaping is not the + //beginning of a multi-byte character. + if(Verifier.isHighSurrogate((char) ch)) { + //this is a the high of a surrogate pair + i++; + if (i < str.length()) { + char low = str.charAt(i); + if(!Verifier.isLowSurrogate(low)) { + throw new IllegalDataException("Could not decode surrogate pair 0x" + + Integer.toHexString(ch) + " / 0x" + Integer.toHexString(low)); + } + ch = Verifier.decodeSurrogatePair((char) ch, low); + } else { + throw new IllegalDataException("Surrogate pair 0x" + + Integer.toHexString(ch) + " truncated"); + } + } + entity = "&#x" + Integer.toHexString(ch) + ";"; + } + else { + entity = null; + } + break; + } + if (buffer == null) { + if (entity != null) { + // An entity occurred, so we'll have to use StringBuffer + // (allocate room for it plus a few more entities). + buffer = new StringBuffer(str.length() + 20); + // Copy previous skipped characters and fall through + // to pickup current character + buffer.append(str.substring(0, pos)); + buffer.append(entity); + } + } + else { + if (entity == null) { + buffer.append((char) ch); + } + else { + buffer.append(entity); + } + } + } + + // If there were any entities, return the escaped characters + // that we put in the StringBuffer. Otherwise, just return + // the unmodified input string. + return (buffer == null) ? str : buffer.toString(); + } + + /** + * Returns a copy of this XMLOutputter. + */ + public Object clone() { + // Implementation notes: Since all state of an XMLOutputter is + // embodied in simple private instance variables, Object.clone + // can be used. Note that since Object.clone is totally + // broken, we must catch an exception that will never be + // thrown. + try { + return super.clone(); + } + catch (java.lang.CloneNotSupportedException e) { + // even though this should never ever happen, it's still + // possible to fool Java into throwing a + // CloneNotSupportedException. If that happens, we + // shouldn't swallow it. + throw new RuntimeException(e.toString()); + } + } + + /** + * Return a string listing of the settings for this + * XMLOutputter instance. + * + * @return a string listing the settings for this XMLOutputter instance + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < userFormat.lineSeparator.length(); i++) { + char ch = userFormat.lineSeparator.charAt(i); + switch (ch) { + case '\r': buffer.append("\\r"); + break; + case '\n': buffer.append("\\n"); + break; + case '\t': buffer.append("\\t"); + break; + default: buffer.append("[" + ((int)ch) + "]"); + break; + } + } + + return ( + "XMLOutputter[omitDeclaration = " + userFormat.omitDeclaration + ", " + + "encoding = " + userFormat.encoding + ", " + + "omitEncoding = " + userFormat.omitEncoding + ", " + + "indent = '" + userFormat.indent + "'" + ", " + + "expandEmptyElements = " + userFormat.expandEmptyElements + ", " + + "lineSeparator = '" + buffer.toString() + "', " + + "textMode = " + userFormat.mode + "]" + ); + } + + /** + * Factory for making new NamespaceStack objects. The NamespaceStack + * created is actually an inner class extending the package protected + * NamespaceStack, as a way to make NamespaceStack "friendly" toward + * subclassers. + */ + private NamespaceStack createNamespaceStack() { + // actually returns a XMLOutputter.NamespaceStack (see below) + return new NamespaceStack(); + } + + /** + * Our own null subclass of NamespaceStack. This plays a little + * trick with Java access protection. We want subclasses of + * XMLOutputter to be able to override protected methods that + * declare a NamespaceStack parameter, but we don't want to + * declare the parent NamespaceStack class as public. + */ + protected class NamespaceStack + extends org.jdom.output.NamespaceStack + { + } + + // Support method to print a name without using elt.getQualifiedName() + // and thus avoiding a StringBuffer creation and memory churn + private void printQualifiedName(Writer out, Element e) throws IOException { + if (e.getNamespace().getPrefix().length() == 0) { + out.write(e.getName()); + } + else { + out.write(e.getNamespace().getPrefix()); + out.write(':'); + out.write(e.getName()); + } + } + + // Support method to print a name without using att.getQualifiedName() + // and thus avoiding a StringBuffer creation and memory churn + private void printQualifiedName(Writer out, Attribute a) throws IOException { + String prefix = a.getNamespace().getPrefix(); + if ((prefix != null) && (!prefix.equals(""))) { + out.write(prefix); + out.write(':'); + out.write(a.getName()); + } + else { + out.write(a.getName()); + } + } + + // * * * * * * * * * * Deprecated methods * * * * * * * * * * + + /* The methods below here are deprecations of protected methods. We + * don't usually deprecate protected methods, so they're commented out. + * They're left here in case this mass deprecation causes people trouble. + * Since we're getting close to 1.0 it's actually better for people to + * raise issues early though. + */ + +} Index: 3rdParty_sources/jdom/org/jdom/output/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/output/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/output/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,15 @@ + + +Classes to output JDOM documents to various destinations. The most common +outputter class is XMLOutputter which outputs a document (or part of a +document) as a stream of bytes. Format and EscapeStrategy support the +XMLOutputter in letting you choose how the output should be formatted and how +special characters should be escaped. + +SAXOutputter lets you output as a stream of SAX events (handy especially in +transformations). JDOMLocator supports SAXOutputter and helps you observe the +SAX output process. + +DOMOutputter lets you output a JDOM document as a DOM tree. + + Index: 3rdParty_sources/jdom/org/jdom/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,13 @@ + + +Classes to represent the components of an XML document. The Verifier is a +special class useful in ensuring well-formedness of documents. The Parent +interface is implemented by Document and Element exposing their commonality. +The Content abstract class is extended by all the node types of a document +except Document itself. + +The JDOMFactory interface and DefaultJDOMFactory standard implementation +provide advanced users with the ability to create subtypes of the org.jdom +classes. + + Index: 3rdParty_sources/jdom/org/jdom/transform/JDOMResult.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/transform/JDOMResult.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/transform/JDOMResult.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,671 @@ +/*-- + + $Id$ + + Copyright (C) 2001-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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.transform; + +import java.util.*; + +import javax.xml.transform.sax.*; + +import org.jdom.*; +import org.jdom.input.*; +import org.xml.sax.*; +import org.xml.sax.ext.*; +import org.xml.sax.helpers.*; + +/** + * A holder for an XSL Transformation result, generally a list of nodes + * although it can be a JDOM Document also. As stated by the XSLT 1.0 + * specification, the result tree generated by an XSL transformation is not + * required to be a well-formed XML document. The result tree may have "any + * sequence of nodes as children that would be possible for an + * element node". + *

+ * The following example shows how to apply an XSL Transformation + * to a JDOM document and get the transformation result in the form + * of a list of JDOM nodes: + *


+ *   public static List transform(Document doc, String stylesheet)
+ *                                        throws JDOMException {
+ *     try {
+ *       Transformer transformer = TransformerFactory.newInstance()
+ *                             .newTransformer(new StreamSource(stylesheet));
+ *       JDOMSource in = new JDOMSource(doc);
+ *       JDOMResult out = new JDOMResult();
+ *       transformer.transform(in, out);
+ *       return out.getResult();
+ *     }
+ *     catch (TransformerException e) {
+ *       throw new JDOMException("XSLT Transformation failed", e);
+ *     }
+ *   }
+ * 
+ * + * @see org.jdom.transform.JDOMSource + * + * @version $Revision$, $Date$ + * @author Laurent Bihanic + * @author Jason Hunter + */ +public class JDOMResult extends SAXResult { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an + * argument, the Transformer natively supports JDOM. + *

+ * Note: This implementation does not override + * the {@link SAXResult#FEATURE} value defined by its superclass + * to be considered as a SAXResult by Transformer implementations + * not natively supporting JDOM.

+ */ + public final static String JDOM_FEATURE = + "http://org.jdom.transform.JDOMResult/feature"; + + /** + * The result of a transformation, as set by Transformer + * implementations that natively support JDOM, as a JDOM document + * or a list of JDOM nodes. + */ + private Object result = null; + + /** + * Whether the application queried the result (as a list or a + * document) since it was last set. + */ + private boolean queried = false; + + /** + * The custom JDOM factory to use when building the transformation + * result or null to use the default JDOM classes. + */ + private JDOMFactory factory = null; + + /** + * Public default constructor. + */ + public JDOMResult() { + // Allocate custom builder object... + DocumentBuilder builder = new DocumentBuilder(); + + // And use it as ContentHandler and LexicalHandler. + super.setHandler(builder); + super.setLexicalHandler(builder); + } + + /** + * Sets the object(s) produced as result of an XSL Transformation. + *

+ * Note: This method shall be used by the + * {@link javax.xml.transform.Transformer} implementations that + * natively support JDOM to directly set the transformation + * result rather than considering this object as a + * {@link SAXResult}. Applications should not use this + * method.

+ * + * @param result the result of a transformation as a + * {@link java.util.List list} of JDOM nodes + * (Elements, Texts, Comments, PIs...). + * + * @see #getResult + */ + public void setResult(List result) { + this.result = result; + this.queried = false; + } + + /** + * Returns the result of an XSL Transformation as a list of JDOM + * nodes. + *

+ * If the result of the transformation is a JDOM document, + * this method converts it into a list of JDOM nodes; any + * subsequent call to {@link #getDocument} will return + * null.

+ * + * @return the transformation result as a (possibly empty) list of + * JDOM nodes (Elements, Texts, Comments, PIs...). + */ + public List getResult() { + List nodes = Collections.EMPTY_LIST; + + // Retrieve result from the document builder if not set. + this.retrieveResult(); + + if (result instanceof List) { + nodes = (List)result; + } + else { + if ((result instanceof Document) && (queried == false)) { + List content = ((Document)result).getContent(); + nodes = new ArrayList(content.size()); + + while (content.size() != 0) + { + Object o = content.remove(0); + nodes.add(o); + } + result = nodes; + } + } + queried = true; + + return (nodes); + } + + /** + * Sets the document produced as result of an XSL Transformation. + *

+ * Note: This method shall be used by the + * {@link javax.xml.transform.Transformer} implementations that + * natively support JDOM to directly set the transformation + * result rather than considering this object as a + * {@link SAXResult}. Applications should not use this + * method.

+ * + * @param document the JDOM document result of a transformation. + * + * @see #setResult + * @see #getDocument + */ + public void setDocument(Document document) { + this.result = document; + this.queried = false; + } + + /** + * Returns the result of an XSL Transformation as a JDOM document. + *

+ * If the result of the transformation is a list of nodes, + * this method attempts to convert it into a JDOM document. If + * successful, any subsequent call to {@link #getResult} will + * return an empty list.

+ *

+ * Warning: The XSLT 1.0 specification states that + * the output of an XSL transformation is not a well-formed XML + * document but a list of nodes. Applications should thus use + * {@link #getResult} instead of this method or at least expect + * null documents to be returned. + * + * @return the transformation result as a JDOM document or + * null if the result of the transformation + * can not be converted into a well-formed document. + * + * @see #getResult + */ + public Document getDocument() { + Document doc = null; + + // Retrieve result from the document builder if not set. + this.retrieveResult(); + + if (result instanceof Document) { + doc = (Document)result; + } + else { + if ((result instanceof List) && (queried == false)) { + // Try to create a document from the result nodes + try { + JDOMFactory f = this.getFactory(); + if (f == null) { f = new DefaultJDOMFactory(); } + + doc = f.document(null); + doc.setContent((List)result); + + result = doc; + } + catch (RuntimeException ex1) { + // Some of the result nodes are not valid children of a + // Document node. => return null. + return null; + } + } + } + queried = true; + + return (doc); + } + + /** + * Sets a custom JDOMFactory to use when building the + * transformation result. Use a custom factory to build the tree + * with your own subclasses of the JDOM classes. + * + * @param factory the custom JDOMFactory to use or + * null to use the default JDOM + * classes. + * + * @see #getFactory + */ + public void setFactory(JDOMFactory factory) { + this.factory = factory; + } + + /** + * Returns the custom JDOMFactory used to build the transformation + * result. + * + * @return the custom JDOMFactory used to build the + * transformation result or null if the + * default JDOM classes are being used. + * + * @see #setFactory + */ + public JDOMFactory getFactory() { + return this.factory; + } + + /** + * Checks whether a transformation result has been set and, if not, + * retrieves the result tree being built by the document builder. + */ + private void retrieveResult() { + if (result == null) { + this.setResult(((DocumentBuilder)this.getHandler()).getResult()); + } + } + + //------------------------------------------------------------------------- + // SAXResult overwritten methods + //------------------------------------------------------------------------- + + /** + * Sets the target to be a SAX2 ContentHandler. + * + * @param handler Must be a non-null ContentHandler reference. + */ + public void setHandler(ContentHandler handler) { } + + /** + * Sets the SAX2 LexicalHandler for the output. + *

+ * This is needed to handle XML comments and the like. If the + * lexical handler is not set, an attempt should be made by the + * transformer to cast the ContentHandler to a LexicalHandler.

+ * + * @param handler A non-null LexicalHandler for + * handling lexical parse events. + */ + public void setLexicalHandler(LexicalHandler handler) { } + + + //========================================================================= + // FragmentHandler nested class + //========================================================================= + + private static class FragmentHandler extends SAXHandler { + /** + * A dummy root element required by SAXHandler that can only + * cope with well-formed documents. + */ + private Element dummyRoot = new Element("root", null, null); + + /** + * Public constructor. + */ + public FragmentHandler(JDOMFactory factory) { + super(factory); + + // Add a dummy root element to the being-built document as XSL + // transformation can output node lists instead of well-formed + // documents. + this.pushElement(dummyRoot); + } + + /** + * Returns the result of an XSL Transformation. + * + * @return the transformation result as a (possibly empty) list of + * JDOM nodes (Elements, Texts, Comments, PIs...). + */ + public List getResult() { + // Flush remaining text content in case the last text segment is + // outside an element. + try { + this.flushCharacters(); + } + catch (SAXException e) { /* Ignore... */ } + return this.getDetachedContent(dummyRoot); + } + + /** + * Returns the content of a JDOM Element detached from it. + * + * @param elt the element to get the content from. + * + * @return a (possibly empty) list of JDOM nodes, detached from + * their parent. + */ + private List getDetachedContent(Element elt) { + List content = elt.getContent(); + List nodes = new ArrayList(content.size()); + + while (content.size() != 0) + { + Object o = content.remove(0); + nodes.add(o); + } + return (nodes); + } + } + + //========================================================================= + // DocumentBuilder inner class + //========================================================================= + + private class DocumentBuilder extends XMLFilterImpl + implements LexicalHandler { + /** + * The actual JDOM document builder. + */ + private FragmentHandler saxHandler = null; + + /** + * Whether the startDocument event was received. Some XSLT + * processors such as Oracle's do not fire this event. + */ + private boolean startDocumentReceived = false; + + /** + * Public default constructor. + */ + public DocumentBuilder() { } + + /** + * Returns the result of an XSL Transformation. + * + * @return the transformation result as a (possibly empty) list of + * JDOM nodes (Elements, Texts, Comments, PIs...) or + * null if no new transformation occurred + * since the result of the previous one was returned. + */ + public List getResult() { + List result = null; + + if (this.saxHandler != null) { + // Retrieve result from SAX content handler. + result = this.saxHandler.getResult(); + + // Detach the (non-reusable) SAXHandler instance. + this.saxHandler = null; + + // And get ready for the next transformation. + this.startDocumentReceived = false; + } + return result; + } + + private void ensureInitialization() throws SAXException { + // Trigger document initialization if XSLT processor failed to + // fire the startDocument event. + if (this.startDocumentReceived == false) { + this.startDocument(); + } + } + + //----------------------------------------------------------------------- + // XMLFilterImpl overwritten methods + //----------------------------------------------------------------------- + + /** + * [SAX ContentHandler interface support] Processes a + * start of document event. + *

+ * This implementation creates a new JDOM document builder and + * marks the current result as "under construction".

+ * + * @throws SAXException if any error occurred while creating + * the document builder. + */ + public void startDocument() throws SAXException { + this.startDocumentReceived = true; + + // Reset any previously set result. + setResult(null); + + // Create the actual JDOM document builder and register it as + // ContentHandler on the superclass (XMLFilterImpl): this + // implementation will take care of propagating the LexicalHandler + // events. + this.saxHandler = new FragmentHandler(getFactory()); + super.setContentHandler(this.saxHandler); + + // And propagate event. + super.startDocument(); + } + + /** + * [SAX ContentHandler interface support] Receives + * notification of the beginning of an element. + *

+ * This implementation ensures that startDocument() has been + * called prior processing an element. + * + * @param nsURI the Namespace URI, or the empty string if + * the element has no Namespace URI or if + * Namespace processing is not being performed. + * @param localName the local name (without prefix), or the + * empty string if Namespace processing is + * not being performed. + * @param qName the qualified name (with prefix), or the + * empty string if qualified names are not + * available. + * @param atts The attributes attached to the element. If + * there are no attributes, it shall be an + * empty Attributes object. + * + * @throws SAXException if any error occurred while creating + * the document builder. + */ + public void startElement(String nsURI, String localName, String qName, + Attributes atts) throws SAXException + { + this.ensureInitialization(); + super.startElement(nsURI, localName, qName, atts); + } + + /** + * [SAX ContentHandler interface support] Begins the + * scope of a prefix-URI Namespace mapping. + */ + public void startPrefixMapping(String prefix, String uri) + throws SAXException { + this.ensureInitialization(); + super.startPrefixMapping(prefix, uri); + } + + /** + * [SAX ContentHandler interface support] Receives + * notification of character data. + */ + public void characters(char ch[], int start, int length) + throws SAXException { + this.ensureInitialization(); + super.characters(ch, start, length); + } + + /** + * [SAX ContentHandler interface support] Receives + * notification of ignorable whitespace in element content. + */ + public void ignorableWhitespace(char ch[], int start, int length) + throws SAXException { + this.ensureInitialization(); + super.ignorableWhitespace(ch, start, length); + } + + /** + * [SAX ContentHandler interface support] Receives + * notification of a processing instruction. + */ + public void processingInstruction(String target, String data) + throws SAXException { + this.ensureInitialization(); + super.processingInstruction(target, data); + } + + /** + * [SAX ContentHandler interface support] Receives + * notification of a skipped entity. + */ + public void skippedEntity(String name) throws SAXException { + this.ensureInitialization(); + super.skippedEntity(name); + } + + //----------------------------------------------------------------------- + // LexicalHandler interface support + //----------------------------------------------------------------------- + + /** + * [SAX LexicalHandler interface support] Reports the + * start of DTD declarations, if any. + * + * @param name the document type name. + * @param publicId the declared public identifier for the + * external DTD subset, or null + * if none was declared. + * @param systemId the declared system identifier for the + * external DTD subset, or null + * if none was declared. + * + * @throws SAXException The application may raise an exception. + */ + public void startDTD(String name, String publicId, String systemId) + throws SAXException { + this.ensureInitialization(); + this.saxHandler.startDTD(name, publicId, systemId); + } + + /** + * [SAX LexicalHandler interface support] Reports the end + * of DTD declarations. + * + * @throws SAXException The application may raise an exception. + */ + public void endDTD() throws SAXException { + this.saxHandler.endDTD(); + } + + /** + * [SAX LexicalHandler interface support] Reports the + * beginning of some internal and external XML entities. + * + * @param name the name of the entity. If it is a parameter + * entity, the name will begin with '%', and if it + * is the external DTD subset, it will be "[dtd]". + * + * @throws SAXException The application may raise an exception. + */ + public void startEntity(String name) throws SAXException { + this.ensureInitialization(); + this.saxHandler.startEntity(name); + } + + /** + * [SAX LexicalHandler interface support] Reports the end + * of an entity. + * + * @param name the name of the entity that is ending. + * + * @throws SAXException The application may raise an exception. + */ + public void endEntity(String name) throws SAXException { + this.saxHandler.endEntity(name); + } + + /** + * [SAX LexicalHandler interface support] Reports the + * start of a CDATA section. + * + * @throws SAXException The application may raise an exception. + */ + public void startCDATA() throws SAXException { + this.ensureInitialization(); + this.saxHandler.startCDATA(); + } + + /** + * [SAX LexicalHandler interface support] Reports the end + * of a CDATA section. + * + * @throws SAXException The application may raise an exception. + */ + public void endCDATA() throws SAXException { + this.saxHandler.endCDATA(); + } + + /** + * [SAX LexicalHandler interface support] Reports an XML + * comment anywhere in the document. + * + * @param ch an array holding the characters in the comment. + * @param start the starting position in the array. + * @param length the number of characters to use from the array. + * + * @throws SAXException The application may raise an exception. + */ + public void comment(char ch[], int start, int length) + throws SAXException { + this.ensureInitialization(); + this.saxHandler.comment(ch, start, length); + } + } +} + Index: 3rdParty_sources/jdom/org/jdom/transform/JDOMSource.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/transform/JDOMSource.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/transform/JDOMSource.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,553 @@ +/*-- + + $Id$ + + Copyright (C) 2001-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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.transform; + +import java.io.*; +import java.util.*; + +import javax.xml.transform.sax.*; + +import org.jdom.*; +import org.jdom.output.*; +import org.xml.sax.*; + +/** + * A holder for an XML Transformation source: a Document, Element, or list of + * nodes. + *

+ * The is provides input to a + * {@link javax.xml.transform.Transformer JAXP TrAX Transformer}. + *

+ * The following example shows how to apply an XSL Transformation + * to a JDOM document and get the transformation result in the form + * of a list of JDOM nodes: + *


+ *   public static List transform(Document doc, String stylesheet)
+ *                                        throws JDOMException {
+ *     try {
+ *       Transformer transformer = TransformerFactory.newInstance()
+ *                             .newTransformer(new StreamSource(stylesheet));
+ *       JDOMSource in = new JDOMSource(doc);
+ *       JDOMResult out = new JDOMResult();
+ *       transformer.transform(in, out);
+ *       return out.getResult();
+ *     }
+ *     catch (TransformerException e) {
+ *       throw new JDOMException("XSLT Transformation failed", e);
+ *     }
+ *   }
+ * 
+ * + * @see org.jdom.transform.JDOMResult + * + * @version $Revision$, $Date$ + * @author Laurent Bihanic + * @author Jason Hunter + */ +public class JDOMSource extends SAXSource { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an + * argument, the Transformer natively supports JDOM. + *

+ * Note: This implementation does not override + * the {@link SAXSource#FEATURE} value defined by its superclass + * to be considered as a SAXSource by Transformer implementations + * not natively supporting JDOM. + *

+ */ + public final static String JDOM_FEATURE = + "http://org.jdom.transform.JDOMSource/feature"; + + /** + * The XMLReader object associated to this source or + * null if no XMLReader has yet been requested. + * + * @see #getXMLReader + */ + private XMLReader xmlReader = null; + + /** + * Optional entity resolver associated to the source of + * this document or null if no EntityResolver + * was supplied with this JDOMSource. + * + * @see #buildDocumentReader() + */ + private EntityResolver resolver = null; + + /** + * Creates a JDOM TrAX source wrapping a JDOM document. + * + * @param source the JDOM document to use as source for the + * transformations + * + * @throws IllegalArgumentException if source is + * null. + */ + public JDOMSource(Document source) { + setDocument(source); + } + + /** + * Creates a JDOM TrAX source wrapping a list of JDOM nodes. + * + * @param source the JDOM nodes to use as source for the + * transformations + * + * @throws IllegalArgumentException if source is + * null. + */ + public JDOMSource(List source) { + setNodes(source); + } + + /** + * Creates a JDOM TrAX source wrapping a JDOM element. + * + * @param source the JDOM element to use as source for the + * transformations + * + * @throws IllegalArgumentException if source is + * null. + */ + public JDOMSource(Element source) { + List nodes = new ArrayList(); + nodes.add(source); + + setNodes(nodes); + } + + /** + * Creates a JDOM TrAX source wrapping a JDOM element with an + * associated EntityResolver to resolve external entities. + * + * @param source The JDOM Element to use as source for the + * transformations + * + * @param resolver Entity resolver to use for the source + * transformation + * + * @throws IllegalArgumentException ifsource is + * null + */ + public JDOMSource(Document source, EntityResolver resolver) { + setDocument(source); + this.resolver = resolver; + } + +/** + * Sets the source document used by this TrAX source. + * + * @param source the JDOM document to use as source for the + * transformations + * + * @throws IllegalArgumentException if source is + * null. + * + * @see #getDocument + */ + public void setDocument(Document source) { + super.setInputSource(new JDOMInputSource(source)); + } + + /** + * Returns the source document used by this TrAX source. + * + * @return the source document used by this TrAX source or + * null if the source is a node list. + * + * @see #setDocument + */ + public Document getDocument() { + Object src = ((JDOMInputSource)getInputSource()).getSource(); + Document doc = null; + + if (src instanceof Document) { + doc = (Document)src; + } + return doc; + } + + /** + * Sets the source node list used by this TrAX source. + * + * @param source the JDOM nodes to use as source for the + * transformations + * + * @throws IllegalArgumentException if source is + * null. + * + * @see #getNodes + */ + public void setNodes(List source) { + super.setInputSource(new JDOMInputSource(source)); + } + + /** + * Returns the source node list used by this TrAX source. + * + * @return the source node list used by this TrAX source or + * null if the source is a JDOM document. + * + * @see #setDocument + */ + public List getNodes() { + Object src = ((JDOMInputSource)getInputSource()).getSource(); + List nodes = null; + + if (src instanceof List) { + nodes = (List)src; + } + return nodes; + } + + + //------------------------------------------------------------------------- + // SAXSource overwritten methods + //------------------------------------------------------------------------- + + /** + * Sets the SAX InputSource to be used for the Source. + *

+ * As this implementation only supports JDOM document as data + * source, this method always throws an + * {@link UnsupportedOperationException}. + *

+ * + * @param inputSource a valid InputSource reference. + * + * @throws UnsupportedOperationException always! + */ + public void setInputSource(InputSource inputSource) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + /** + * Set the XMLReader to be used for the Source. + *

+ * As this implementation only supports JDOM document as data + * source, this method throws an + * {@link UnsupportedOperationException} if the provided reader + * object does not implement the SAX {@link XMLFilter} + * interface. Otherwise, the JDOM document reader will be + * attached as parent of the filter chain.

+ * + * @param reader a valid XMLReader or XMLFilter reference. + * + * @throws UnsupportedOperationException if reader + * is not a SAX + * {@link XMLFilter}. + * @see #getXMLReader + */ + public void setXMLReader(XMLReader reader) + throws UnsupportedOperationException { + if (reader instanceof XMLFilter) { + // Connect the filter chain to a document reader. + XMLFilter filter = (XMLFilter)reader; + while (filter.getParent() instanceof XMLFilter) { + filter = (XMLFilter)(filter.getParent()); + } + filter.setParent(buildDocumentReader()); + + // Read XML data from filter chain. + this.xmlReader = reader; + } + else { + throw new UnsupportedOperationException(); + } + } + + /** + * Returns the XMLReader to be used for the Source. + *

+ * This implementation returns a specific XMLReader reading + * the XML data from the source JDOM document. + *

+ * + * @return an XMLReader reading the XML data from the source + * JDOM document. + */ + public XMLReader getXMLReader() { + if (this.xmlReader == null) { + this.xmlReader = buildDocumentReader(); + } + return this.xmlReader; + } + + /** + * Build an XMLReader to be used for the source. This will + * create a new instance of DocumentReader with an + * EntityResolver instance if available. + * + * @return XMLReader reading the XML data from the source + * JDOM document with an optional EntityResolver + */ + private XMLReader buildDocumentReader() { + DocumentReader reader = new DocumentReader(); + if (resolver != null) + reader.setEntityResolver(resolver); + return reader; + } + + //========================================================================= + // JDOMInputSource nested class + //========================================================================= + + /** + * A subclass of the SAX InputSource interface that wraps a JDOM + * Document. + *

+ * This class is nested in JDOMSource as it is not intented to + * be used independently of its friend: DocumentReader. + *

+ * + * @see org.jdom.Document + */ + private static class JDOMInputSource extends InputSource { + /** + * The source as a JDOM document or a list of JDOM nodes. + */ + private Object source = null; + + /** + * Builds a InputSource wrapping the specified JDOM Document. + * + * @param document the source document. + */ + public JDOMInputSource(Document document) { + this.source = document; + } + + /** + * Builds a InputSource wrapping a list of JDOM nodes. + * + * @param nodes the source JDOM nodes. + */ + public JDOMInputSource(List nodes) { + this.source = nodes; + } + + /** + * Returns the source. + * + * @return the source as a JDOM document or a list of JDOM nodes. + */ + public Object getSource() { + return source; + } + + //------------------------------------------------------------------------- + // InputSource overwritten methods + //------------------------------------------------------------------------- + + /** + * Sets the character stream for this input source. + *

+ * This implementation always throws an + * {@link UnsupportedOperationException} as the only source + * stream supported is the source JDOM document. + *

+ * + * @param characterStream a character stream containing + * an XML document. + * + * @throws UnsupportedOperationException always! + */ + public void setCharacterStream(Reader characterStream) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + /** + * Gets the character stream for this input source. + *

+ * Note that this method is only provided to make this + * InputSource implementation acceptable by any XML + * parser. As it generates an in-memory string representation + * of the JDOM document, it is quite inefficient from both + * speed and memory consumption points of view. + *

+ * + * @return a Reader to a string representation of the + * source JDOM document. + */ + public Reader getCharacterStream() { + Object src = this.getSource(); + Reader reader = null; + + if (src instanceof Document) { + // Get an in-memory string representation of the document + // and return a reader on it. + reader = new StringReader( + new XMLOutputter().outputString((Document)src)); + } + else { + if (src instanceof List) { + reader = new StringReader( + new XMLOutputter().outputString((List)src)); + } + // Else: No source, no reader! + } + return reader; + } + /** + * Sets the byte stream for this input source. + *

+ * This implementation always throws an + * {@link UnsupportedOperationException} as the only source + * stream supported is the source JDOM document. + *

+ * + * @param byteStream a byte stream containing + * an XML document. + * + * @throws UnsupportedOperationException always! + */ + public void setByteStream(InputStream byteStream) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + } + + //========================================================================= + // DocumentReader nested class + //========================================================================= + + /** + * An implementation of the SAX2 XMLReader interface that presents + * a SAX view of a JDOM Document. The actual generation of the + * SAX events is delegated to JDOM's SAXOutputter. + * + * @see org.jdom.Document + * @see org.jdom.output.SAXOutputter + */ + private static class DocumentReader extends SAXOutputter + implements XMLReader { + /** + * Public default constructor. + */ + public DocumentReader() { + super(); + } + + //---------------------------------------------------------------------- + // SAX XMLReader interface support + //---------------------------------------------------------------------- + + /** + * Parses an XML document from a system identifier (URI). + *

+ * This implementation does not support reading XML data from + * system identifiers, only from JDOM documents. Hence, + * this method always throws a {@link SAXNotSupportedException}. + *

+ * + * @param systemId the system identifier (URI). + * + * @throws SAXNotSupportedException always! + */ + public void parse(String systemId) throws SAXNotSupportedException { + throw new SAXNotSupportedException( + "Only JDOM Documents are supported as input"); + } + + /** + * Parses an XML document. + *

+ * The methods accepts only JDOMInputSources + * instances as input sources. + *

+ * + * @param input the input source for the top-level of the + * XML document. + * + * @throws SAXException any SAX exception, + * possibly wrapping + * another exception. + * @throws SAXNotSupportedException if the input source does + * not wrap a JDOM document. + */ + public void parse(InputSource input) throws SAXException { + if (input instanceof JDOMInputSource) { + try { + Object source = ((JDOMInputSource)input).getSource(); + if (source instanceof Document) { + this.output((Document)source); + } + else { + this.output((List)source); + } + } + catch (JDOMException e) { + throw new SAXException(e.getMessage(), e); + } + } + else { + throw new SAXNotSupportedException( + "Only JDOM Documents are supported as input"); + } + } + } +} + Index: 3rdParty_sources/jdom/org/jdom/transform/XSLTransformException.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/transform/XSLTransformException.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/transform/XSLTransformException.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,82 @@ +/*-- + + $Id$ + + Copyright (C) 2003-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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.transform; + +import org.jdom.JDOMException; + +/** + * Thrown when an XSL stylesheet fails to compile or an XSL transform fails + * + * @version $Revision$, $Date$ + * @author Jason Hunter + */ +public class XSLTransformException extends JDOMException { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + public XSLTransformException() { + } + + public XSLTransformException(String message) { + super(message); + } + + public XSLTransformException(String message, Exception cause) { + super(message, cause); + } +} Index: 3rdParty_sources/jdom/org/jdom/transform/XSLTransformer.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/transform/XSLTransformer.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/transform/XSLTransformer.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,291 @@ +/*-- + + $Id$ + + Copyright (C) 2001-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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.transform; + +import java.util.*; +import java.io.*; +import javax.xml.transform.*; +import javax.xml.transform.stream.StreamSource; +import org.jdom.*; +import org.xml.sax.EntityResolver; + +/** + * A convenience class to handle simple transformations. The JAXP TrAX classes + * have more bells and whistles and can be used with {@link JDOMSource} and + * {@link JDOMResult} for advanced uses. This class handles the common case and + * presents a simple interface. XSLTransformer is thread safe and may be + * used from multiple threads. + * + *

+ * XSLTransformer transformer = new XSLTransformer("file.xsl");
+ *
+ * Document x2 = transformer.transform(x);  // x is a Document
+ * Document y2 = transformer.transform(y);  // y is a Document
+ * 
+ * + * JDOM relies on TrAX to perform the transformation. + * The javax.xml.transform.TransformerFactory Java system property + * determines which XSLT engine TrAX uses. Its value should be + * the fully qualified name of the implementation of the abstract + * javax.xml.transform.TransformerFactory class. + * Values of this property for popular XSLT processors include: + *

+ *
  • Saxon 6.x: com.icl.saxon.TransformerFactoryImpl
  • + *
  • Saxon 7.x: net.sf.saxon.TransformerFactoryImpl
  • + *
  • Xalan: org.apache.xalan.processor.TransformerFactoryImpl
  • + *
  • jd.xslt: jd.xml.xslt.trax.TransformerFactoryImpl
  • + *
  • Oracle: oracle.xml.jaxp.JXSAXTransformerFactory
  • + *
+ *

+ * This property can be set in all the usual ways a Java system property + * can be set. TrAX picks from them in this order:

+ *
    + *
  1. Invoking System.setProperty( "javax.xml.transform.TransformerFactory", + * "classname")
  2. + *
  3. The value specified at the command line using the + * -Djavax.xml.transform.TransformerFactory=classname + * option to the java interpreter
  4. + *
  5. The class named in the lib/jaxp.properties properties file + * in the JRE directory, in a line like this one: + *
    javax.xml.parsers.DocumentBuilderFactory=classname
  6. + *
  7. The class named in the + * META-INF/services/javax.xml.transform.TransformerFactory file + * in the JAR archives available to the runtime
  8. + *
  9. Finally, if all of the above options fail, + * a default implementation is chosen. In Sun's JDK 1.4, this is + * Xalan 2.2d10.
  10. + *
+ + * @version $Revision$, $Date$ + * @author Jason Hunter + * @author Elliotte Rusty Harold + */ +public class XSLTransformer { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + private Templates templates; + + /** + * The custom JDOM factory to use when building the transformation + * result or null to use the default JDOM classes. + */ + private JDOMFactory factory = null; + + // Internal constructor to support the other constructors + private XSLTransformer(Source stylesheet) throws XSLTransformException { + try { + templates = TransformerFactory.newInstance() + .newTemplates(stylesheet); + } + catch (TransformerException e) { + throw new XSLTransformException("Could not construct XSLTransformer", e); + } + } + + /** + * Creates a transformer for a given stylesheet system id. + * + * @param stylesheetSystemId source stylesheet as a Source object + * @throws XSLTransformException if there's a problem in the TrAX back-end + */ + public XSLTransformer(String stylesheetSystemId) throws XSLTransformException { + this(new StreamSource(stylesheetSystemId)); + } + + /** + *

+ * This will create a new XSLTransformer by + * reading the stylesheet from the specified + * InputStream. + *

+ * + * @param stylesheet InputStream from which the stylesheet is read. + * @throws XSLTransformException when an IOException, format error, or + * something else prevents the stylesheet from being compiled + */ + public XSLTransformer(InputStream stylesheet) throws XSLTransformException { + this(new StreamSource(stylesheet)); + } + + /** + *

+ * This will create a new XSLTransformer by + * reading the stylesheet from the specified + * Reader. + *

+ * + * @param stylesheet Reader from which the stylesheet is read. + * @throws XSLTransformException when an IOException, format error, or + * something else prevents the stylesheet from being compiled + */ + public XSLTransformer(Reader stylesheet) throws XSLTransformException { + this(new StreamSource(stylesheet)); + } + + /** + *

+ * This will create a new XSLTransformer by + * reading the stylesheet from the specified + * File. + *

+ * + * @param stylesheet File from which the stylesheet is read. + * @throws XSLTransformException when an IOException, format error, or + * something else prevents the stylesheet from being compiled + */ + public XSLTransformer(File stylesheet) throws XSLTransformException { + this(new StreamSource(stylesheet)); + } + + /** + *

+ * This will create a new XSLTransformer by + * reading the stylesheet from the specified + * Document. + *

+ * + * @param stylesheet Document containing the stylesheet. + * @throws XSLTransformException when the supplied Document + * is not syntactically correct XSLT + */ + public XSLTransformer(Document stylesheet) throws XSLTransformException { + this(new JDOMSource(stylesheet)); + } + + /** + * Transforms the given input nodes to a list of output nodes. + * + * @param inputNodes input nodes + * @return transformed output nodes + * @throws XSLTransformException if there's a problem in the transformation + */ + public List transform(List inputNodes) throws XSLTransformException { + JDOMSource source = new JDOMSource(inputNodes); + JDOMResult result = new JDOMResult(); + result.setFactory(factory); // null ok + try { + templates.newTransformer().transform(source, result); + return result.getResult(); + } + catch (TransformerException e) { + throw new XSLTransformException("Could not perform transformation", e); + } + } + + /** + * Transforms the given document to an output document. + * + * @param inputDoc input document + * @return transformed output document + * @throws XSLTransformException if there's a problem in the transformation + */ + public Document transform(Document inputDoc) throws XSLTransformException { + return transform(inputDoc, null); + } + + /** + * Transforms the given document to an output document. + * + * @param inputDoc input document + * @param resolver entity resolver for the input document + * @return transformed output document + * @throws XSLTransformException if there's a problem in the transformation + */ + public Document transform(Document inputDoc, EntityResolver resolver) throws XSLTransformException { + JDOMSource source = new JDOMSource(inputDoc, resolver); + JDOMResult result = new JDOMResult(); + result.setFactory(factory); // null ok + try { + templates.newTransformer().transform(source, result); + return result.getDocument(); + } + catch (TransformerException e) { + throw new XSLTransformException("Could not perform transformation", e); + } + } + + /** + * Sets a custom JDOMFactory to use when building the + * transformation result. Use a custom factory to build the tree + * with your own subclasses of the JDOM classes. + * + * @param factory the custom JDOMFactory to use or + * null to use the default JDOM + * classes. + * + * @see #getFactory + */ + public void setFactory(JDOMFactory factory) { + this.factory = factory; + } + + /** + * Returns the custom JDOMFactory used to build the transformation + * result. + * + * @return the custom JDOMFactory used to build the + * transformation result or null if the + * default JDOM classes are being used. + * + * @see #setFactory + */ + public JDOMFactory getFactory() { + return this.factory; + } +} Index: 3rdParty_sources/jdom/org/jdom/transform/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/transform/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/transform/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,8 @@ + + +Classes to help with transformations, based on the JAXP TrAX classes. +JDOMTransformer supports simple transformations with one line of code. +Advanced features are available with the JDOMSource and JDOMResult classes +that interface with TrAX. + + Index: 3rdParty_sources/jdom/org/jdom/xpath/JaxenXPath.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/xpath/JaxenXPath.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/xpath/JaxenXPath.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,356 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.xpath; + + +import java.util.*; + +import org.jaxen.*; +import org.jaxen.jdom.*; +import org.jdom.*; + + +/** + * A non-public concrete XPath implementation for Jaxen. + * + * @version $Revision$, $Date$ + * @author Laurent Bihanic + */ +class JaxenXPath extends XPath { // package protected + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * The compiled XPath object to select nodes. This attribute can + * not be made final as it needs to be set upon object + * deserialization. + */ + private transient JDOMXPath xPath; + + /** + * The current context for XPath expression evaluation. + */ + private Object currentContext; + + /** + * Creates a new XPath wrapper object, compiling the specified + * XPath expression. + * + * @param expr the XPath expression to wrap. + * + * @throws JDOMException if the XPath expression is invalid. + */ + public JaxenXPath(String expr) throws JDOMException { + setXPath(expr); + } + + /** + * Evaluates the wrapped XPath expression and returns the list + * of selected items. + * + * @param context the node to use as context for evaluating + * the XPath expression. + * + * @return the list of selected items, which may be of types: {@link Element}, + * {@link Attribute}, {@link Text}, {@link CDATA}, + * {@link Comment}, {@link ProcessingInstruction}, Boolean, + * Double, or String. + * + * @throws JDOMException if the evaluation of the XPath + * expression on the specified context + * failed. + */ + public List selectNodes(Object context) throws JDOMException { + try { + currentContext = context; + + return xPath.selectNodes(context); + } + catch (JaxenException ex1) { + throw new JDOMException("XPath error while evaluating \"" + + xPath.toString() + "\": " + ex1.getMessage(), ex1); + } + finally { + currentContext = null; + } + } + + /** + * Evaluates the wrapped XPath expression and returns the first + * entry in the list of selected nodes (or atomics). + * + * @param context the node to use as context for evaluating + * the XPath expression. + * + * @return the first selected item, which may be of types: {@link Element}, + * {@link Attribute}, {@link Text}, {@link CDATA}, + * {@link Comment}, {@link ProcessingInstruction}, Boolean, + * Double, String, or null if no item was selected. + * + * @throws JDOMException if the evaluation of the XPath + * expression on the specified context + * failed. + */ + public Object selectSingleNode(Object context) throws JDOMException { + try { + currentContext = context; + + return xPath.selectSingleNode(context); + } + catch (JaxenException ex1) { + throw new JDOMException("XPath error while evaluating \"" + + xPath.toString() + "\": " + ex1.getMessage(), ex1); + } + finally { + currentContext = null; + } + } + + /** + * Returns the string value of the first node selected by applying + * the wrapped XPath expression to the given context. + * + * @param context the element to use as context for evaluating + * the XPath expression. + * + * @return the string value of the first node selected by applying + * the wrapped XPath expression to the given context. + * + * @throws JDOMException if the XPath expression is invalid or + * its evaluation on the specified context + * failed. + */ + public String valueOf(Object context) throws JDOMException { + try { + currentContext = context; + + return xPath.stringValueOf(context); + } + catch (JaxenException ex1) { + throw new JDOMException("XPath error while evaluating \"" + + xPath.toString() + "\": " + ex1.getMessage(), ex1); + } + finally { + currentContext = null; + } + } + + /** + * Returns the number value of the first item selected by applying + * the wrapped XPath expression to the given context. + * + * @param context the element to use as context for evaluating + * the XPath expression. + * + * @return the number value of the first item selected by applying + * the wrapped XPath expression to the given context, + * null if no node was selected or the + * special value {@link java.lang.Double#NaN} + * (Not-a-Number) if the selected value can not be + * converted into a number value. + * + * @throws JDOMException if the XPath expression is invalid or + * its evaluation on the specified context + * failed. + */ + public Number numberValueOf(Object context) throws JDOMException { + try { + currentContext = context; + + return xPath.numberValueOf(context); + } + catch (JaxenException ex1) { + throw new JDOMException("XPath error while evaluating \"" + + xPath.toString() + "\": " + ex1.getMessage(), ex1); + } + finally { + currentContext = null; + } + } + + /** + * Defines an XPath variable and sets its value. + * + * @param name the variable name. + * @param value the variable value. + * + * @throws IllegalArgumentException if name is not + * a valid XPath variable name + * or if the value type is not + * supported by the underlying + * implementation + */ + public void setVariable(String name, Object value) + throws IllegalArgumentException { + Object o = xPath.getVariableContext(); + if (o instanceof SimpleVariableContext) { + ((SimpleVariableContext)o).setVariableValue(null, name, value); + } + } + + /** + * Adds a namespace definition to the list of namespaces known of + * this XPath expression. + *

+ * Note: In XPath, there is no such thing as a + * 'default namespace'. The empty prefix always resolves + * to the empty namespace URI.

+ * + * @param namespace the namespace. + */ + public void addNamespace(Namespace namespace) { + try { + xPath.addNamespace(namespace.getPrefix(), namespace.getURI()); + } + catch (JaxenException ex1) { /* Can't happen here. */ } + } + + /** + * Returns the wrapped XPath expression as a string. + * + * @return the wrapped XPath expression as a string. + */ + public String getXPath() { + return (xPath.toString()); + } + + /** + * Compiles and sets the XPath expression wrapped by this object. + * + * @param expr the XPath expression to wrap. + * + * @throws JDOMException if the XPath expression is invalid. + */ + private void setXPath(String expr) throws JDOMException { + try { + xPath = new JDOMXPath(expr); + xPath.setNamespaceContext(new NSContext()); + } + catch (Exception ex1) { + throw new JDOMException( + "Invalid XPath expression: \"" + expr + "\"", ex1); + } + } + + public String toString() { + return (xPath.toString()); + } + + public boolean equals(Object o) { + if (o instanceof JaxenXPath) { + JaxenXPath x = (JaxenXPath)o; + + return (super.equals(o) && + xPath.toString().equals(x.xPath.toString())); + } + return false; + } + + public int hashCode() { + return xPath.hashCode(); + } + + private class NSContext extends SimpleNamespaceContext { + public NSContext() { + super(); + } + + /** + * [Jaxen NamespaceContext interface support] Translates + * the provided namespace prefix into the matching bound + * namespace URI. + * + * @param prefix the namespace prefix to resolve. + * + * @return the namespace URI matching the prefix. + */ + public String translateNamespacePrefixToUri(String prefix) { + if ((prefix == null) || (prefix.length() == 0)) { + return null; + } + + String uri = super.translateNamespacePrefixToUri(prefix); + if (uri == null) { + Object ctx = currentContext; + if (ctx != null) { + Element elt = null; + + // Get closer element node + if (ctx instanceof Element) { + elt = (Element)ctx; + } else if (ctx instanceof Attribute) { + elt = ((Attribute)ctx).getParent(); + } else if (ctx instanceof Content) { + elt = ((Content) ctx).getParentElement(); + } else if (ctx instanceof Document) { + elt = ((Document)ctx).getRootElement(); + } + + if (elt != null) { + Namespace ns = elt.getNamespace(prefix); + if (ns != null) { + uri = ns.getURI(); + } + } + } + } + return uri; + } + } +} + Index: 3rdParty_sources/jdom/org/jdom/xpath/XPath.java =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/xpath/XPath.java (revision 0) +++ 3rdParty_sources/jdom/org/jdom/xpath/XPath.java (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,453 @@ +/*-- + + $Id$ + + 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 . + + 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 . + + 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 and + Brett McLaughlin . For more information + on the JDOM Project, please see . + + */ + +package org.jdom.xpath; + + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import org.jdom.*; + + +/** + * A utility class for performing XPath calls on JDOM nodes, with a factory + * interface for obtaining a first XPath instance. Users operate against this + * class while XPath vendors can plug-in implementations underneath. Users + * can choose an implementation using either {@link #setXPathClass} or + * the system property "org.jdom.xpath.class". + * + * @version $Revision$, $Date$ + * @author Laurent Bihanic + */ +public abstract class XPath implements Serializable { + + private static final String CVS_ID = + "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; + + /** + * The name of the system property from which to retrieve the + * name of the implementation class to use. + *

+ * The property name is: + * "org.jdom.xpath.class".

+ */ + private final static String XPATH_CLASS_PROPERTY = "org.jdom.xpath.class"; + + /** + * The default implementation class to use if none was configured. + */ + private final static String DEFAULT_XPATH_CLASS = + "org.jdom.xpath.JaxenXPath"; + + /** + * The string passable to the JAXP 1.3 XPathFactory isObjectModelSupported() + * method to query an XPath engine regarding its support for JDOM. Defined + * to be the well-known URI "http://jdom.org/jaxp/xpath/jdom". + */ + public final static String JDOM_OBJECT_MODEL_URI = + "http://jdom.org/jaxp/xpath/jdom"; + + /** + * The constructor to instanciate a new XPath concrete + * implementation. + * + * @see #newInstance + */ + private static Constructor constructor = null; + + /** + * Creates a new XPath wrapper object, compiling the specified + * XPath expression. + * + * @param path the XPath expression to wrap. + * + * @throws JDOMException if the XPath expression is invalid. + */ + public static XPath newInstance(String path) throws JDOMException { + try { + if (constructor == null) { + // First call => Determine implementation. + String className; + try { + className = System.getProperty(XPATH_CLASS_PROPERTY, + DEFAULT_XPATH_CLASS); + } + catch (SecurityException ex1) { + // Access to system property denied. => Use default impl. + className = DEFAULT_XPATH_CLASS; + } + setXPathClass(Class.forName(className)); + } + // Allocate and return new implementation instance. + return (XPath)constructor.newInstance(new Object[] { path }); + } + catch (JDOMException ex1) { + throw ex1; + } + catch (InvocationTargetException ex2) { + // Constructor threw an error on invocation. + Throwable t = ex2.getTargetException(); + + throw (t instanceof JDOMException)? (JDOMException)t: + new JDOMException(t.toString(), t); + } + catch (Exception ex3) { + // Any reflection error (probably due to a configuration mistake). + throw new JDOMException(ex3.toString(), ex3); + } + } + + /** + * Sets the concrete XPath subclass to use when allocating XPath + * instances. + * + * @param aClass the concrete subclass of XPath. + * + * @throws IllegalArgumentException if aClass is + * null. + * @throws JDOMException if aClass is + * not a concrete subclass + * of XPath. + */ + public static void setXPathClass(Class aClass) throws JDOMException { + if (aClass == null) { + throw new IllegalArgumentException("aClass"); + } + + try { + if ((XPath.class.isAssignableFrom(aClass)) && + (Modifier.isAbstract(aClass.getModifiers()) == false)) { + // Concrete subclass of XPath => Get constructor + constructor = aClass.getConstructor(new Class[] { String.class }); + } + else { + throw new JDOMException(aClass.getName() + + " is not a concrete JDOM XPath implementation"); + } + } + catch (JDOMException ex1) { + throw ex1; + } + catch (Exception ex2) { + // Any reflection error (probably due to a configuration mistake). + throw new JDOMException(ex2.toString(), ex2); + } + } + + /** + * Evaluates the wrapped XPath expression and returns the list + * of selected items. + * + * @param context the node to use as context for evaluating + * the XPath expression. + * + * @return the list of selected items, which may be of types: {@link Element}, + * {@link Attribute}, {@link Text}, {@link CDATA}, + * {@link Comment}, {@link ProcessingInstruction}, Boolean, + * Double, or String. + * + * @throws JDOMException if the evaluation of the XPath + * expression on the specified context + * failed. + */ + abstract public List selectNodes(Object context) throws JDOMException; + + /** + * Evaluates the wrapped XPath expression and returns the first + * entry in the list of selected nodes (or atomics). + * + * @param context the node to use as context for evaluating + * the XPath expression. + * + * @return the first selected item, which may be of types: {@link Element}, + * {@link Attribute}, {@link Text}, {@link CDATA}, + * {@link Comment}, {@link ProcessingInstruction}, Boolean, + * Double, String, or null if no item was selected. + * + * @throws JDOMException if the evaluation of the XPath + * expression on the specified context + * failed. + */ + abstract public Object selectSingleNode(Object context) throws JDOMException; + + /** + * Returns the string value of the first node selected by applying + * the wrapped XPath expression to the given context. + * + * @param context the element to use as context for evaluating + * the XPath expression. + * + * @return the string value of the first node selected by applying + * the wrapped XPath expression to the given context. + * + * @throws JDOMException if the XPath expression is invalid or + * its evaluation on the specified context + * failed. + */ + abstract public String valueOf(Object context) throws JDOMException; + + /** + * Returns the number value of the first node selected by applying + * the wrapped XPath expression to the given context. + * + * @param context the element to use as context for evaluating + * the XPath expression. + * + * @return the number value of the first node selected by applying + * the wrapped XPath expression to the given context, + * null if no node was selected or the + * special value {@link java.lang.Double#NaN} + * (Not-a-Number) if the selected value can not be + * converted into a number value. + * + * @throws JDOMException if the XPath expression is invalid or + * its evaluation on the specified context + * failed. + */ + abstract public Number numberValueOf(Object context) throws JDOMException; + + /** + * Defines an XPath variable and sets its value. + * + * @param name the variable name. + * @param value the variable value. + * + * @throws IllegalArgumentException if name is not + * a valid XPath variable name + * or if the value type is not + * supported by the underlying + * implementation + */ + abstract public void setVariable(String name, Object value); + + /** + * Adds a namespace definition to the list of namespaces known of + * this XPath expression. + *

+ * Note: In XPath, there is no such thing as a + * 'default namespace'. The empty prefix always resolves + * to the empty namespace URI.

+ * + * @param namespace the namespace. + */ + abstract public void addNamespace(Namespace namespace); + + /** + * Adds a namespace definition (prefix and URI) to the list of + * namespaces known of this XPath expression. + *

+ * Note: In XPath, there is no such thing as a + * 'default namespace'. The empty prefix always resolves + * to the empty namespace URI.

+ * + * @param prefix the namespace prefix. + * @param uri the namespace URI. + * + * @throws IllegalNameException if the prefix or uri are null or + * empty strings or if they contain + * illegal characters. + */ + public void addNamespace(String prefix, String uri) { + addNamespace(Namespace.getNamespace(prefix, uri)); + } + + /** + * Returns the wrapped XPath expression as a string. + * + * @return the wrapped XPath expression as a string. + */ + abstract public String getXPath(); + + + /** + * Evaluates an XPath expression and returns the list of selected + * items. + *

+ * Note: This method should not be used when the + * same XPath expression needs to be applied several times (on the + * same or different contexts) as it requires the expression to be + * compiled before being evaluated. In such cases, + * {@link #newInstance allocating} an XPath wrapper instance and + * {@link #selectNodes(java.lang.Object) evaluating} it several + * times is way more efficient. + *

+ * + * @param context the node to use as context for evaluating + * the XPath expression. + * @param path the XPath expression to evaluate. + * + * @return the list of selected items, which may be of types: {@link Element}, + * {@link Attribute}, {@link Text}, {@link CDATA}, + * {@link Comment}, {@link ProcessingInstruction}, Boolean, + * Double, or String. + * + * @throws JDOMException if the XPath expression is invalid or + * its evaluation on the specified context + * failed. + */ + public static List selectNodes(Object context, String path) + throws JDOMException { + return newInstance(path).selectNodes(context); + } + + /** + * Evaluates the wrapped XPath expression and returns the first + * entry in the list of selected nodes (or atomics). + *

+ * Note: This method should not be used when the + * same XPath expression needs to be applied several times (on the + * same or different contexts) as it requires the expression to be + * compiled before being evaluated. In such cases, + * {@link #newInstance allocating} an XPath wrapper instance and + * {@link #selectSingleNode(java.lang.Object) evaluating} it + * several times is way more efficient. + *

+ * + * @param context the element to use as context for evaluating + * the XPath expression. + * @param path the XPath expression to evaluate. + * + * @return the first selected item, which may be of types: {@link Element}, + * {@link Attribute}, {@link Text}, {@link CDATA}, + * {@link Comment}, {@link ProcessingInstruction}, Boolean, + * Double, String, or null if no item was selected. + * + * @throws JDOMException if the XPath expression is invalid or + * its evaluation on the specified context + * failed. + */ + public static Object selectSingleNode(Object context, String path) + throws JDOMException { + return newInstance(path).selectSingleNode(context); + } + + + //------------------------------------------------------------------------- + // Serialization support + //------------------------------------------------------------------------- + + /** + * [Serialization support] Returns the alternative object + * to write to the stream when serializing this object. This + * method returns an instance of a dedicated nested class to + * serialize XPath expressions independently of the concrete + * implementation being used. + *

+ * Note: Subclasses are not allowed to override + * this method to ensure valid serialization of all + * implementations.

+ * + * @return an XPathString instance configured with the wrapped + * XPath expression. + * + * @throws ObjectStreamException never. + */ + protected final Object writeReplace() throws ObjectStreamException { + return new XPathString(this.getXPath()); + } + + /** + * The XPathString is dedicated to serialize instances of + * XPath subclasses in a implementation-independent manner. + *

+ * XPathString ensures that only string data are serialized. Upon + * deserialization, XPathString relies on XPath factory method to + * to create instances of the concrete XPath wrapper currently + * configured.

+ */ + private final static class XPathString implements Serializable { + /** + * The XPath expression as a string. + */ + private String xPath = null; + + /** + * Creates a new XPathString instance from the specified + * XPath expression. + * + * @param xpath the XPath expression. + */ + public XPathString(String xpath) { + super(); + + this.xPath = xpath; + } + + /** + * [Serialization support] Resolves the read XPathString + * objects into XPath implementations. + * + * @return an instance of a concrete implementation of + * XPath. + * + * @throws ObjectStreamException if no XPath could be built + * from the read object. + */ + private Object readResolve() throws ObjectStreamException { + try { + return XPath.newInstance(this.xPath); + } + catch (JDOMException ex1) { + throw new InvalidObjectException( + "Can't create XPath object for expression \"" + + this.xPath + "\": " + ex1.toString()); + } + } + } +} + Index: 3rdParty_sources/jdom/org/jdom/xpath/package.html =================================================================== diff -u --- 3rdParty_sources/jdom/org/jdom/xpath/package.html (revision 0) +++ 3rdParty_sources/jdom/org/jdom/xpath/package.html (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -0,0 +1,6 @@ + + +Support for XPath from within JDOM. XPath provides a common interface with a +pluggable back-end. The default back end is Jaxen. + + Index: 3rdParty_sources/versions.txt =================================================================== diff -u -rc208628989d52041b3765784f4c8cbfd6c80d47b -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- 3rdParty_sources/versions.txt (.../versions.txt) (revision c208628989d52041b3765784f4c8cbfd6c80d47b) +++ 3rdParty_sources/versions.txt (.../versions.txt) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -25,6 +25,8 @@ JBoss Web 2.1.3 +jdom 1.1.2 + JSP API 2.3 Joda Time 2.1 Index: lams_build/3rdParty.userlibraries =================================================================== diff -u -re179b1c5a61d9aa11b2b3d9d741ad2674322aec4 -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_build/3rdParty.userlibraries (.../3rdParty.userlibraries) (revision e179b1c5a61d9aa11b2b3d9d741ad2674322aec4) +++ lams_build/3rdParty.userlibraries (.../3rdParty.userlibraries) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -13,7 +13,6 @@ - Index: lams_build/build.xml =================================================================== diff -u -rb4525dd04f70af9ce0b787e61884438ff80c3848 -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_build/build.xml (.../build.xml) (revision b4525dd04f70af9ce0b787e61884438ff80c3848) +++ lams_build/build.xml (.../build.xml) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -566,16 +566,6 @@ - - - - - - - - - Index: lams_build/build_base.xml =================================================================== diff -u -r0c0cbdac26679e47d5c48e045c30e5496e1f809b -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_build/build_base.xml (.../build_base.xml) (revision 0c0cbdac26679e47d5c48e045c30e5496e1f809b) +++ lams_build/build_base.xml (.../build_base.xml) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -49,7 +49,7 @@ - + Index: lams_build/conf/j2ee/jboss-deployment-structure.xml =================================================================== diff -u -re179b1c5a61d9aa11b2b3d9d741ad2674322aec4 -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_build/conf/j2ee/jboss-deployment-structure.xml (.../jboss-deployment-structure.xml) (revision e179b1c5a61d9aa11b2b3d9d741ad2674322aec4) +++ lams_build/conf/j2ee/jboss-deployment-structure.xml (.../jboss-deployment-structure.xml) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -39,7 +39,7 @@ - + Index: lams_build/lib/jdom/jdom.jar =================================================================== diff -u -rb11fdf8e6de8f399b37b5382808063fd323d2958 -r588fe01186ff8c7c5b215e15f5ac4763137e0284 Binary files differ Fisheye: Tag 588fe01186ff8c7c5b215e15f5ac4763137e0284 refers to a dead (removed) revision in file `lams_build/lib/jdom/jdom.module.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_build/liblist.txt =================================================================== diff -u -rc208628989d52041b3765784f4c8cbfd6c80d47b -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_build/liblist.txt (.../liblist.txt) (revision c208628989d52041b3765784f4c8cbfd6c80d47b) +++ lams_build/liblist.txt (.../liblist.txt) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -33,14 +33,10 @@ jboss jbossweb.jar 2.1.3 LGPL 2.1 Apache Software Foundation SSO valve and JSON -jdom jdom.jar 0.7 BSD/Apache style Jason Hunter, Rolf Lear Java representation of an XML document - joda joda-time-2.1.jar 2.1 Apache License 2.0 Joda.org time calculation library joid joid.jar 2.0 Apache License 2.0 Java Open ID library - - lucene lucene-core-2.4.0.jar 2.4.0 Apache License 2.0 Apache text search engine library lucene-snowball-2.4.0.jar 2.4.0 Index: lams_central/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_central/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_central/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -36,5 +36,6 @@ + Index: lams_common/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_common/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_common/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -43,6 +43,7 @@ + Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java =================================================================== diff -u -ra4a61e7b65ede7f903eb08521a9455685ef9283d -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision a4a61e7b65ede7f903eb08521a9455685ef9283d) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -37,10 +37,8 @@ import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -151,7 +149,6 @@ import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.Converter; -import com.thoughtworks.xstream.converters.ConverterLookup; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; @@ -750,7 +747,7 @@ // create resources.xml file Document resourcesDom = new Document(); Element resRoot = new Element(ExportToolContentService.IMS_TAG_RESOURCES); - resRoot.setChildren(resChildren); + resRoot.setContent(resChildren); resourcesDom.setRootElement(resRoot); File resFile = new File(FileUtil.getFullPath(xsltDir, ExportToolContentService.IMS_RESOURCES_FILE_NAME)); XMLOutputter resOutput = new XMLOutputter(); @@ -850,7 +847,7 @@ } } - transRoot.setChildren(transChildren); + transRoot.setContent(transChildren); transDom.setRootElement(transRoot); File transFile = new File(FileUtil.getFullPath(xsltDir, ExportToolContentService.IMS_TRANSITION_FILE_NAME)); XMLOutputter transOutput = new XMLOutputter(); @@ -861,14 +858,14 @@ // create the properties file and conditions file - needed for gate // showing gates when open and branches when // determined - propertiesRoot.setChildren(propertiesChildren); + propertiesRoot.setContent(propertiesChildren); propertiesDom.setRootElement(propertiesRoot); File propertiesFile = new File(FileUtil.getFullPath(xsltDir, ExportToolContentService.IMS_PROPERTIES_FILE_NAME)); XMLOutputter propertiesOutput = new XMLOutputter(); propertiesOutput.output(propertiesDom, new FileOutputStream(propertiesFile)); log.debug("Export IMS: Properties file generated sucess: " + propertiesFile.getAbsolutePath()); - conditionsRoot.setChildren(conditionsChildren); + conditionsRoot.setContent(conditionsChildren); conditionsDom.setRootElement(conditionsRoot); File conditionsFile = new File(FileUtil.getFullPath(xsltDir, ExportToolContentService.IMS_CONDITIONS_FILE_NAME)); XMLOutputter conditionsOutput = new XMLOutputter(); @@ -916,7 +913,7 @@ // Setup the property first Element locpersProperty = new Element(ExportToolContentService.IMS_TAG_LOCPERS_PROPERTY); locpersProperty.setAttribute(new Attribute(ExportToolContentService.IMS_ATTR_IDENTIFIER, propertyName)); - locpersProperty.setChildren(new ArrayList()); + locpersProperty.setContent(new ArrayList()); Element el = new Element(ExportToolContentService.IMS_TAG_DATATYPE); el.setAttribute(new Attribute(ExportToolContentService.IMS_ATTR_DATATYPE, "boolean")); locpersProperty.getChildren().add(el); @@ -1151,7 +1148,7 @@ + activity.getToolContentID() + "] into resources XML node"); // build relations of TAGS fileChildren.add(fileEle); - resEle.setChildren(fileChildren); + resEle.setContent(fileChildren); resChildren.add(resEle); } @@ -1164,7 +1161,7 @@ while (iter.hasNext()) { Element child = (Element) iter.next(); child.setNamespace(ns); - if (child.hasChildren()) { + if (child.getContentSize() > 0) { updateNamespaceForChildren(child, ns); } } @@ -1479,9 +1476,10 @@ * @param fullFilePath * @param toolsErrorMsgs * @return version of the server that exported this file + * @throws IOException */ - private String checkImportVersion(String fullFilePath, List toolsErrorMsgs) throws FileNotFoundException, - JDOMException { + private String checkImportVersion(String fullFilePath, List toolsErrorMsgs) throws JDOMException, + IOException { SAXBuilder sax = new SAXBuilder(); Document doc = sax.build(new FileInputStream(fullFilePath), "UTF-8"); Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ToolContentVersionFilter.java =================================================================== diff -u -ra4a61e7b65ede7f903eb08521a9455685ef9283d -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ToolContentVersionFilter.java (.../ToolContentVersionFilter.java) (revision a4a61e7b65ede7f903eb08521a9455685ef9283d) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ToolContentVersionFilter.java (.../ToolContentVersionFilter.java) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -142,7 +142,7 @@ output.output(doc, new FileOutputStream(newToolFile)); } - private void retrieveXML(Element root) throws JDOMException { + private void retrieveXML(Element root) throws JDOMException, IOException { // collect all removed fields in this class List clzRemoveFlds = new ArrayList(); for (RemovedField remove : removedFieldList) { Index: lams_tool_assessment/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_tool_assessment/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_tool_assessment/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -26,6 +26,7 @@ + Index: lams_tool_eadventure/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_tool_eadventure/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_tool_eadventure/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -27,5 +27,6 @@ + Index: lams_tool_imscc/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_tool_imscc/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_tool_imscc/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -27,5 +27,6 @@ + Index: lams_tool_larsrc/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r588fe01186ff8c7c5b215e15f5ac4763137e0284 --- lams_tool_larsrc/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_tool_larsrc/.classpath (.../.classpath) (revision 588fe01186ff8c7c5b215e15f5ac4763137e0284) @@ -26,5 +26,6 @@ +