XMLElement.java

Index Score
freemind.main
FreeMind

View: Reasons, Metrics, Source Code

These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.

MetricDescription
DOC_COMMENTNumber of javadoc comment lines
COMMENTSComment lines
SIZESize of the file in bytes
RETURNSNumber of return points from functions
LINESNumber of lines in the source file
INTERFACE_COMPLEXITYInterface complexity
DECL_COMMENTSComments in declarations
PARAMSNumber of formal parameter declarations
BLOCKSNumber of blocks
CYCLOMATICCyclomatic complexity
JAVA0110JAVA0110 Incorrect javadoc: no @return tag
LOCLines of code
JAVA0108JAVA0108 Incorrect javadoc: no @param tag for 'parameter'
JAVA0075JAVA0075 Method parameter hides field
FUNCTIONSNumber of function declarations
ELOCEffective lines of code
OPERATORSNumber of operators
LOOPSNumber of loops
LOGICAL_LINESNumber of statements
JAVA0115JAVA0115 Incorrect javadoc: no @throws or @exception tag for 'exception'
PROGRAM_LENGTHHalstead program length
OPERANDSNumber of operands
COMPARISONSNumber of comparison operators
EXITSProcedure exits
JAVA0126JAVA0126 Method declares unchecked exception in throws
JAVA0123JAVA0123 Use all three components of for loop
UNIQUE_OPERANDSNumber of unique operands
PROGRAM_VOCABHalstead program vocabulary
WHITESPACENumber of whitespace lines
JAVA0031JAVA0031 Case statement not properly closed
JAVA0235JAVA0235 Class defines serialVersionUID but does not implement Serializable
JAVA0034JAVA0034 Missing braces in if statement
JAVA0109JAVA0109 Incorrect javadoc: no parameter 'parameter'
JAVA0112JAVA0112 Incorrect javadoc: no exception 'exception' in throws
JAVA0177JAVA0177 Variable declaration missing initializer
JAVA0179JAVA0179 Local variable hides visible field
UNIQUE_OPERATORSNumber of unique operators
EXEC_COMMENTSComments in executable code
JAVA0076JAVA0076 Use of magic number
NEST_DEPTHMaximum nesting depth
PROGRAM_VOLUMEHalstead program volume
JAVA0136JAVA0136 N methods defined in class (maximum: M)
JAVA0132JAVA0132 Method overload with compatible signature
JAVA0117JAVA0117 Missing javadoc: method 'method'
JAVA0100JAVA0100 Class contains N non-final fields (maximum: M)
JAVA0254JAVA0254 Use enhanced for loop construct instead of Iterator
JAVA0145JAVA0145 Tab character used in source file
/* XMLElement.java * * $Revision: 1.8 $ * $Date: 2007/08/07 17:37:22 $ * $Name: $ * * This file is part of NanoXML 2 Lite. * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved. * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. *****************************************************************************/ /* * This version of XMLElement has been *altered* for the purposes of FreeMind * toUpperCase(Locale.ENGLISH) for turkish added. */ package freemind.main; import java.io.ByteArrayOutputStream; import java.io.CharArrayReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.io.Writer; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; import java.util.TreeMap; import java.util.Vector; /** * XMLElement is a representation of an XML object. The object is able to parse * XML code. * <P><DL> * <DT><B>Parsing XML Data</B></DT> * <DD> * You can parse XML data using the following code: * <UL><CODE> * XMLElement xml = new XMLElement();<BR> * FileReader reader = new FileReader("filename.xml");<BR> * xml.parseFromReader(reader); * </CODE></UL></DD></DL> * <DL><DT><B>Retrieving Attributes</B></DT> * <DD> * You can enumerate the attributes of an element using the method * {@link #enumerateAttributeNames() enumerateAttributeNames}. * The attribute values can be retrieved using the method * {@link #getStringAttribute(java.lang.String) getStringAttribute}. * The following example shows how to list the attributes of an element: * <UL><CODE> * XMLElement element = ...;<BR> * Enumeration enumerator = element.getAttributeNames();<BR> * while (enumerator.hasMoreElements()) {<BR> * &nbsp;&nbsp;&nbsp;&nbsp;String key = (String) enumerator.nextElement();<BR> * &nbsp;&nbsp;&nbsp;&nbsp;String value = element.getStringAttribute(key);<BR> * &nbsp;&nbsp;&nbsp;&nbsp;System.out.println(key + " = " + value);<BR> * } * </CODE></UL></DD></DL> * <DL><DT><B>Retrieving Child Elements</B></DT> * <DD> * You can enumerate the children of an element using * {@link #enumerateChildren() enumerateChildren}. * The number of child elements can be retrieved using * {@link #countChildren() countChildren}. * </DD></DL> * <DL><DT><B>Elements Containing Character Data</B></DT> * <DD> * If an elements contains character data, like in the following example: * <UL><CODE> * &lt;title&gt;The Title&lt;/title&gt; * </CODE></UL> * you can retrieve that data using the method * {@link #getContent() getContent}. * </DD></DL> * <DL><DT><B>Subclassing XMLElement</B></DT> * <DD> * When subclassing XMLElement, you need to override the method * {@link #createAnotherElement() createAnotherElement} * which has to return a new copy of the receiver. * </DD></DL> * <P> * * @see nanoxml.XMLParseException * * @author Marc De Scheemaecker * &lt;<A href="mailto:cyberelf@mac.com">cyberelf@mac.com</A>&gt; * @version $Name: $, $Revision: 1.8 $ */ public class XMLElement { /** * Serialization serial version ID. */ static final long serialVersionUID = 6685035139346394777L; /** * Major version of NanoXML. Classes with the same major and minor * version are binary compatible. Classes with the same major version * are source compatible. If the major version is different, you may * need to modify the client source code. * * @see nanoxml.XMLElement#NANOXML_MINOR_VERSION */ public static final int NANOXML_MAJOR_VERSION = 2; /** * Minor version of NanoXML. Classes with the same major and minor * version are binary compatible. Classes with the same major version * are source compatible. If the major version is different, you may * need to modify the client source code. * * @see nanoxml.XMLElement#NANOXML_MAJOR_VERSION */ public static final int NANOXML_MINOR_VERSION = 2; /** * The attributes given to the element. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>The field can be empty. * <li>The field is never <code>null</code>. * <li>The keys and the values are strings. * </ul></dd></dl> */ private TreeMap attributes; /** * Child elements of the element. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>The field can be empty. * <li>The field is never <code>null</code>. * <li>The elements are instances of <code>XMLElement</code> * or a subclass of <code>XMLElement</code>. * </ul></dd></dl> */ private Vector children; /** * The name of the element. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>The field is <code>null</code> iff the element is not * initialized by either parse or setName. * <li>If the field is not <code>null</code>, it's not empty. * <li>If the field is not <code>null</code>, it contains a valid * XML identifier. * </ul></dd></dl> */ private String name; /** * The #PCDATA content of the object. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>The field is <code>null</code> iff the element is not a * #PCDATA element. * <li>The field can be any string, including the empty string. * </ul></dd></dl> */ private String contents; /** * Conversion table for &amp;...; entities. The keys are the entity names * without the &amp; and ; delimiters. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>The field is never <code>null</code>. * <li>The field always contains the following associations: * "lt"&nbsp;=&gt;&nbsp;"&lt;", "gt"&nbsp;=&gt;&nbsp;"&gt;", * "quot"&nbsp;=&gt;&nbsp;"\"", "apos"&nbsp;=&gt;&nbsp;"'", * "amp"&nbsp;=&gt;&nbsp;"&amp;" * <li>The keys are strings * <li>The values are char arrays * </ul></dd></dl> */ private Hashtable entities; /** * The line number where the element starts. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li><code>lineNr &gt= 0</code> * </ul></dd></dl> */ private int lineNr; /** * <code>true</code> if the case of the element and attribute names * are case insensitive. */ protected boolean ignoreCase; /** * <code>true</code> if the leading and trailing whitespace of #PCDATA * sections have to be ignored. */ private boolean ignoreWhitespace; /** * Character read too much. * This character provides push-back functionality to the input reader * without having to use a PushbackReader. * If there is no such character, this field is '\0'. */ private char charReadTooMuch; /** * The reader provided by the caller of the parse method. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>The field is not <code>null</code> while the parse method * is running. * </ul></dd></dl> */ private Reader reader; /** * The current line number in the source content. * * <dl><dt><b>Invariants:</b></dt><dd> * <ul><li>parserLineNr &gt; 0 while the parse method is running. * </ul></dd></dl> */ private int parserLineNr; /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * <ul><code>new XMLElement(new Hashtable(), false, true) * </code></ul> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => 0 * <li>enumerateChildren() => empty enumeration * <li>enumeratePropertyNames() => empty enumeration * <li>getChildren() => empty vector * <li>getContent() => "" * <li>getLineNr() => 0 * <li>getName() => null * </ul></dd></dl> * * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement() { this(new Hashtable(), false, true, true); } /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * <ul><code>new XMLElement(entities, false, true) * </code></ul> * * @param entities * The entity conversion table. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>entities != null</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => 0 * <li>enumerateChildren() => empty enumeration * <li>enumeratePropertyNames() => empty enumeration * <li>getChildren() => empty vector * <li>getContent() => "" * <li>getLineNr() => 0 * <li>getName() => null * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement(Hashtable entities) { this(entities, false, true, true); } /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * <ul><code>new XMLElement(new Hashtable(), skipLeadingWhitespace, true) * </code></ul> * * @param skipLeadingWhitespace * <code>true</code> if leading and trailing whitespace in PCDATA * content has to be removed. * * </dl><dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => 0 * <li>enumerateChildren() => empty enumeration * <li>enumeratePropertyNames() => empty enumeration * <li>getChildren() => empty vector * <li>getContent() => "" * <li>getLineNr() => 0 * <li>getName() => null * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement(boolean skipLeadingWhitespace) { this(new Hashtable(), skipLeadingWhitespace, true, true); } /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * <ul><code>new XMLElement(entities, skipLeadingWhitespace, true) * </code></ul> * * @param entities * The entity conversion table. * @param skipLeadingWhitespace * <code>true</code> if leading and trailing whitespace in PCDATA * content has to be removed. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>entities != null</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => 0 * <li>enumerateChildren() => empty enumeration * <li>enumeratePropertyNames() => empty enumeration * <li>getChildren() => empty vector * <li>getContent() => "" * <li>getLineNr() => 0 * <li>getName() => null * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) */ public XMLElement(Hashtable entities, boolean skipLeadingWhitespace) { this(entities, skipLeadingWhitespace, true, true); } /** * Creates and initializes a new XML element. * * @param entities * The entity conversion table. * @param skipLeadingWhitespace * <code>true</code> if leading and trailing whitespace in PCDATA * content has to be removed. * @param ignoreCase * <code>true</code> if the case of element and attribute names have * to be ignored. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>entities != null</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => 0 * <li>enumerateChildren() => empty enumeration * <li>enumeratePropertyNames() => empty enumeration * <li>getChildren() => empty vector * <li>getContent() => "" * <li>getLineNr() => 0 * <li>getName() => null * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement(Hashtable entities, boolean skipLeadingWhitespace, boolean ignoreCase) { this(entities, skipLeadingWhitespace, true, ignoreCase); } /** * Creates and initializes a new XML element. * <P> * This constructor should <I>only</I> be called from * {@link #createAnotherElement() createAnotherElement} * to create child elements. * * @param entities * The entity conversion table. * @param skipLeadingWhitespace * <code>true</code> if leading and trailing whitespace in PCDATA * content has to be removed. * @param fillBasicConversionTable * <code>true</code> if the basic entities need to be added to * the entity list. * @param ignoreCase * <code>true</code> if the case of element and attribute names have * to be ignored. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>entities != null</code> * <li>if <code>fillBasicConversionTable == false</code> * then <code>entities</code> contains at least the following * entries: <code>amp</code>, <code>lt</code>, <code>gt</code>, * <code>apos</code> and <code>quot</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => 0 * <li>enumerateChildren() => empty enumeration * <li>enumeratePropertyNames() => empty enumeration * <li>getChildren() => empty vector * <li>getContent() => "" * <li>getLineNr() => 0 * <li>getName() => null * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#createAnotherElement() */ protected XMLElement(Hashtable entities, boolean skipLeadingWhitespace, boolean fillBasicConversionTable, boolean ignoreCase) { this.ignoreWhitespace = skipLeadingWhitespace; this.ignoreCase = ignoreCase; this.name = null; this.contents = ""; this.attributes = new TreeMap(); this.children = new Vector(); this.entities = entities; this.lineNr = 0; Enumeration enumerator = this.entities.keys(); while (enumerator.hasMoreElements()) { Object key = enumerator.nextElement(); Object value = this.entities.get(key); if (value instanceof String) { value = ((String) value).toCharArray(); this.entities.put(key, value); } } if (fillBasicConversionTable) { this.entities.put("amp", new char[] { '&' }); this.entities.put("quot", new char[] { '"' }); this.entities.put("apos", new char[] { '\'' }); this.entities.put("lt", new char[] { '<' }); this.entities.put("gt", new char[] { '>' }); } } // We may expect that some subclass would like to have its own object public Object getUserObject() { return null; } /** * Adds a child element. * * @param child * The child element to add. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>child != null</code> * <li><code>child.getName() != null</code> * <li><code>child</code> does not have a parent element * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => old.countChildren() + 1 * <li>enumerateChildren() => old.enumerateChildren() + child * <li>getChildren() => old.enumerateChildren() + child * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#getChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public void addChild(XMLElement child) { this.children.addElement(child); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * <li><code>value != null</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>enumerateAttributeNames() * => old.enumerateAttributeNames() + name * <li>getAttribute(name) => value * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) */ public void setAttribute(String name, Object value) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } this.attributes.put(name, value.toString()); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * @deprecated Use {@link #setAttribute(java.lang.String, java.lang.Object) * setAttribute} instead. */ public void addProperty(String name, Object value) { this.setAttribute(name, value); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>enumerateAttributeNames() * => old.enumerateAttributeNames() + name * <li>getIntAttribute(name) => value * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) */ public void setIntAttribute(String name, int value) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } this.attributes.put(name, Integer.toString(value)); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * @deprecated Use {@link #setIntAttribute(java.lang.String, int) * setIntAttribute} instead. */ public void addProperty(String key, int value) { this.setIntAttribute(key, value); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>enumerateAttributeNames() * => old.enumerateAttributeNames() + name * <li>getDoubleAttribute(name) => value * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) */ public void setDoubleAttribute(String name, double value) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } this.attributes.put(name, Double.toString(value)); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * @deprecated Use {@link #setDoubleAttribute(java.lang.String, double) * setDoubleAttribute} instead. */ public void addProperty(String name, double value) { this.setDoubleAttribute(name, value); } /** * Returns the number of child elements of the element. * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li><code>result >= 0</code> * </ul></dd></dl> * * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#getChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public int countChildren() { return this.children.size(); } /** * Enumerates the attribute names. * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li><code>result != null</code> * </ul></dd></dl> * * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String, * java.lang.String, * java.lang.String, boolean) * getBooleanAttribute(String, String, String, boolean) */ public Iterator enumerateAttributeNames() { return this.attributes.keySet().iterator(); } /** * Enumerates the attribute names. * * @deprecated Use {@link #enumerateAttributeNames() * enumerateAttributeNames} instead. */ public Iterator enumeratePropertyNames() { return this.enumerateAttributeNames(); } /** * Enumerates the child elements. * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li><code>result != null</code> * </ul></dd></dl> * * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#getChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public Enumeration enumerateChildren() { return this.children.elements(); } /** * Returns the child elements as a Vector. It is safe to modify this * Vector. * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li><code>result != null</code> * </ul></dd></dl> * * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public Vector getChildren() { try { return (Vector) this.children.clone(); } catch (Exception e) { // this never happens, however, some Java compilers are so // braindead that they require this exception clause return null; } } /** * Returns the PCDATA content of the object. If there is no such content, * <CODE>null</CODE> is returned. * * @deprecated Use {@link #getContent() getContent} instead. */ public String getContents() { return this.getContent(); } /** * Returns the PCDATA content of the object. If there is no such content, * <CODE>null</CODE> is returned. * * @see nanoxml.XMLElement#setContent(java.lang.String) * setContent(String) */ public String getContent() { return this.contents; } /** * Returns the line nr in the source data on which the element is found. * This method returns <code>0</code> there is no associated source data. * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li><code>result >= 0</code> * </ul></dd></dl> */ public int getLineNr() { return this.lineNr; } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>null</code> is returned. * * @param name The name of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) */ public Object getAttribute(String name) { return this.getAttribute(name, null); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>defaultValue</code> is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) */ public Object getAttribute(String name, Object defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } Object value = this.attributes.get(name); if (value == null) { value = defaultValue; } return value; } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. * <P> * As an example, if valueSet contains the mapping <code>"one" => * "1"</code> * and the element contains the attribute <code>attr="one"</code>, then * <code>getAttribute("attr", mapping, defaultKey, false)</code> returns * <code>"1"</code>. * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiterals * <code>true</code> if literals are valid. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * <li><code>valueSet</code> != null * <li>the keys of <code>valueSet</code> are strings * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) */ public Object getAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiterals) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } Object key = this.attributes.get(name); Object result; if (key == null) { key = defaultKey; } result = valueSet.get(key); if (result == null) { if (allowLiterals) { result = key; } else { throw this.invalidValue(name, (String) key); } } return result; } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>null</code> is returned. * * @param name The name of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) */ public String getStringAttribute(String name) { return this.getStringAttribute(name, null); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>defaultValue</code> is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) */ public String getStringAttribute(String name, String defaultValue) { return (String) this.getAttribute(name, defaultValue); } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. * <P> * As an example, if valueSet contains the mapping <code>"one" => * "1"</code> * and the element contains the attribute <code>attr="one"</code>, then * <code>getAttribute("attr", mapping, defaultKey, false)</code> returns * <code>"1"</code>. * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiterals * <code>true</code> if literals are valid. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * <li><code>valueSet</code> != null * <li>the keys of <code>valueSet</code> are strings * <li>the values of <code>valueSet</code> are strings * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) */ public String getStringAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiterals) { return (String) this.getAttribute(name, valueSet, defaultKey, allowLiterals); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>0</code> is returned. * * @param name The name of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) */ public int getIntAttribute(String name) { return this.getIntAttribute(name, 0); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>defaultValue</code> is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) */ public int getIntAttribute(String name, int defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } String value = (String) this.attributes.get(name); if (value == null) { return defaultValue; } else { try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw this.invalidValue(name, value); } } } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. * <P> * As an example, if valueSet contains the mapping <code>"one" => 1</code> * and the element contains the attribute <code>attr="one"</code>, then * <code>getIntAttribute("attr", mapping, defaultKey, false)</code> returns * <code>1</code>. * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiteralNumbers * <code>true</code> if literal numbers are valid. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * <li><code>valueSet</code> != null * <li>the keys of <code>valueSet</code> are strings * <li>the values of <code>valueSet</code> are Integer objects * <li><code>defaultKey</code> is either <code>null</code>, a * key in <code>valueSet</code> or an integer. * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) */ public int getIntAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiteralNumbers) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } Object key = this.attributes.get(name); Integer result; if (key == null) { key = defaultKey; } try { result = (Integer) valueSet.get(key); } catch (ClassCastException e) { throw this.invalidValueSet(name); } if (result == null) { if (! allowLiteralNumbers) { throw this.invalidValue(name, (String) key); } try { result = Integer.valueOf((String) key); } catch (NumberFormatException e) { throw this.invalidValue(name, (String) key); } } return result.intValue(); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>0.0</code> is returned. * * @param name The name of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) */ public double getDoubleAttribute(String name) { return this.getDoubleAttribute(name, 0.); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>defaultValue</code> is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) */ public double getDoubleAttribute(String name, double defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } String value = (String) this.attributes.get(name); if (value == null) { return defaultValue; } else { try { return Double.valueOf(value).doubleValue(); } catch (NumberFormatException e) { throw this.invalidValue(name, value); } } } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. * <P> * As an example, if valueSet contains the mapping <code>"one" =&gt; * 1.0</code> * and the element contains the attribute <code>attr="one"</code>, then * <code>getDoubleAttribute("attr", mapping, defaultKey, false)</code> * returns <code>1.0</code>. * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiteralNumbers * <code>true</code> if literal numbers are valid. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * <li><code>valueSet != null</code> * <li>the keys of <code>valueSet</code> are strings * <li>the values of <code>valueSet</code> are Double objects * <li><code>defaultKey</code> is either <code>null</code>, a * key in <code>valueSet</code> or a double. * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) */ public double getDoubleAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiteralNumbers) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } Object key = this.attributes.get(name); Double result; if (key == null) { key = defaultKey; } try { result = (Double) valueSet.get(key); } catch (ClassCastException e) { throw this.invalidValueSet(name); } if (result == null) { if (! allowLiteralNumbers) { throw this.invalidValue(name, (String) key); } try { result = Double.valueOf((String) key); } catch (NumberFormatException e) { throw this.invalidValue(name, (String) key); } } return result.doubleValue(); } /** * Returns an attribute of the element. * If the attribute doesn't exist, <code>defaultValue</code> is returned. * If the value of the attribute is equal to <code>trueValue</code>, * <code>true</code> is returned. * If the value of the attribute is equal to <code>falseValue</code>, * <code>false</code> is returned. * If the value doesn't match <code>trueValue</code> or * <code>falseValue</code>, an exception is thrown. * * @param name The name of the attribute. * @param trueValue The value associated with <code>true</code>. * @param falseValue The value associated with <code>true</code>. * @param defaultValue Value to use if the attribute is missing. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * <li><code>trueValue</code> and <code>falseValue</code> * are different strings. * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() */ public boolean getBooleanAttribute(String name, String trueValue, String falseValue, boolean defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } Object value = this.attributes.get(name); if (value == null) { return defaultValue; } else if (value.equals(trueValue)) { return true; } else if (value.equals(falseValue)) { return false; } else { throw this.invalidValue(name, (String) value); } } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getIntAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getIntAttribute} instead. */ public int getIntProperty(String name, Hashtable valueSet, String defaultKey) { return this.getIntAttribute(name, valueSet, defaultKey, false); } /** * Returns an attribute. * * @deprecated Use {@link #getStringAttribute(java.lang.String) * getStringAttribute} instead. */ public String getProperty(String name) { return this.getStringAttribute(name); } /** * Returns an attribute. * * @deprecated Use {@link #getStringAttribute(java.lang.String, * java.lang.String) getStringAttribute} instead. */ public String getProperty(String name, String defaultValue) { return this.getStringAttribute(name, defaultValue); } /** * Returns an attribute. * * @deprecated Use {@link #getIntAttribute(java.lang.String, int) * getIntAttribute} instead. */ public int getProperty(String name, int defaultValue) { return this.getIntAttribute(name, defaultValue); } /** * Returns an attribute. * * @deprecated Use {@link #getDoubleAttribute(java.lang.String, double) * getDoubleAttribute} instead. */ public double getProperty(String name, double defaultValue) { return this.getDoubleAttribute(name, defaultValue); } /** * Returns an attribute. * * @deprecated Use {@link #getBooleanAttribute(java.lang.String, * java.lang.String, java.lang.String, boolean) * getBooleanAttribute} instead. */ public boolean getProperty(String key, String trueValue, String falseValue, boolean defaultValue) { return this.getBooleanAttribute(key, trueValue, falseValue, defaultValue); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getAttribute} instead. */ public Object getProperty(String name, Hashtable valueSet, String defaultKey) { return this.getAttribute(name, valueSet, defaultKey, false); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getStringAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getStringAttribute} instead. */ public String getStringProperty(String name, Hashtable valueSet, String defaultKey) { return this.getStringAttribute(name, valueSet, defaultKey, false); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getIntAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getIntAttribute} instead. */ public int getSpecialIntProperty(String name, Hashtable valueSet, String defaultKey) { return this.getIntAttribute(name, valueSet, defaultKey, true); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getDoubleAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getDoubleAttribute} instead. */ public double getSpecialDoubleProperty(String name, Hashtable valueSet, String defaultKey) { return this.getDoubleAttribute(name, valueSet, defaultKey, true); } /** * Returns the name of the element. * * @see nanoxml.XMLElement#setName(java.lang.String) setName(String) */ public String getName() { return this.name; } /** * Returns the name of the element. * * @deprecated Use {@link #getName() getName} instead. */ public String getTagName() { return this.getName(); } /** * Reads one XML element from a java.io.Reader and parses it. * * @param reader * The reader from which to retrieve the XML data. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>reader != null</code> * <li><code>reader</code> is not closed * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * <li>the reader points to the first character following the last * '&gt;' character of the XML element * </ul></dd></dl><dl> * * @throws java.io.IOException * If an error occured while reading the input. * @throws nanoxml.XMLParseException * If an error occured while parsing the read data. */ public void parseFromReader(Reader reader) throws IOException, XMLParseException { this.parseFromReader(reader, /*startingLineNr*/ 1); } /** * Reads one XML element from a java.io.Reader and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param startingLineNr * The line number of the first line in the data. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>reader != null</code> * <li><code>reader</code> is not closed * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * <li>the reader points to the first character following the last * '&gt;' character of the XML element * </ul></dd></dl><dl> * * @throws java.io.IOException * If an error occured while reading the input. * @throws nanoxml.XMLParseException * If an error occured while parsing the read data. */ public void parseFromReader(Reader reader, int startingLineNr) throws IOException, XMLParseException { this.charReadTooMuch = '\0'; this.reader = reader; this.parserLineNr = startingLineNr; for (;;) { char ch = this.scanWhitespace(); if (ch != '<') { throw this.expectedInput("<"); } ch = this.readChar(); if ((ch == '!') || (ch == '?')) { this.skipSpecialTag(0); } else { this.unreadChar(ch); this.scanElement(this); return; } } } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>string != null</code> * <li><code>string.length() &gt; 0</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * </ul></dd></dl><dl> * * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string) throws XMLParseException { try { this.parseFromReader(new StringReader(string), /*startingLineNr*/ 1); } catch (IOException e) { // Java exception handling suxx } } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in <code>string</code> to scan. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>string != null</code> * <li><code>offset &lt; string.length()</code> * <li><code>offset &gt;= 0</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * </ul></dd></dl><dl> * * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string, int offset) throws XMLParseException { this.parseString(string.substring(offset)); } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in <code>string</code> to scan. * @param end * The character where to stop scanning. * This character is not scanned. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>string != null</code> * <li><code>end &lt;= string.length()</code> * <li><code>offset &lt; end</code> * <li><code>offset &gt;= 0</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * </ul></dd></dl><dl> * * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string, int offset, int end) throws XMLParseException { this.parseString(string.substring(offset, end)); } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in <code>string</code> to scan. * @param end * The character where to stop scanning. * This character is not scanned. * @param startingLineNr * The line number of the first line in the data. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>string != null</code> * <li><code>end &lt;= string.length()</code> * <li><code>offset &lt; end</code> * <li><code>offset &gt;= 0</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * </ul></dd></dl><dl> * * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string, int offset, int end, int startingLineNr) throws XMLParseException { string = string.substring(offset, end); try { this.parseFromReader(new StringReader(string), startingLineNr); } catch (IOException e) { // Java exception handling suxx } } /** * Reads one XML element from a char array and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in <code>string</code> to scan. * @param end * The character where to stop scanning. * This character is not scanned. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>input != null</code> * <li><code>end &lt;= input.length</code> * <li><code>offset &lt; end</code> * <li><code>offset &gt;= 0</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * </ul></dd></dl><dl> * * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseCharArray(char[] input, int offset, int end) throws XMLParseException { this.parseCharArray(input, offset, end, /*startingLineNr*/ 1); } /** * Reads one XML element from a char array and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in <code>string</code> to scan. * @param end * The character where to stop scanning. * This character is not scanned. * @param startingLineNr * The line number of the first line in the data. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>input != null</code> * <li><code>end &lt;= input.length</code> * <li><code>offset &lt; end</code> * <li><code>offset &gt;= 0</code> * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>the state of the receiver is updated to reflect the XML element * parsed from the reader * </ul></dd></dl><dl> * * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseCharArray(char[] input, int offset, int end, int startingLineNr) throws XMLParseException { try { Reader reader = new CharArrayReader(input, offset, end); this.parseFromReader(reader, startingLineNr); } catch (IOException e) { // This exception will never happen. } } /** * Removes a child element. * * @param child * The child element to remove. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>child != null</code> * <li><code>child</code> is a child element of the receiver * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>countChildren() => old.countChildren() - 1 * <li>enumerateChildren() => old.enumerateChildren() - child * <li>getChildren() => old.enumerateChildren() - child * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#getChildren() */ public void removeChild(XMLElement child) { this.children.removeElement(child); } /** * Removes an attribute. * * @param name * The name of the attribute. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>enumerateAttributeNames() * => old.enumerateAttributeNames() - name * <li>getAttribute(name) => <code>null</code> * </ul></dd></dl><dl> * * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String, * java.lang.String, * java.lang.String, boolean) * getBooleanAttribute(String, String, String, boolean) */ public void removeAttribute(String name) { if (this.ignoreCase) { name = name.toUpperCase(Locale.ENGLISH); } this.attributes.remove(name); } /** * Removes an attribute. * * @param name * The name of the attribute. * * @deprecated Use {@link #removeAttribute(java.lang.String) * removeAttribute} instead. */ public void removeProperty(String name) { this.removeAttribute(name); } /** * Removes an attribute. * * @param name * The name of the attribute. * * @deprecated Use {@link #removeAttribute(java.lang.String) * removeAttribute} instead. */ public void removeChild(String name) { this.removeAttribute(name); } /** * Creates a new similar XML element. * <P> * You should override this method when subclassing XMLElement. */ protected XMLElement createAnotherElement() { return new XMLElement(this.entities, this.ignoreWhitespace, false, this.ignoreCase); } // You should override this method when subclassing XMLElement. protected void completeElement() { } /** * Changes the content string. * * @param content * The new content string. */ public void setContent(String content) { this.contents = content; } /** * Changes the name of the element. * * @param name * The new name. * * @deprecated Use {@link #setName(java.lang.String) setName} instead. */ public void setTagName(String name) { this.setName(name); } /** * Changes the name of the element. * * @param name * The new name. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name</code> is a valid XML identifier * </ul></dd></dl> * * @see nanoxml.XMLElement#getName() */ public void setName(String name) { this.name = name; } /** * Writes the XML element to a string. * * @see nanoxml.XMLElement#write(java.io.Writer) write(Writer) */ public String toString() { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(out); this.write(writer); writer.flush(); return new String(out.toByteArray()); } catch (IOException e) { // Java exception handling suxx return super.toString(); } } /** * Writes the XML element to a writer. * * @param writer * The writer to write the XML data to. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>writer != null</code> * <li><code>writer</code> is not closed * </ul></dd></dl> * * @throws java.io.IOException * If the data could not be written to the writer. * * @see nanoxml.XMLElement#toString() */ public void write(Writer writer) throws IOException { write(writer, true); } public void writeWithoutClosingTag(Writer writer) throws IOException { write(writer, false); } public void writeClosingTag(Writer writer) throws IOException { writer.write('<'); writer.write('/'); writer.write(this.name); writer.write('>'); writer.write('\n'); } public void write(Writer writer, boolean withClosingTag) throws IOException { if (this.name == null) { this.writeEncoded(writer, this.contents); return; } writer.write('<'); writer.write(this.name); if (! this.attributes.isEmpty()) { Iterator enumerator = this.attributes.keySet().iterator(); while (enumerator.hasNext()) { writer.write(' '); String key = (String) enumerator.next(); String value = (String) this.attributes.get(key); writer.write(key); writer.write('='); writer.write('"'); this.writeEncoded(writer, value); writer.write('"'); } } if ((this.contents != null) && (this.contents.length() > 0)) { writer.write('>'); //writer.write('\n'); this.writeEncoded(writer, this.contents); if (withClosingTag) { writer.write('<'); writer.write('/'); writer.write(this.name); writer.write('>'); writer.write('\n'); } } else if (this.children.isEmpty()) { if (withClosingTag) { writer.write('/'); } writer.write('>'); writer.write('\n'); } else { writer.write('>'); writer.write('\n'); Enumeration enumerator = this.enumerateChildren(); while (enumerator.hasMoreElements()) { XMLElement child = (XMLElement) enumerator.nextElement(); child.write(writer); } if (withClosingTag) { writer.write('<'); writer.write('/'); writer.write(this.name); writer.write('>'); writer.write('\n'); } } } /** * Writes a string encoded to a writer. * * @param writer * The writer to write the XML data to. * @param str * The string to write encoded. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>writer != null</code> * <li><code>writer</code> is not closed * <li><code>str != null</code> * </ul></dd></dl> */ protected void writeEncoded(Writer writer, String str) throws IOException { for (int i = 0; i < str.length(); i += 1) { char ch = str.charAt(i); switch (ch) { case '<': writer.write('&'); writer.write('l'); writer.write('t'); writer.write(';'); break; case '>': writer.write('&'); writer.write('g'); writer.write('t'); writer.write(';'); break; case '&': writer.write('&'); writer.write('a'); writer.write('m'); writer.write('p'); writer.write(';'); break; case '"': writer.write('&'); writer.write('q'); writer.write('u'); writer.write('o'); writer.write('t'); writer.write(';'); break; case '\'': writer.write('&'); writer.write('a'); writer.write('p'); writer.write('o'); writer.write('s'); writer.write(';'); break; default: int unicode = (int) ch; if ((unicode < 32) || (unicode > 126)) { writer.write('&'); writer.write('#'); writer.write('x'); writer.write(Integer.toString(unicode, 16)); writer.write(';'); } else { writer.write(ch); } } } } /** * Scans an identifier from the current reader. * The scanned identifier is appended to <code>result</code>. * * @param result * The buffer in which the scanned identifier will be put. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>result != null</code> * <li>The next character read from the reader is a valid first * character of an XML identifier. * </ul></dd></dl> * * <dl><dt><b>Postconditions:</b></dt><dd> * <ul><li>The next character read from the reader won't be an identifier * character. * </ul></dd></dl><dl> */ protected void scanIdentifier(StringBuffer result) throws IOException { for (;;) { char ch = this.readChar(); if (((ch < 'A') || (ch > 'Z')) && ((ch < 'a') || (ch > 'z')) && ((ch < '0') || (ch > '9')) && (ch != '_') && (ch != '.') && (ch != ':') && (ch != '-') && (ch <= '\u007E')) { this.unreadChar(ch); return; } result.append(ch); } } /** * This method scans an identifier from the current reader. * * @return the next character following the whitespace. */ protected char scanWhitespace() throws IOException { for (;;) { char ch = this.readChar(); switch (ch) { case ' ': case '\t': case '\n': case '\r': break; default: return ch; } } } /** * This method scans an identifier from the current reader. * The scanned whitespace is appended to <code>result</code>. * * @return the next character following the whitespace. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>result != null</code> * </ul></dd></dl> */ protected char scanWhitespace(StringBuffer result) throws IOException { for (;;) { char ch = this.readChar(); switch (ch) { case ' ': case '\t': case '\n': result.append(ch); case '\r': break; default: return ch; } } } /** * This method scans a delimited string from the current reader. * The scanned string without delimiters is appended to * <code>string</code>. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>string != null</code> * <li>the next char read is the string delimiter * </ul></dd></dl> */ protected void scanString(StringBuffer string) throws IOException { char delimiter = this.readChar(); if ((delimiter != '\'') && (delimiter != '"')) { throw this.expectedInput("' or \""); } for (;;) { char ch = this.readChar(); if (ch == delimiter) { return; } else if (ch == '&') { this.resolveEntity(string); } else { string.append(ch); } } } /** * Scans a #PCDATA element. CDATA sections and entities are resolved. * The next &lt; char is skipped. * The scanned data is appended to <code>data</code>. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>data != null</code> * </ul></dd></dl> */ protected void scanPCData(StringBuffer data) throws IOException { for (;;) { char ch = this.readChar(); if (ch == '<') { ch = this.readChar(); if (ch == '!') { this.checkCDATA(data); } else { this.unreadChar(ch); return; } } else if (ch == '&') { this.resolveEntity(data); } else { data.append(ch); } } } /** * Scans a special tag and if the tag is a CDATA section, append its * content to <code>buf</code>. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>buf != null</code> * <li>The first &lt; has already been read. * </ul></dd></dl> */ protected boolean checkCDATA(StringBuffer buf) throws IOException { char ch = this.readChar(); if (ch != '[') { this.unreadChar(ch); this.skipSpecialTag(0); return false; } else if (! this.checkLiteral("CDATA[")) { this.skipSpecialTag(1); // one [ has already been read return false; } else { int delimiterCharsSkipped = 0; while (delimiterCharsSkipped < 3) { ch = this.readChar(); switch (ch) { case ']': if (delimiterCharsSkipped < 2) { delimiterCharsSkipped += 1; } else { buf.append(']'); buf.append(']'); delimiterCharsSkipped = 0; } break; case '>': if (delimiterCharsSkipped < 2) { for (int i = 0; i < delimiterCharsSkipped; i++) { buf.append(']'); } delimiterCharsSkipped = 0; buf.append('>'); } else { delimiterCharsSkipped = 3; } break; default: for (int i = 0; i < delimiterCharsSkipped; i += 1) { buf.append(']'); } buf.append(ch); delimiterCharsSkipped = 0; } } return true; } } /** * Skips a comment. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li>The first &lt;!-- has already been read. * </ul></dd></dl> */ protected void skipComment() throws IOException { int dashesToRead = 2; while (dashesToRead > 0) { char ch = this.readChar(); if (ch == '-') { dashesToRead -= 1; } else { dashesToRead = 2; } } if (this.readChar() != '>') { throw this.expectedInput(">"); } } /** * Skips a special tag or comment. * * @param bracketLevel The number of open square brackets ([) that have * already been read. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li>The first &lt;! has already been read. * <li><code>bracketLevel >= 0</code> * </ul></dd></dl> */ protected void skipSpecialTag(int bracketLevel) throws IOException { int tagLevel = 1; // < char stringDelimiter = '\0'; if (bracketLevel == 0) { char ch = this.readChar(); if (ch == '[') { bracketLevel += 1; } else if (ch == '-') { ch = this.readChar(); if (ch == '[') { bracketLevel += 1; } else if (ch == ']') { bracketLevel -= 1; } else if (ch == '-') { this.skipComment(); return; } } } while (tagLevel > 0) { char ch = this.readChar(); if (stringDelimiter == '\0') { if ((ch == '"') || (ch == '\'')) { stringDelimiter = ch; } else if (bracketLevel <= 0) { if (ch == '<') { tagLevel += 1; } else if (ch == '>') { tagLevel -= 1; } } if (ch == '[') { bracketLevel += 1; } else if (ch == ']') { bracketLevel -= 1; } } else { if (ch == stringDelimiter) { stringDelimiter = '\0'; } } } } /** * Scans the data for literal text. * Scanning stops when a character does not match or after the complete * text has been checked, whichever comes first. * * @param literal the literal to check. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>literal != null</code> * </ul></dd></dl> */ protected boolean checkLiteral(String literal) throws IOException { int length = literal.length(); for (int i = 0; i < length; i += 1) { if (this.readChar() != literal.charAt(i)) { return false; } } return true; } /** * Reads a character from a reader. */ protected char readChar() throws IOException { if (this.charReadTooMuch != '\0') { char ch = this.charReadTooMuch; this.charReadTooMuch = '\0'; return ch; } else { int i = this.reader.read(); if (i < 0) { throw this.unexpectedEndOfData(); } else if (i == 10) { this.parserLineNr += 1; return '\n'; } else { return (char) i; } } } /** * Scans an XML element. * * @param elt The element that will contain the result. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li>The first &lt; has already been read. * <li><code>elt != null</code> * </ul></dd></dl> */ protected void scanElement(XMLElement elt) throws IOException { StringBuffer buf = new StringBuffer(); this.scanIdentifier(buf); String name = buf.toString(); elt.setName(name); char ch = this.scanWhitespace(); // Scan the attributes of opening tag while ((ch != '>') && (ch != '/')) { // Not the end of the tag buf.setLength(0); this.unreadChar(ch); this.scanIdentifier(buf); String key = buf.toString(); ch = this.scanWhitespace(); if (ch != '=') { throw this.expectedInput("="); } this.unreadChar(this.scanWhitespace()); buf.setLength(0); this.scanString(buf); elt.setAttribute(key, buf); ch = this.scanWhitespace(); } if (ch == '/') { // Case of self ending tag ch = this.readChar(); if (ch != '>') { throw this.expectedInput(">"); } elt.completeElement(); return; } // This part is unclear - probing for PCDATA buf.setLength(0); ch = this.scanWhitespace(buf); if (ch != '<') { // Either: PCDATA this.unreadChar(ch); this.scanPCData(buf); } else { // Or: Maybe sequence of children tags for (;;) { // This is a loop, after all ch = this.readChar(); if (ch == '!') { if (this.checkCDATA(buf)) { this.scanPCData(buf); break; } else { ch = this.scanWhitespace(buf); if (ch != '<') { this.unreadChar(ch); this.scanPCData(buf); break; } } } else { buf.setLength(0); break; } } } if (buf.length() == 0) { // Not PCDATA, '<' already read while (ch != '/') { if (ch == '!') { // Comment ch = this.readChar(); if (ch != '-') { throw this.expectedInput("Comment or Element"); } ch = this.readChar(); if (ch != '-') { throw this.expectedInput("Comment or Element"); } this.skipComment(); } else { // Not Comment this.unreadChar(ch); XMLElement child = this.createAnotherElement(); // Here goes the recursion. this.scanElement(child); elt.addChild(child); } ch = this.scanWhitespace(); if (ch != '<') { throw this.expectedInput("<"); } ch = this.readChar(); } this.unreadChar(ch); } else { // PCDATA if (this.ignoreWhitespace) { elt.setContent(buf.toString().trim()); } else { elt.setContent(buf.toString()); } } // ch = this.readChar(); if (ch != '/') { throw this.expectedInput("/"); } this.unreadChar(this.scanWhitespace()); if (! this.checkLiteral(name)) { throw this.expectedInput(name); } if (this.scanWhitespace() != '>') { throw this.expectedInput(">"); } elt.completeElement(); } /** * Resolves an entity. The name of the entity is read from the reader. * The value of the entity is appended to <code>buf</code>. * * @param buf Where to put the entity value. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li>The first &amp; has already been read. * <li><code>buf != null</code> * </ul></dd></dl> */ protected void resolveEntity(StringBuffer buf) throws IOException { char ch = '\0'; StringBuffer keyBuf = new StringBuffer(); for (;;) { ch = this.readChar(); if (ch == ';') { break; } keyBuf.append(ch); } String key = keyBuf.toString(); if (key.charAt(0) == '#') { try { if (key.charAt(1) == 'x') { ch = (char) Integer.parseInt(key.substring(2), 16); } else { ch = (char) Integer.parseInt(key.substring(1), 10); } } catch (NumberFormatException e) { throw this.unknownEntity(key); } buf.append(ch); } else { char[] value = (char[]) this.entities.get(key); if (value == null) { throw this.unknownEntity(key); } buf.append(value); } } /** * Pushes a character back to the read-back buffer. * * @param ch The character to push back. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li>The read-back buffer is empty. * <li><code>ch != '\0'</code> * </ul></dd></dl> */ protected void unreadChar(char ch) { this.charReadTooMuch = ch; } /** * Creates a parse exception for when an invalid valueset is given to * a method. * * @param name The name of the entity. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * </ul></dd></dl> */ protected XMLParseException invalidValueSet(String name) { String msg = "Invalid value set (entity name = \"" + name + "\")"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when an invalid value is given to a * method. * * @param name The name of the entity. * @param value The value of the entity. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>value != null</code> * </ul></dd></dl> */ protected XMLParseException invalidValue(String name, String value) { String msg = "Attribute \"" + name + "\" does not contain a valid " + "value (\"" + value + "\")"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when the end of the data input has been * reached. */ protected XMLParseException unexpectedEndOfData() { String msg = "Unexpected end of data reached"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when a syntax error occured. * * @param context The context in which the error occured. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>context != null</code> * <li><code>context.length() &gt; 0</code> * </ul></dd></dl> */ protected XMLParseException syntaxError(String context) { String msg = "Syntax error while parsing " + context; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when the next character read is not * the character that was expected. * * @param charSet The set of characters (in human readable form) that was * expected. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>charSet != null</code> * <li><code>charSet.length() &gt; 0</code> * </ul></dd></dl> */ protected XMLParseException expectedInput(String charSet) { String msg = "Expected: " + charSet; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when an entity could not be resolved. * * @param name The name of the entity. * * </dl><dl><dt><b>Preconditions:</b></dt><dd> * <ul><li><code>name != null</code> * <li><code>name.length() &gt; 0</code> * </ul></dd></dl> */ protected XMLParseException unknownEntity(String name) { String msg = "Unknown or invalid entity: &" + name + ";"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } }

The table below shows all metrics for XMLElement.java.

MetricValueDescription
BLOCKS247.00Number of blocks
BLOCK_COMMENT31.00Number of block comment lines
COMMENTS1669.00Comment lines
COMMENT_DENSITY 2.22Comment density
COMPARISONS97.00Number of comparison operators
CYCLOMATIC239.00Cyclomatic complexity
DECL_COMMENTS103.00Comments in declarations
DOC_COMMENT1623.00Number of javadoc comment lines
ELOC753.00Effective lines of code
EXEC_COMMENTS12.00Comments in executable code
EXITS96.00Procedure exits
FUNCTIONS89.00Number of function declarations
HALSTEAD_DIFFICULTY116.02Halstead difficulty
HALSTEAD_EFFORT 0.00Halstead effort
INTERFACE_COMPLEXITY389.00Interface complexity
JAVA0001 0.00JAVA0001 Package name does not contain only lower case letters
JAVA0002 1.00JAVA0002 Package name does not begin with a top level domain name or country code
JAVA0003 0.00JAVA0003 Minimize use of on-demand (.*) imports
JAVA0004 0.00JAVA0004 Unnecessary import from java.lang
JAVA0005 0.00JAVA0005 Imports not in specified order
JAVA0006 0.00JAVA0006 Empty finally block
JAVA0007 0.00JAVA0007 Should not declare public field
JAVA0008 0.00JAVA0008 Empty catch block
JAVA0009 0.00JAVA0009 Protected member in final class
JAVA0010 0.00JAVA0010 Non-instantiable class does not contain a non-private static member
JAVA0011 0.00JAVA0011 Abstract class does not contain an abstract method
JAVA0012 0.00JAVA0012 Non-constructor method with same name as declaring class
JAVA0013 0.00JAVA0013 Non-blank final field is not static
JAVA0014 0.00JAVA0014 Class with only static members has non-private constructor
JAVA0015 0.00JAVA0015 Package class contains public nested type
JAVA0016 0.00JAVA0016 Abstract class contains public constructor
JAVA0017 0.00JAVA0017 Class name does not have required form
JAVA0018 0.00JAVA0018 Method name does not have required form
JAVA0019 0.00JAVA0019 Interface name does not have required form
JAVA0020 0.00JAVA0020 Field name does not have required form
JAVA0021 0.00JAVA0021 Interface method name does not have required form
JAVA0022 0.00JAVA0022 Static final field name does not have required form
JAVA0023 0.00JAVA0023 Empty finalize method
JAVA0024 0.00JAVA0024 Empty class
JAVA0025 0.00JAVA0025 Method override is empty
JAVA0026 0.00JAVA0026 Finalize method with parameters
JAVA0029 0.00JAVA0029 Private method not used
JAVA0030 0.00JAVA0030 Private field not used
JAVA0031 3.00JAVA0031 Case statement not properly closed
JAVA0032 0.00JAVA0032 Switch statement missing default
JAVA0033 0.00JAVA0033 default: not last case in switch statement
JAVA0034 0.00JAVA0034 Missing braces in if statement
JAVA0035 0.00JAVA0035 Missing braces in for statement
JAVA0036 0.00JAVA0036 Missing braces in while statement
JAVA0038 0.00JAVA0038 Non-case label in switch statement
JAVA0039 0.00JAVA0039 Break statement with label
JAVA0040 0.00JAVA0040 Switch statement contains N cases (maximum: M)
JAVA0041 0.00JAVA0041 Nested synchronized block
JAVA0042 0.00JAVA0042 Empty synchronized statement
JAVA0043 0.00JAVA0043 Inner class does not use outer class
JAVA0044 0.00JAVA0044 Serializable class with no instance variables
JAVA0045 0.00JAVA0045 Serializable class with only transient fields
JAVA0046 0.00JAVA0046 Name of class not derived from Exception ends with 'Exception'
JAVA0047 0.00JAVA0047 Serializable class derives from invalid base class
JAVA0048 0.00JAVA0048 Name of class derived from Exception does not end with 'Exception'
JAVA0049 1.00JAVA0049 Nested block at depth N (maximum: M)
JAVA0050 0.00JAVA0050 Class derives from java.lang.Error
JAVA0051 0.00JAVA0051 Class derives from java.lang.RuntimeException
JAVA0052 0.00JAVA0052 Class derives from java.lang.Throwable
JAVA0053 0.00JAVA0053 Unused label
JAVA0054 0.00JAVA0054 Inheritance depth N exceeds maximum M
JAVA0055 0.00JAVA0055 Class should be interface
JAVA0056 0.00JAVA0056 Unnecessary abstract modifier for interface or annotation
JAVA0057 0.00JAVA0057 Unnecessary default constructor
JAVA0058 0.00JAVA0058 Constructor calls super()
JAVA0059 0.00JAVA0059 Method override only calls super()
JAVA0061 0.00JAVA0061 Inaccessible member in anonymous class
JAVA0062 0.00JAVA0062 Public class missing public member or protected constructor
JAVA0063 0.00JAVA0063 Identifier name should not contain '$'
JAVA0064 0.00JAVA0064 N variations of identifier name (maximum: M)
JAVA0065 0.00JAVA0065 Unnecessary final modifier for method in final class
JAVA0066 0.00JAVA0066 Unnecessary modifier for interface nested type
JAVA0067 0.00JAVA0067 Array descriptor on identifier name
JAVA0068 0.00JAVA0068 Modifiers not declared in recommended order
JAVA0071 0.00JAVA0071 Strings compared with ==
JAVA0073 0.00JAVA0073 Integer division in floating-point context
JAVA0074 0.00JAVA0074 Use of Object.notify()
JAVA007532.00JAVA0075 Method parameter hides field
JAVA0076 4.00JAVA0076 Use of magic number
JAVA0077 0.00JAVA0077 Private field not used in declaring class
JAVA0078 0.00JAVA0078 Floating point values compared with ==
JAVA0079 0.00JAVA0079 Use of instance to reference static member
JAVA0080 0.00JAVA0080 Import declaration not used
JAVA0081 0.00JAVA0081 Boolean literal in comparison
JAVA0082 0.00JAVA0082 Unnecessary widening cast
JAVA0083 0.00JAVA0083 Unnecessary instanceof test
JAVA0084 0.00JAVA0084 Should use compound assignment operator
JAVA0085 0.00JAVA0085 Use of sun.* class
JAVA0087 0.00JAVA0087 Use of Thread.sleep()
JAVA0089 0.00JAVA0089 Use of restricted package
JAVA0092 0.00JAVA0092 Use of restricted type
JAVA0093 0.00JAVA0093 Redundant assignment
JAVA0094 0.00JAVA0094 Field hides a superclass field
JAVA0095 0.00JAVA0095 Uninitialized private field
JAVA0096 0.00JAVA0096 Field in nested class hides outer field
JAVA0098 0.00JAVA0098 Minimize use of implicit field initializers
JAVA0100 1.00JAVA0100 Class contains N non-final fields (maximum: M)
JAVA0101 0.00JAVA0101 Unnecessary modifier for field in interface
JAVA0102 0.00JAVA0102 Last statement in finalize() not super.finalize()
JAVA0103 0.00JAVA0103 Explicit call to finalize()
JAVA0104 0.00JAVA0104 finalize() only calls super.finalize()
JAVA0105 0.00JAVA0105 Duplicate import declaration
JAVA0106 0.00JAVA0106 Unnecessary import from current package
JAVA010837.00JAVA0108 Incorrect javadoc: no @param tag for 'parameter'
JAVA0109 7.00JAVA0109 Incorrect javadoc: no parameter 'parameter'
JAVA011044.00JAVA0110 Incorrect javadoc: no @return tag
JAVA0111 0.00JAVA0111 Incorrect javadoc: @return tag for void method
JAVA0112 8.00JAVA0112 Incorrect javadoc: no exception 'exception' in throws
JAVA0113 0.00JAVA0113 Incorrect javadoc: no @author tag
JAVA0114 0.00JAVA0114 Incorrect javadoc: no @version tag
JAVA011521.00JAVA0115 Incorrect javadoc: no @throws or @exception tag for 'exception'
JAVA0116 0.00JAVA0116 Missing javadoc: field 'field'
JAVA0117 5.00JAVA0117 Missing javadoc: method 'method'
JAVA0118 0.00JAVA0118 Missing javadoc: type 'type'
JAVA0119 0.00JAVA0119 Control variable changed within body of for loop
JAVA0123 8.00JAVA0123 Use all three components of for loop
JAVA0125 0.00JAVA0125 Continue statement with label
JAVA0126 8.00JAVA0126 Method declares unchecked exception in throws
JAVA0128 0.00JAVA0128 Public constructor in non-public class
JAVA0130 0.00JAVA0130 Non-static method does not use instance fields
JAVA0131 0.00JAVA0131 Compatible method does not override base
JAVA0132 2.00JAVA0132 Method overload with compatible signature
JAVA0133 0.00JAVA0133 Non-synchronized method overrides synchronized method
JAVA0135 0.00JAVA0135 Only one of Object.equals and Object.hashCode defined: missing 'method'
JAVA0136 1.00JAVA0136 N methods defined in class (maximum: M)
JAVA0137 0.00JAVA0137 Non-abstract class missing constructor
JAVA0138 0.00JAVA0138 N parameters defined for method (maximum: M)
JAVA0139 0.00JAVA0139 Definition of main other than public static void main(java.lang.String[])
JAVA0141 0.00JAVA0141 Unnecessary modifier for method in interface
JAVA0143 0.00JAVA0143 Synchronized method
JAVA0144 0.00JAVA0144 Line exceeds maximum M characters
JAVA0145 0.00JAVA0145 Tab character used in source file
JAVA0150 0.00JAVA0150 java.lang.Error (or subclass) thrown
JAVA0153 0.00JAVA0153 Inefficient conversion of integer to string
JAVA0159 0.00JAVA0159 Inefficient conversion of string to integer
JAVA0160 0.00JAVA0160 Method does not throw specified exception
JAVA0161 0.00JAVA0161 Conditional wait() not in loop
JAVA0163 0.00JAVA0163 Empty statement
JAVA0165 0.00JAVA0165 Conflicting return statement in finally block
JAVA0166 1.00JAVA0166 Generic exception caught
JAVA0167 0.00JAVA0167 ThreadDeath not rethrown
JAVA0169 0.00JAVA0169 Unnecessary catch block: exception 'exception'
JAVA0170 0.00JAVA0170 Caught exception not derived from java.lang.Exception
JAVA0171 0.00JAVA0171 Unused local variable
JAVA0173 0.00JAVA0173 Unused method parameter
JAVA0174 0.00JAVA0174 Assigned local variable never used
JAVA0175 0.00JAVA0175 Successive assignment to variable
JAVA0176 0.00JAVA0176 Local variable name does not have required form
JAVA0177 3.00JAVA0177 Variable declaration missing initializer
JAVA0179 2.00JAVA0179 Local variable hides visible field
JAVA0233 0.00JAVA0233 Definition of serialVersionUID other than 'private static final long serialVersionUID'
JAVA0234 0.00JAVA0234 Class is Serializable but does not define serialVersionUID
JAVA0235 1.00JAVA0235 Class defines serialVersionUID but does not implement Serializable
JAVA0236 0.00JAVA0236 Attempt to clone an object which does not implement Cloneable
JAVA0237 0.00JAVA0237 Class implements Cloneable but does not have public clone method
JAVA0238 0.00JAVA0238 Clone method does not call super.clone()
JAVA0239 0.00JAVA0239 Class declares 'readObject' or 'writeObject' but does not implement Serializable
JAVA0240 0.00JAVA0240 Serializable class which declares readObject or writeObject but not both
JAVA0241 0.00JAVA0241 'readObject' or 'writeObject' should be declared private in Serializable class
JAVA0242 0.00JAVA0242 Transient field in non-Serializable class
JAVA0243 0.00JAVA0243 'readResolve' or 'writeReplace' should be declared private or protected
JAVA0244 0.00JAVA0244 Field or method name in subclass differs only by case from inherited field or method
JAVA0245 0.00JAVA0245 JUnit TestCase with non-trivial constructor
JAVA0246 0.00JAVA0246 JUnit assertXXX statement missing message parameter
JAVA0247 0.00JAVA0247 JUnit 'setUp()' and 'tearDown()' should call super method
JAVA0248 0.00JAVA0248 JUnit method 'setUp' or 'tearDown' with incorrect signature
JAVA0249 0.00JAVA0249 JUnit TestCase 'suite()' should be declared static
JAVA0250 0.00JAVA0250 JUnit TestCase declares testXXX method with incorrect signature
JAVA0251 0.00JAVA0251 Use '%n' for line breaks in printf/format for platform independence
JAVA0252 0.00JAVA0252 'enum' is a Java 1.5 reserved word
JAVA0253 0.00JAVA0253 Not all enum constants consumed in switch statement
JAVA0254 1.00JAVA0254 Use enhanced for loop construct instead of Iterator
JAVA0255 0.00JAVA0255 Result of method invocation not used
JAVA0256 0.00JAVA0256 Assignment of external collection/array to field
JAVA0257 0.00JAVA0257 Use of 'Constant Interface' anti-pattern
JAVA0258 1.00JAVA0258 Implement Iterable for foreach compatibility
JAVA0259 0.00JAVA0259 Return of collection/array field
JAVA0260 0.00JAVA0260 Use 'enum' instead of Enumerated Type pattern
JAVA0261 0.00JAVA0261 Use specialized Enum collection types
JAVA0262 0.00JAVA0262 Use of char in integer context
JAVA0263 0.00JAVA0263 Long literal ends with 'l' instead of 'L'
JAVA0264 0.00JAVA0264 Integer math in long context - check for overflow
JAVA0265 0.00JAVA0265 Use of Throwable.printStackTrace()
JAVA0266 0.00JAVA0266 Use of System.out
JAVA0267 0.00JAVA0267 Use of System.err
JAVA0269 0.00JAVA0269 Contents of StringBuffer never used
JAVA0270 0.00JAVA0270 Use Java 5.0 enhanced for loop construct to iterate over all elements in an array
JAVA0271 0.00JAVA0271 Minimize use of on-demand (.*) static imports
JAVA0272 0.00JAVA0272 Thread.run() called
JAVA0273 0.00JAVA0273 Non-final derivative of Thread calls start() in constructor
JAVA0274 0.00JAVA0274 Serializable class has a synchronized readObject()
JAVA0275 0.00JAVA0275 Serializable class has a synchronized writeObject() and no other synchronized methods
JAVA0276 0.00JAVA0276 Unnecessary use of String constructor
JAVA0277 0.00JAVA0277 Iterator.next() implementation does not throw NoSuchElementException
JAVA0278 0.00JAVA0278 Unnecessary use of Boolean constructor
JAVA0279 0.00JAVA0279 Serialization method readObject or readObjectNoData calls an overridable method
JAVA0280 0.00JAVA0280 IllegalMonitorStateException caught
JAVA0281 0.00JAVA0281 Iterator.next() not called in loop
JAVA0282 0.00JAVA0282 Call to Iterator.next() in loop which does not test Iterator.hasNext()
JAVA0283 0.00JAVA0283 Control variable not updated in loop body
JAVA0284 0.00JAVA0284 Explicit garbage collection
JAVA0285 0.00JAVA0285 Dereference of potentially null variable
JAVA0286 0.00JAVA0286 Dereference of null variable
JAVA0287 0.00JAVA0287 Unnecessary null check
JAVA0288 0.00JAVA0288 Inconsistent null check
LINES2930.00Number of lines in the source file
LINE_COMMENT15.00Number of line comments
LOC1042.00Lines of code
LOGICAL_LINES431.00Number of statements
LOOPS20.00Number of loops
NEST_DEPTH 6.00Maximum nesting depth
OPERANDS1722.00Number of operands
OPERATORS3894.00Number of operators
PARAMS132.00Number of formal parameter declarations
PROGRAM_LENGTH5616.00Halstead program length
PROGRAM_VOCAB480.00Halstead program vocabulary
PROGRAM_VOLUME 0.00Halstead program volume
RETURNS257.00Number of return points from functions
SIZE99247.00Size of the file in bytes
UNIQUE_OPERANDS423.00Number of unique operands
UNIQUE_OPERATORS57.00Number of unique operators
WHITESPACE219.00Number of whitespace lines