By default (when no XML SAX and DOM 2 present) parsing the properties stream with simple nanoXML parser
1.1 --- a/build.xml Wed Jun 24 14:53:01 2009 +0200
1.2 +++ b/build.xml Wed Jun 24 16:38:24 2009 +0200
1.3 @@ -16,7 +16,7 @@
1.4 </target>
1.5
1.6 <!-- basic parameters -->
1.7 - <property name="plugs" value="../../plugs"/>
1.8 + <property name="plugs" value="${ant.file.modularize}/../../../plugs"/>
1.9 <fail message="You need to provide location of plugs">
1.10 <condition><not><available file="${plugs}/jre/lib/rt-closed.jar"/></not></condition>
1.11 </fail>
1.12 @@ -63,7 +63,13 @@
1.13 <pathelement location="src/solaris/classes"/>
1.14 <!-- <pathelement location="src/windows/classes"/> -->
1.15 </path>
1.16 - <property name="build.dir" location="build/modularize"/>
1.17 + <property name="build.dir" location="${ant.file.modularize}/../build/modularize"/>
1.18 + <path id="boot">
1.19 + <fileset dir="${build.dir}">
1.20 + <include name="*.jar"/>
1.21 + </fileset>
1.22 + </path>
1.23 + <property name="test.dir" value="${ant.file.modularize}/../build/test"/>
1.24
1.25 <!-- this is the core of the separation - definition
1.26 of what classes belong into what compilation group.
1.27 @@ -360,15 +366,11 @@
1.28
1.29 <!-- basic sanity tests -->
1.30 <target name="test">
1.31 - <property name="test.dir" value="build/test"/>
1.32 <mkdir dir="${test.dir}"/>
1.33 - <path id="boot">
1.34 - <fileset dir="${build.dir}">
1.35 - <include name="*.jar"/>
1.36 - </fileset>
1.37 - </path>
1.38 -
1.39 - <javac srcdir="test/java/util/Properties" destdir="${test.dir}" includeantruntime="false" includejavaruntime="false">
1.40 + <javac srcdir="test/java/util/Properties" destdir="${test.dir}"
1.41 + includeantruntime="false" includejavaruntime="false"
1.42 + debug="true" debuglevel="lines,vars,source"
1.43 + >
1.44 <bootclasspath refid="boot"/>
1.45 </javac>
1.46
1.47 @@ -402,6 +404,8 @@
1.48 includejavaruntime="false"
1.49 includeantruntime="false"
1.50 classpath="${module.cp}:${plugs}/jre/lib/rt-closed.jar"
1.51 + debug="true"
1.52 + debuglevel="lines,vars,source"
1.53 >
1.54 <src refid="src.path"/>
1.55 <and>
2.1 --- a/src/share/classes/sun/util/xml/DefaultPropertiesXMLUtils.java Wed Jun 24 14:53:01 2009 +0200
2.2 +++ b/src/share/classes/sun/util/xml/DefaultPropertiesXMLUtils.java Wed Jun 24 16:38:24 2009 +0200
2.3 @@ -40,7 +40,14 @@
2.4 public class DefaultPropertiesXMLUtils extends PropertiesXMLUtils {
2.5 public void load(Properties props, InputStream in)
2.6 throws IOException, InvalidPropertiesFormatException {
2.7 - throw new IOException("Not implemented yet");
2.8 + XMLElement e = new XMLElement();
2.9 + e.parseFromReader(new InputStreamReader(in, "UTF-8"));
2.10 + for (Object o : e.getChildren()) {
2.11 + XMLElement ch = (XMLElement)o;
2.12 + if (ch.getName().equals("entry")) {
2.13 + props.put(ch.getAttribute("key"), ch.getContent());
2.14 + }
2.15 + }
2.16 }
2.17 public void save(Properties props, OutputStream out, String comment, String encoding)
2.18 throws IOException {
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/share/classes/sun/util/xml/XMLElement.java Wed Jun 24 16:38:24 2009 +0200
3.3 @@ -0,0 +1,2874 @@
3.4 +/* XMLElement.java
3.5 + *
3.6 + * $Revision: 1.4 $
3.7 + * $Date: 2002/03/24 10:27:59 $
3.8 + * $Name: RELEASE_2_2_1 $
3.9 + *
3.10 + * This file is part of NanoXML 2 Lite.
3.11 + * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
3.12 + *
3.13 + * This software is provided 'as-is', without any express or implied warranty.
3.14 + * In no event will the authors be held liable for any damages arising from the
3.15 + * use of this software.
3.16 + *
3.17 + * Permission is granted to anyone to use this software for any purpose,
3.18 + * including commercial applications, and to alter it and redistribute it
3.19 + * freely, subject to the following restrictions:
3.20 + *
3.21 + * 1. The origin of this software must not be misrepresented; you must not
3.22 + * claim that you wrote the original software. If you use this software in
3.23 + * a product, an acknowledgment in the product documentation would be
3.24 + * appreciated but is not required.
3.25 + *
3.26 + * 2. Altered source versions must be plainly marked as such, and must not be
3.27 + * misrepresented as being the original software.
3.28 + *
3.29 + * 3. This notice may not be removed or altered from any source distribution.
3.30 + *****************************************************************************/
3.31 +
3.32 +
3.33 +package sun.util.xml;
3.34 +
3.35 +
3.36 +import java.io.ByteArrayOutputStream;
3.37 +import java.io.CharArrayReader;
3.38 +import java.io.IOException;
3.39 +import java.io.OutputStreamWriter;
3.40 +import java.io.Reader;
3.41 +import java.io.StringReader;
3.42 +import java.io.Writer;
3.43 +import java.util.Enumeration;
3.44 +import java.util.Hashtable;
3.45 +import java.util.Vector;
3.46 +
3.47 +
3.48 +/**
3.49 + * XMLElement is a representation of an XML object. The object is able to parse
3.50 + * XML code.
3.51 + * <P><DL>
3.52 + * <DT><B>Parsing XML Data</B></DT>
3.53 + * <DD>
3.54 + * You can parse XML data using the following code:
3.55 + * <UL><CODE>
3.56 + * XMLElement xml = new XMLElement();<BR>
3.57 + * FileReader reader = new FileReader("filename.xml");<BR>
3.58 + * xml.parseFromReader(reader);
3.59 + * </CODE></UL></DD></DL>
3.60 + * <DL><DT><B>Retrieving Attributes</B></DT>
3.61 + * <DD>
3.62 + * You can enumerate the attributes of an element using the method
3.63 + * {@link #enumerateAttributeNames() enumerateAttributeNames}.
3.64 + * The attribute values can be retrieved using the method
3.65 + * {@link #getStringAttribute(java.lang.String) getStringAttribute}.
3.66 + * The following example shows how to list the attributes of an element:
3.67 + * <UL><CODE>
3.68 + * XMLElement element = ...;<BR>
3.69 + * Enumeration enumV = element.getAttributeNames();<BR>
3.70 + * while (enumV.hasMoreElements()) {<BR>
3.71 + * String key = (String) enumV.nextElement();<BR>
3.72 + * String value = element.getStringAttribute(key);<BR>
3.73 + * System.out.println(key + " = " + value);<BR>
3.74 + * }
3.75 + * </CODE></UL></DD></DL>
3.76 + * <DL><DT><B>Retrieving Child Elements</B></DT>
3.77 + * <DD>
3.78 + * You can enumerate the children of an element using
3.79 + * {@link #enumerateChildren() enumerateChildren}.
3.80 + * The number of child elements can be retrieved using
3.81 + * {@link #countChildren() countChildren}.
3.82 + * </DD></DL>
3.83 + * <DL><DT><B>Elements Containing Character Data</B></DT>
3.84 + * <DD>
3.85 + * If an elements contains character data, like in the following example:
3.86 + * <UL><CODE>
3.87 + * <title>The Title</title>
3.88 + * </CODE></UL>
3.89 + * you can retrieve that data using the method
3.90 + * {@link #getContent() getContent}.
3.91 + * </DD></DL>
3.92 + * <DL><DT><B>Subclassing XMLElement</B></DT>
3.93 + * <DD>
3.94 + * When subclassing XMLElement, you need to override the method
3.95 + * {@link #createAnotherElement() createAnotherElement}
3.96 + * which has to return a new copy of the receiver.
3.97 + * </DD></DL>
3.98 + * <P>
3.99 + *
3.100 + * @see nanoxml.XMLParseException
3.101 + *
3.102 + * @author Marc De Scheemaecker
3.103 + * <<A href="mailto:cyberelf@mac.com">cyberelf@mac.com</A>>
3.104 + * @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
3.105 + */
3.106 +class XMLElement {
3.107 +
3.108 + /**
3.109 + * Serialization serial version ID.
3.110 + */
3.111 + static final long serialVersionUID = 6685035139346394777L;
3.112 +
3.113 +
3.114 + /**
3.115 + * Major version of NanoXML. Classes with the same major and minor
3.116 + * version are binary compatible. Classes with the same major version
3.117 + * are source compatible. If the major version is different, you may
3.118 + * need to modify the client source code.
3.119 + *
3.120 + * @see nanoxml.XMLElement#NANOXML_MINOR_VERSION
3.121 + */
3.122 + public static final int NANOXML_MAJOR_VERSION = 2;
3.123 +
3.124 +
3.125 + /**
3.126 + * Minor version of NanoXML. Classes with the same major and minor
3.127 + * version are binary compatible. Classes with the same major version
3.128 + * are source compatible. If the major version is different, you may
3.129 + * need to modify the client source code.
3.130 + *
3.131 + * @see nanoxml.XMLElement#NANOXML_MAJOR_VERSION
3.132 + */
3.133 + public static final int NANOXML_MINOR_VERSION = 2;
3.134 +
3.135 +
3.136 + /**
3.137 + * The attributes given to the element.
3.138 + *
3.139 + * <dl><dt><b>Invariants:</b></dt><dd>
3.140 + * <ul><li>The field can be empty.
3.141 + * <li>The field is never <code>null</code>.
3.142 + * <li>The keys and the values are strings.
3.143 + * </ul></dd></dl>
3.144 + */
3.145 + private Hashtable attributes;
3.146 +
3.147 +
3.148 + /**
3.149 + * Child elements of the element.
3.150 + *
3.151 + * <dl><dt><b>Invariants:</b></dt><dd>
3.152 + * <ul><li>The field can be empty.
3.153 + * <li>The field is never <code>null</code>.
3.154 + * <li>The elements are instances of <code>XMLElement</code>
3.155 + * or a subclass of <code>XMLElement</code>.
3.156 + * </ul></dd></dl>
3.157 + */
3.158 + private Vector children;
3.159 +
3.160 +
3.161 + /**
3.162 + * The name of the element.
3.163 + *
3.164 + * <dl><dt><b>Invariants:</b></dt><dd>
3.165 + * <ul><li>The field is <code>null</code> iff the element is not
3.166 + * initialized by either parse or setName.
3.167 + * <li>If the field is not <code>null</code>, it's not empty.
3.168 + * <li>If the field is not <code>null</code>, it contains a valid
3.169 + * XML identifier.
3.170 + * </ul></dd></dl>
3.171 + */
3.172 + private String name;
3.173 +
3.174 +
3.175 + /**
3.176 + * The #PCDATA content of the object.
3.177 + *
3.178 + * <dl><dt><b>Invariants:</b></dt><dd>
3.179 + * <ul><li>The field is <code>null</code> iff the element is not a
3.180 + * #PCDATA element.
3.181 + * <li>The field can be any string, including the empty string.
3.182 + * </ul></dd></dl>
3.183 + */
3.184 + private String contents;
3.185 +
3.186 +
3.187 + /**
3.188 + * Conversion table for &...; entities. The keys are the entity names
3.189 + * without the & and ; delimiters.
3.190 + *
3.191 + * <dl><dt><b>Invariants:</b></dt><dd>
3.192 + * <ul><li>The field is never <code>null</code>.
3.193 + * <li>The field always contains the following associations:
3.194 + * "lt" => "<", "gt" => ">",
3.195 + * "quot" => "\"", "apos" => "'",
3.196 + * "amp" => "&"
3.197 + * <li>The keys are strings
3.198 + * <li>The values are char arrays
3.199 + * </ul></dd></dl>
3.200 + */
3.201 + private Hashtable entities;
3.202 +
3.203 +
3.204 + /**
3.205 + * The line number where the element starts.
3.206 + *
3.207 + * <dl><dt><b>Invariants:</b></dt><dd>
3.208 + * <ul><li><code>lineNr >= 0</code>
3.209 + * </ul></dd></dl>
3.210 + */
3.211 + private int lineNr;
3.212 +
3.213 +
3.214 + /**
3.215 + * <code>true</code> if the case of the element and attribute names
3.216 + * are case insensitive.
3.217 + */
3.218 + private boolean ignoreCase;
3.219 +
3.220 +
3.221 + /**
3.222 + * <code>true</code> if the leading and trailing whitespace of #PCDATA
3.223 + * sections have to be ignored.
3.224 + */
3.225 + private boolean ignoreWhitespace;
3.226 +
3.227 +
3.228 + /**
3.229 + * Character read too much.
3.230 + * This character provides push-back functionality to the input reader
3.231 + * without having to use a PushbackReader.
3.232 + * If there is no such character, this field is '\0'.
3.233 + */
3.234 + private char charReadTooMuch;
3.235 +
3.236 +
3.237 + /**
3.238 + * The reader provided by the caller of the parse method.
3.239 + *
3.240 + * <dl><dt><b>Invariants:</b></dt><dd>
3.241 + * <ul><li>The field is not <code>null</code> while the parse method
3.242 + * is running.
3.243 + * </ul></dd></dl>
3.244 + */
3.245 + private Reader reader;
3.246 +
3.247 +
3.248 + /**
3.249 + * The current line number in the source content.
3.250 + *
3.251 + * <dl><dt><b>Invariants:</b></dt><dd>
3.252 + * <ul><li>parserLineNr > 0 while the parse method is running.
3.253 + * </ul></dd></dl>
3.254 + */
3.255 + private int parserLineNr;
3.256 +
3.257 +
3.258 + /**
3.259 + * Creates and initializes a new XML element.
3.260 + * Calling the construction is equivalent to:
3.261 + * <ul><code>new XMLElement(new Hashtable(), false, true)
3.262 + * </code></ul>
3.263 + *
3.264 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.265 + * <ul><li>countChildren() => 0
3.266 + * <li>enumerateChildren() => empty enumeration
3.267 + * <li>enumeratePropertyNames() => empty enumeration
3.268 + * <li>getChildren() => empty vector
3.269 + * <li>getContent() => ""
3.270 + * <li>getLineNr() => 0
3.271 + * <li>getName() => null
3.272 + * </ul></dd></dl>
3.273 + *
3.274 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
3.275 + * XMLElement(Hashtable)
3.276 + * @see nanoxml.XMLElement#XMLElement(boolean)
3.277 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
3.278 + * XMLElement(Hashtable, boolean)
3.279 + */
3.280 + public XMLElement()
3.281 + {
3.282 + this(new Hashtable(), false, true, true);
3.283 + }
3.284 +
3.285 +
3.286 + /**
3.287 + * Creates and initializes a new XML element.
3.288 + * Calling the construction is equivalent to:
3.289 + * <ul><code>new XMLElement(entities, false, true)
3.290 + * </code></ul>
3.291 + *
3.292 + * @param entities
3.293 + * The entity conversion table.
3.294 + *
3.295 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.296 + * <ul><li><code>entities != null</code>
3.297 + * </ul></dd></dl>
3.298 + *
3.299 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.300 + * <ul><li>countChildren() => 0
3.301 + * <li>enumerateChildren() => empty enumeration
3.302 + * <li>enumeratePropertyNames() => empty enumeration
3.303 + * <li>getChildren() => empty vector
3.304 + * <li>getContent() => ""
3.305 + * <li>getLineNr() => 0
3.306 + * <li>getName() => null
3.307 + * </ul></dd></dl><dl>
3.308 + *
3.309 + * @see nanoxml.XMLElement#XMLElement()
3.310 + * @see nanoxml.XMLElement#XMLElement(boolean)
3.311 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
3.312 + * XMLElement(Hashtable, boolean)
3.313 + */
3.314 + public XMLElement(Hashtable entities)
3.315 + {
3.316 + this(entities, false, true, true);
3.317 + }
3.318 +
3.319 +
3.320 + /**
3.321 + * Creates and initializes a new XML element.
3.322 + * Calling the construction is equivalent to:
3.323 + * <ul><code>new XMLElement(new Hashtable(), skipLeadingWhitespace, true)
3.324 + * </code></ul>
3.325 + *
3.326 + * @param skipLeadingWhitespace
3.327 + * <code>true</code> if leading and trailing whitespace in PCDATA
3.328 + * content has to be removed.
3.329 + *
3.330 + * </dl><dl><dt><b>Postconditions:</b></dt><dd>
3.331 + * <ul><li>countChildren() => 0
3.332 + * <li>enumerateChildren() => empty enumeration
3.333 + * <li>enumeratePropertyNames() => empty enumeration
3.334 + * <li>getChildren() => empty vector
3.335 + * <li>getContent() => ""
3.336 + * <li>getLineNr() => 0
3.337 + * <li>getName() => null
3.338 + * </ul></dd></dl><dl>
3.339 + *
3.340 + * @see nanoxml.XMLElement#XMLElement()
3.341 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
3.342 + * XMLElement(Hashtable)
3.343 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
3.344 + * XMLElement(Hashtable, boolean)
3.345 + */
3.346 + public XMLElement(boolean skipLeadingWhitespace)
3.347 + {
3.348 + this(new Hashtable(), skipLeadingWhitespace, true, true);
3.349 + }
3.350 +
3.351 +
3.352 + /**
3.353 + * Creates and initializes a new XML element.
3.354 + * Calling the construction is equivalent to:
3.355 + * <ul><code>new XMLElement(entities, skipLeadingWhitespace, true)
3.356 + * </code></ul>
3.357 + *
3.358 + * @param entities
3.359 + * The entity conversion table.
3.360 + * @param skipLeadingWhitespace
3.361 + * <code>true</code> if leading and trailing whitespace in PCDATA
3.362 + * content has to be removed.
3.363 + *
3.364 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.365 + * <ul><li><code>entities != null</code>
3.366 + * </ul></dd></dl>
3.367 + *
3.368 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.369 + * <ul><li>countChildren() => 0
3.370 + * <li>enumerateChildren() => empty enumeration
3.371 + * <li>enumeratePropertyNames() => empty enumeration
3.372 + * <li>getChildren() => empty vector
3.373 + * <li>getContent() => ""
3.374 + * <li>getLineNr() => 0
3.375 + * <li>getName() => null
3.376 + * </ul></dd></dl><dl>
3.377 + *
3.378 + * @see nanoxml.XMLElement#XMLElement()
3.379 + * @see nanoxml.XMLElement#XMLElement(boolean)
3.380 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
3.381 + * XMLElement(Hashtable)
3.382 + */
3.383 + public XMLElement(Hashtable entities,
3.384 + boolean skipLeadingWhitespace)
3.385 + {
3.386 + this(entities, skipLeadingWhitespace, true, true);
3.387 + }
3.388 +
3.389 +
3.390 + /**
3.391 + * Creates and initializes a new XML element.
3.392 + *
3.393 + * @param entities
3.394 + * The entity conversion table.
3.395 + * @param skipLeadingWhitespace
3.396 + * <code>true</code> if leading and trailing whitespace in PCDATA
3.397 + * content has to be removed.
3.398 + * @param ignoreCase
3.399 + * <code>true</code> if the case of element and attribute names have
3.400 + * to be ignored.
3.401 + *
3.402 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.403 + * <ul><li><code>entities != null</code>
3.404 + * </ul></dd></dl>
3.405 + *
3.406 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.407 + * <ul><li>countChildren() => 0
3.408 + * <li>enumerateChildren() => empty enumeration
3.409 + * <li>enumeratePropertyNames() => empty enumeration
3.410 + * <li>getChildren() => empty vector
3.411 + * <li>getContent() => ""
3.412 + * <li>getLineNr() => 0
3.413 + * <li>getName() => null
3.414 + * </ul></dd></dl><dl>
3.415 + *
3.416 + * @see nanoxml.XMLElement#XMLElement()
3.417 + * @see nanoxml.XMLElement#XMLElement(boolean)
3.418 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
3.419 + * XMLElement(Hashtable)
3.420 + * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
3.421 + * XMLElement(Hashtable, boolean)
3.422 + */
3.423 + public XMLElement(Hashtable entities,
3.424 + boolean skipLeadingWhitespace,
3.425 + boolean ignoreCase)
3.426 + {
3.427 + this(entities, skipLeadingWhitespace, true, ignoreCase);
3.428 + }
3.429 +
3.430 +
3.431 + /**
3.432 + * Creates and initializes a new XML element.
3.433 + * <P>
3.434 + * This constructor should <I>only</I> be called from
3.435 + * {@link #createAnotherElement() createAnotherElement}
3.436 + * to create child elements.
3.437 + *
3.438 + * @param entities
3.439 + * The entity conversion table.
3.440 + * @param skipLeadingWhitespace
3.441 + * <code>true</code> if leading and trailing whitespace in PCDATA
3.442 + * content has to be removed.
3.443 + * @param fillBasicConversionTable
3.444 + * <code>true</code> if the basic entities need to be added to
3.445 + * the entity list.
3.446 + * @param ignoreCase
3.447 + * <code>true</code> if the case of element and attribute names have
3.448 + * to be ignored.
3.449 + *
3.450 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.451 + * <ul><li><code>entities != null</code>
3.452 + * <li>if <code>fillBasicConversionTable == false</code>
3.453 + * then <code>entities</code> contains at least the following
3.454 + * entries: <code>amp</code>, <code>lt</code>, <code>gt</code>,
3.455 + * <code>apos</code> and <code>quot</code>
3.456 + * </ul></dd></dl>
3.457 + *
3.458 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.459 + * <ul><li>countChildren() => 0
3.460 + * <li>enumerateChildren() => empty enumeration
3.461 + * <li>enumeratePropertyNames() => empty enumeration
3.462 + * <li>getChildren() => empty vector
3.463 + * <li>getContent() => ""
3.464 + * <li>getLineNr() => 0
3.465 + * <li>getName() => null
3.466 + * </ul></dd></dl><dl>
3.467 + *
3.468 + * @see nanoxml.XMLElement#createAnotherElement()
3.469 + */
3.470 + protected XMLElement(Hashtable entities,
3.471 + boolean skipLeadingWhitespace,
3.472 + boolean fillBasicConversionTable,
3.473 + boolean ignoreCase)
3.474 + {
3.475 + this.ignoreWhitespace = skipLeadingWhitespace;
3.476 + this.ignoreCase = ignoreCase;
3.477 + this.name = null;
3.478 + this.contents = "";
3.479 + this.attributes = new Hashtable();
3.480 + this.children = new Vector();
3.481 + this.entities = entities;
3.482 + this.lineNr = 0;
3.483 + Enumeration enumV = this.entities.keys();
3.484 + while (enumV.hasMoreElements()) {
3.485 + Object key = enumV.nextElement();
3.486 + Object value = this.entities.get(key);
3.487 + if (value instanceof String) {
3.488 + value = ((String) value).toCharArray();
3.489 + this.entities.put(key, value);
3.490 + }
3.491 + }
3.492 + if (fillBasicConversionTable) {
3.493 + this.entities.put("amp", new char[] { '&' });
3.494 + this.entities.put("quot", new char[] { '"' });
3.495 + this.entities.put("apos", new char[] { '\'' });
3.496 + this.entities.put("lt", new char[] { '<' });
3.497 + this.entities.put("gt", new char[] { '>' });
3.498 + }
3.499 + }
3.500 +
3.501 +
3.502 + /**
3.503 + * Adds a child element.
3.504 + *
3.505 + * @param child
3.506 + * The child element to add.
3.507 + *
3.508 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.509 + * <ul><li><code>child != null</code>
3.510 + * <li><code>child.getName() != null</code>
3.511 + * <li><code>child</code> does not have a parent element
3.512 + * </ul></dd></dl>
3.513 + *
3.514 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.515 + * <ul><li>countChildren() => old.countChildren() + 1
3.516 + * <li>enumerateChildren() => old.enumerateChildren() + child
3.517 + * <li>getChildren() => old.enumerateChildren() + child
3.518 + * </ul></dd></dl><dl>
3.519 + *
3.520 + * @see nanoxml.XMLElement#countChildren()
3.521 + * @see nanoxml.XMLElement#enumerateChildren()
3.522 + * @see nanoxml.XMLElement#getChildren()
3.523 + * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
3.524 + * removeChild(XMLElement)
3.525 + */
3.526 + public void addChild(XMLElement child)
3.527 + {
3.528 + this.children.addElement(child);
3.529 + }
3.530 +
3.531 +
3.532 + /**
3.533 + * Adds or modifies an attribute.
3.534 + *
3.535 + * @param name
3.536 + * The name of the attribute.
3.537 + * @param value
3.538 + * The value of the attribute.
3.539 + *
3.540 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.541 + * <ul><li><code>name != null</code>
3.542 + * <li><code>name</code> is a valid XML identifier
3.543 + * <li><code>value != null</code>
3.544 + * </ul></dd></dl>
3.545 + *
3.546 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.547 + * <ul><li>enumerateAttributeNames()
3.548 + * => old.enumerateAttributeNames() + name
3.549 + * <li>getAttribute(name) => value
3.550 + * </ul></dd></dl><dl>
3.551 + *
3.552 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.553 + * setDoubleAttribute(String, double)
3.554 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.555 + * setIntAttribute(String, int)
3.556 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.557 + * @see nanoxml.XMLElement#getAttribute(java.lang.String)
3.558 + * getAttribute(String)
3.559 + * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
3.560 + * getAttribute(String, Object)
3.561 + * @see nanoxml.XMLElement#getAttribute(java.lang.String,
3.562 + * java.util.Hashtable,
3.563 + * java.lang.String, boolean)
3.564 + * getAttribute(String, Hashtable, String, boolean)
3.565 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
3.566 + * getStringAttribute(String)
3.567 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.568 + * java.lang.String)
3.569 + * getStringAttribute(String, String)
3.570 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.571 + * java.util.Hashtable,
3.572 + * java.lang.String, boolean)
3.573 + * getStringAttribute(String, Hashtable, String, boolean)
3.574 + */
3.575 + public void setAttribute(String name,
3.576 + Object value)
3.577 + {
3.578 + if (this.ignoreCase) {
3.579 + name = name.toUpperCase();
3.580 + }
3.581 + this.attributes.put(name, value.toString());
3.582 + }
3.583 +
3.584 +
3.585 + /**
3.586 + * Adds or modifies an attribute.
3.587 + *
3.588 + * @param name
3.589 + * The name of the attribute.
3.590 + * @param value
3.591 + * The value of the attribute.
3.592 + *
3.593 + * @deprecated Use {@link #setAttribute(java.lang.String, java.lang.Object)
3.594 + * setAttribute} instead.
3.595 + */
3.596 + public void addProperty(String name,
3.597 + Object value)
3.598 + {
3.599 + this.setAttribute(name, value);
3.600 + }
3.601 +
3.602 +
3.603 + /**
3.604 + * Adds or modifies an attribute.
3.605 + *
3.606 + * @param name
3.607 + * The name of the attribute.
3.608 + * @param value
3.609 + * The value of the attribute.
3.610 + *
3.611 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.612 + * <ul><li><code>name != null</code>
3.613 + * <li><code>name</code> is a valid XML identifier
3.614 + * </ul></dd></dl>
3.615 + *
3.616 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.617 + * <ul><li>enumerateAttributeNames()
3.618 + * => old.enumerateAttributeNames() + name
3.619 + * <li>getIntAttribute(name) => value
3.620 + * </ul></dd></dl><dl>
3.621 + *
3.622 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.623 + * setDoubleAttribute(String, double)
3.624 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.625 + * setAttribute(String, Object)
3.626 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.627 + * removeAttribute(String)
3.628 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.629 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
3.630 + * getIntAttribute(String)
3.631 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
3.632 + * getIntAttribute(String, int)
3.633 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
3.634 + * java.util.Hashtable,
3.635 + * java.lang.String, boolean)
3.636 + * getIntAttribute(String, Hashtable, String, boolean)
3.637 + */
3.638 + public void setIntAttribute(String name,
3.639 + int value)
3.640 + {
3.641 + if (this.ignoreCase) {
3.642 + name = name.toUpperCase();
3.643 + }
3.644 + this.attributes.put(name, Integer.toString(value));
3.645 + }
3.646 +
3.647 +
3.648 + /**
3.649 + * Adds or modifies an attribute.
3.650 + *
3.651 + * @param name
3.652 + * The name of the attribute.
3.653 + * @param value
3.654 + * The value of the attribute.
3.655 + *
3.656 + * @deprecated Use {@link #setIntAttribute(java.lang.String, int)
3.657 + * setIntAttribute} instead.
3.658 + */
3.659 + public void addProperty(String key,
3.660 + int value)
3.661 + {
3.662 + this.setIntAttribute(key, value);
3.663 + }
3.664 +
3.665 +
3.666 + /**
3.667 + * Adds or modifies an attribute.
3.668 + *
3.669 + * @param name
3.670 + * The name of the attribute.
3.671 + * @param value
3.672 + * The value of the attribute.
3.673 + *
3.674 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.675 + * <ul><li><code>name != null</code>
3.676 + * <li><code>name</code> is a valid XML identifier
3.677 + * </ul></dd></dl>
3.678 + *
3.679 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.680 + * <ul><li>enumerateAttributeNames()
3.681 + * => old.enumerateAttributeNames() + name
3.682 + * <li>getDoubleAttribute(name) => value
3.683 + * </ul></dd></dl><dl>
3.684 + *
3.685 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.686 + * setIntAttribute(String, int)
3.687 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.688 + * setAttribute(String, Object)
3.689 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.690 + * removeAttribute(String)
3.691 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.692 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
3.693 + * getDoubleAttribute(String)
3.694 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
3.695 + * getDoubleAttribute(String, double)
3.696 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
3.697 + * java.util.Hashtable,
3.698 + * java.lang.String, boolean)
3.699 + * getDoubleAttribute(String, Hashtable, String, boolean)
3.700 + */
3.701 + public void setDoubleAttribute(String name,
3.702 + double value)
3.703 + {
3.704 + if (this.ignoreCase) {
3.705 + name = name.toUpperCase();
3.706 + }
3.707 + this.attributes.put(name, Double.toString(value));
3.708 + }
3.709 +
3.710 +
3.711 + /**
3.712 + * Adds or modifies an attribute.
3.713 + *
3.714 + * @param name
3.715 + * The name of the attribute.
3.716 + * @param value
3.717 + * The value of the attribute.
3.718 + *
3.719 + * @deprecated Use {@link #setDoubleAttribute(java.lang.String, double)
3.720 + * setDoubleAttribute} instead.
3.721 + */
3.722 + public void addProperty(String name,
3.723 + double value)
3.724 + {
3.725 + this.setDoubleAttribute(name, value);
3.726 + }
3.727 +
3.728 +
3.729 + /**
3.730 + * Returns the number of child elements of the element.
3.731 + *
3.732 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.733 + * <ul><li><code>result >= 0</code>
3.734 + * </ul></dd></dl>
3.735 + *
3.736 + * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
3.737 + * addChild(XMLElement)
3.738 + * @see nanoxml.XMLElement#enumerateChildren()
3.739 + * @see nanoxml.XMLElement#getChildren()
3.740 + * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
3.741 + * removeChild(XMLElement)
3.742 + */
3.743 + public int countChildren()
3.744 + {
3.745 + return this.children.size();
3.746 + }
3.747 +
3.748 +
3.749 + /**
3.750 + * Enumerates the attribute names.
3.751 + *
3.752 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.753 + * <ul><li><code>result != null</code>
3.754 + * </ul></dd></dl>
3.755 + *
3.756 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.757 + * setDoubleAttribute(String, double)
3.758 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.759 + * setIntAttribute(String, int)
3.760 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.761 + * setAttribute(String, Object)
3.762 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.763 + * removeAttribute(String)
3.764 + * @see nanoxml.XMLElement#getAttribute(java.lang.String)
3.765 + * getAttribute(String)
3.766 + * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
3.767 + * getAttribute(String, String)
3.768 + * @see nanoxml.XMLElement#getAttribute(java.lang.String,
3.769 + * java.util.Hashtable,
3.770 + * java.lang.String, boolean)
3.771 + * getAttribute(String, Hashtable, String, boolean)
3.772 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
3.773 + * getStringAttribute(String)
3.774 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.775 + * java.lang.String)
3.776 + * getStringAttribute(String, String)
3.777 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.778 + * java.util.Hashtable,
3.779 + * java.lang.String, boolean)
3.780 + * getStringAttribute(String, Hashtable, String, boolean)
3.781 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
3.782 + * getIntAttribute(String)
3.783 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
3.784 + * getIntAttribute(String, int)
3.785 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
3.786 + * java.util.Hashtable,
3.787 + * java.lang.String, boolean)
3.788 + * getIntAttribute(String, Hashtable, String, boolean)
3.789 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
3.790 + * getDoubleAttribute(String)
3.791 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
3.792 + * getDoubleAttribute(String, double)
3.793 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
3.794 + * java.util.Hashtable,
3.795 + * java.lang.String, boolean)
3.796 + * getDoubleAttribute(String, Hashtable, String, boolean)
3.797 + * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String,
3.798 + * java.lang.String,
3.799 + * java.lang.String, boolean)
3.800 + * getBooleanAttribute(String, String, String, boolean)
3.801 + */
3.802 + public Enumeration enumerateAttributeNames()
3.803 + {
3.804 + return this.attributes.keys();
3.805 + }
3.806 +
3.807 +
3.808 + /**
3.809 + * Enumerates the attribute names.
3.810 + *
3.811 + * @deprecated Use {@link #enumerateAttributeNames()
3.812 + * enumerateAttributeNames} instead.
3.813 + */
3.814 + public Enumeration enumeratePropertyNames()
3.815 + {
3.816 + return this.enumerateAttributeNames();
3.817 + }
3.818 +
3.819 +
3.820 + /**
3.821 + * Enumerates the child elements.
3.822 + *
3.823 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.824 + * <ul><li><code>result != null</code>
3.825 + * </ul></dd></dl>
3.826 + *
3.827 + * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
3.828 + * addChild(XMLElement)
3.829 + * @see nanoxml.XMLElement#countChildren()
3.830 + * @see nanoxml.XMLElement#getChildren()
3.831 + * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
3.832 + * removeChild(XMLElement)
3.833 + */
3.834 + public Enumeration enumerateChildren()
3.835 + {
3.836 + return this.children.elements();
3.837 + }
3.838 +
3.839 +
3.840 + /**
3.841 + * Returns the child elements as a Vector. It is safe to modify this
3.842 + * Vector.
3.843 + *
3.844 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.845 + * <ul><li><code>result != null</code>
3.846 + * </ul></dd></dl>
3.847 + *
3.848 + * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
3.849 + * addChild(XMLElement)
3.850 + * @see nanoxml.XMLElement#countChildren()
3.851 + * @see nanoxml.XMLElement#enumerateChildren()
3.852 + * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
3.853 + * removeChild(XMLElement)
3.854 + */
3.855 + public Vector getChildren()
3.856 + {
3.857 + try {
3.858 + return (Vector) this.children.clone();
3.859 + } catch (Exception e) {
3.860 + // this never happens, however, some Java compilers are so
3.861 + // braindead that they require this exception clause
3.862 + return null;
3.863 + }
3.864 + }
3.865 +
3.866 +
3.867 + /**
3.868 + * Returns the PCDATA content of the object. If there is no such content,
3.869 + * <CODE>null</CODE> is returned.
3.870 + *
3.871 + * @deprecated Use {@link #getContent() getContent} instead.
3.872 + */
3.873 + public String getContents()
3.874 + {
3.875 + return this.getContent();
3.876 + }
3.877 +
3.878 +
3.879 + /**
3.880 + * Returns the PCDATA content of the object. If there is no such content,
3.881 + * <CODE>null</CODE> is returned.
3.882 + *
3.883 + * @see nanoxml.XMLElement#setContent(java.lang.String)
3.884 + * setContent(String)
3.885 + */
3.886 + public String getContent()
3.887 + {
3.888 + return this.contents;
3.889 + }
3.890 +
3.891 +
3.892 + /**
3.893 + * Returns the line nr in the source data on which the element is found.
3.894 + * This method returns <code>0</code> there is no associated source data.
3.895 + *
3.896 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.897 + * <ul><li><code>result >= 0</code>
3.898 + * </ul></dd></dl>
3.899 + */
3.900 + public int getLineNr()
3.901 + {
3.902 + return this.lineNr;
3.903 + }
3.904 +
3.905 +
3.906 + /**
3.907 + * Returns an attribute of the element.
3.908 + * If the attribute doesn't exist, <code>null</code> is returned.
3.909 + *
3.910 + * @param name The name of the attribute.
3.911 + *
3.912 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.913 + * <ul><li><code>name != null</code>
3.914 + * <li><code>name</code> is a valid XML identifier
3.915 + * </ul></dd></dl><dl>
3.916 + *
3.917 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.918 + * setAttribute(String, Object)
3.919 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.920 + * removeAttribute(String)
3.921 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.922 + * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
3.923 + * getAttribute(String, Object)
3.924 + * @see nanoxml.XMLElement#getAttribute(java.lang.String,
3.925 + * java.util.Hashtable,
3.926 + * java.lang.String, boolean)
3.927 + * getAttribute(String, Hashtable, String, boolean)
3.928 + */
3.929 + public Object getAttribute(String name)
3.930 + {
3.931 + return this.getAttribute(name, null);
3.932 + }
3.933 +
3.934 +
3.935 + /**
3.936 + * Returns an attribute of the element.
3.937 + * If the attribute doesn't exist, <code>defaultValue</code> is returned.
3.938 + *
3.939 + * @param name The name of the attribute.
3.940 + * @param defaultValue Key to use if the attribute is missing.
3.941 + *
3.942 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.943 + * <ul><li><code>name != null</code>
3.944 + * <li><code>name</code> is a valid XML identifier
3.945 + * </ul></dd></dl><dl>
3.946 + *
3.947 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.948 + * setAttribute(String, Object)
3.949 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.950 + * removeAttribute(String)
3.951 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.952 + * @see nanoxml.XMLElement#getAttribute(java.lang.String)
3.953 + * getAttribute(String)
3.954 + * @see nanoxml.XMLElement#getAttribute(java.lang.String,
3.955 + * java.util.Hashtable,
3.956 + * java.lang.String, boolean)
3.957 + * getAttribute(String, Hashtable, String, boolean)
3.958 + */
3.959 + public Object getAttribute(String name,
3.960 + Object defaultValue)
3.961 + {
3.962 + if (this.ignoreCase) {
3.963 + name = name.toUpperCase();
3.964 + }
3.965 + Object value = this.attributes.get(name);
3.966 + if (value == null) {
3.967 + value = defaultValue;
3.968 + }
3.969 + return value;
3.970 + }
3.971 +
3.972 +
3.973 + /**
3.974 + * Returns an attribute by looking up a key in a hashtable.
3.975 + * If the attribute doesn't exist, the value corresponding to defaultKey
3.976 + * is returned.
3.977 + * <P>
3.978 + * As an example, if valueSet contains the mapping <code>"one" =>
3.979 + * "1"</code>
3.980 + * and the element contains the attribute <code>attr="one"</code>, then
3.981 + * <code>getAttribute("attr", mapping, defaultKey, false)</code> returns
3.982 + * <code>"1"</code>.
3.983 + *
3.984 + * @param name
3.985 + * The name of the attribute.
3.986 + * @param valueSet
3.987 + * Hashtable mapping keys to values.
3.988 + * @param defaultKey
3.989 + * Key to use if the attribute is missing.
3.990 + * @param allowLiterals
3.991 + * <code>true</code> if literals are valid.
3.992 + *
3.993 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.994 + * <ul><li><code>name != null</code>
3.995 + * <li><code>name</code> is a valid XML identifier
3.996 + * <li><code>valueSet</code> != null
3.997 + * <li>the keys of <code>valueSet</code> are strings
3.998 + * </ul></dd></dl><dl>
3.999 + *
3.1000 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.1001 + * setAttribute(String, Object)
3.1002 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.1003 + * removeAttribute(String)
3.1004 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1005 + * @see nanoxml.XMLElement#getAttribute(java.lang.String)
3.1006 + * getAttribute(String)
3.1007 + * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
3.1008 + * getAttribute(String, Object)
3.1009 + */
3.1010 + public Object getAttribute(String name,
3.1011 + Hashtable valueSet,
3.1012 + String defaultKey,
3.1013 + boolean allowLiterals)
3.1014 + {
3.1015 + if (this.ignoreCase) {
3.1016 + name = name.toUpperCase();
3.1017 + }
3.1018 + Object key = this.attributes.get(name);
3.1019 + Object result;
3.1020 + if (key == null) {
3.1021 + key = defaultKey;
3.1022 + }
3.1023 + result = valueSet.get(key);
3.1024 + if (result == null) {
3.1025 + if (allowLiterals) {
3.1026 + result = key;
3.1027 + } else {
3.1028 + throw this.invalidValue(name, (String) key);
3.1029 + }
3.1030 + }
3.1031 + return result;
3.1032 + }
3.1033 +
3.1034 +
3.1035 + /**
3.1036 + * Returns an attribute of the element.
3.1037 + * If the attribute doesn't exist, <code>null</code> is returned.
3.1038 + *
3.1039 + * @param name The name of the attribute.
3.1040 + *
3.1041 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1042 + * <ul><li><code>name != null</code>
3.1043 + * <li><code>name</code> is a valid XML identifier
3.1044 + * </ul></dd></dl><dl>
3.1045 + *
3.1046 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.1047 + * setAttribute(String, Object)
3.1048 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.1049 + * removeAttribute(String)
3.1050 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1051 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.1052 + * java.lang.String)
3.1053 + * getStringAttribute(String, String)
3.1054 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.1055 + * java.util.Hashtable,
3.1056 + * java.lang.String, boolean)
3.1057 + * getStringAttribute(String, Hashtable, String, boolean)
3.1058 + */
3.1059 + public String getStringAttribute(String name)
3.1060 + {
3.1061 + return this.getStringAttribute(name, null);
3.1062 + }
3.1063 +
3.1064 +
3.1065 + /**
3.1066 + * Returns an attribute of the element.
3.1067 + * If the attribute doesn't exist, <code>defaultValue</code> is returned.
3.1068 + *
3.1069 + * @param name The name of the attribute.
3.1070 + * @param defaultValue Key to use if the attribute is missing.
3.1071 + *
3.1072 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1073 + * <ul><li><code>name != null</code>
3.1074 + * <li><code>name</code> is a valid XML identifier
3.1075 + * </ul></dd></dl><dl>
3.1076 + *
3.1077 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.1078 + * setAttribute(String, Object)
3.1079 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.1080 + * removeAttribute(String)
3.1081 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1082 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
3.1083 + * getStringAttribute(String)
3.1084 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.1085 + * java.util.Hashtable,
3.1086 + * java.lang.String, boolean)
3.1087 + * getStringAttribute(String, Hashtable, String, boolean)
3.1088 + */
3.1089 + public String getStringAttribute(String name,
3.1090 + String defaultValue)
3.1091 + {
3.1092 + return (String) this.getAttribute(name, defaultValue);
3.1093 + }
3.1094 +
3.1095 +
3.1096 + /**
3.1097 + * Returns an attribute by looking up a key in a hashtable.
3.1098 + * If the attribute doesn't exist, the value corresponding to defaultKey
3.1099 + * is returned.
3.1100 + * <P>
3.1101 + * As an example, if valueSet contains the mapping <code>"one" =>
3.1102 + * "1"</code>
3.1103 + * and the element contains the attribute <code>attr="one"</code>, then
3.1104 + * <code>getAttribute("attr", mapping, defaultKey, false)</code> returns
3.1105 + * <code>"1"</code>.
3.1106 + *
3.1107 + * @param name
3.1108 + * The name of the attribute.
3.1109 + * @param valueSet
3.1110 + * Hashtable mapping keys to values.
3.1111 + * @param defaultKey
3.1112 + * Key to use if the attribute is missing.
3.1113 + * @param allowLiterals
3.1114 + * <code>true</code> if literals are valid.
3.1115 + *
3.1116 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1117 + * <ul><li><code>name != null</code>
3.1118 + * <li><code>name</code> is a valid XML identifier
3.1119 + * <li><code>valueSet</code> != null
3.1120 + * <li>the keys of <code>valueSet</code> are strings
3.1121 + * <li>the values of <code>valueSet</code> are strings
3.1122 + * </ul></dd></dl><dl>
3.1123 + *
3.1124 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.1125 + * setAttribute(String, Object)
3.1126 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.1127 + * removeAttribute(String)
3.1128 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1129 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
3.1130 + * getStringAttribute(String)
3.1131 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.1132 + * java.lang.String)
3.1133 + * getStringAttribute(String, String)
3.1134 + */
3.1135 + public String getStringAttribute(String name,
3.1136 + Hashtable valueSet,
3.1137 + String defaultKey,
3.1138 + boolean allowLiterals)
3.1139 + {
3.1140 + return (String) this.getAttribute(name, valueSet, defaultKey,
3.1141 + allowLiterals);
3.1142 + }
3.1143 +
3.1144 +
3.1145 + /**
3.1146 + * Returns an attribute of the element.
3.1147 + * If the attribute doesn't exist, <code>0</code> is returned.
3.1148 + *
3.1149 + * @param name The name of the attribute.
3.1150 + *
3.1151 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1152 + * <ul><li><code>name != null</code>
3.1153 + * <li><code>name</code> is a valid XML identifier
3.1154 + * </ul></dd></dl><dl>
3.1155 + *
3.1156 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.1157 + * setIntAttribute(String, int)
3.1158 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1159 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
3.1160 + * getIntAttribute(String, int)
3.1161 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
3.1162 + * java.util.Hashtable,
3.1163 + * java.lang.String, boolean)
3.1164 + * getIntAttribute(String, Hashtable, String, boolean)
3.1165 + */
3.1166 + public int getIntAttribute(String name)
3.1167 + {
3.1168 + return this.getIntAttribute(name, 0);
3.1169 + }
3.1170 +
3.1171 +
3.1172 + /**
3.1173 + * Returns an attribute of the element.
3.1174 + * If the attribute doesn't exist, <code>defaultValue</code> is returned.
3.1175 + *
3.1176 + * @param name The name of the attribute.
3.1177 + * @param defaultValue Key to use if the attribute is missing.
3.1178 + *
3.1179 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1180 + * <ul><li><code>name != null</code>
3.1181 + * <li><code>name</code> is a valid XML identifier
3.1182 + * </ul></dd></dl><dl>
3.1183 + *
3.1184 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.1185 + * setIntAttribute(String, int)
3.1186 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1187 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
3.1188 + * getIntAttribute(String)
3.1189 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
3.1190 + * java.util.Hashtable,
3.1191 + * java.lang.String, boolean)
3.1192 + * getIntAttribute(String, Hashtable, String, boolean)
3.1193 + */
3.1194 + public int getIntAttribute(String name,
3.1195 + int defaultValue)
3.1196 + {
3.1197 + if (this.ignoreCase) {
3.1198 + name = name.toUpperCase();
3.1199 + }
3.1200 + String value = (String) this.attributes.get(name);
3.1201 + if (value == null) {
3.1202 + return defaultValue;
3.1203 + } else {
3.1204 + try {
3.1205 + return Integer.parseInt(value);
3.1206 + } catch (NumberFormatException e) {
3.1207 + throw this.invalidValue(name, value);
3.1208 + }
3.1209 + }
3.1210 + }
3.1211 +
3.1212 +
3.1213 + /**
3.1214 + * Returns an attribute by looking up a key in a hashtable.
3.1215 + * If the attribute doesn't exist, the value corresponding to defaultKey
3.1216 + * is returned.
3.1217 + * <P>
3.1218 + * As an example, if valueSet contains the mapping <code>"one" => 1</code>
3.1219 + * and the element contains the attribute <code>attr="one"</code>, then
3.1220 + * <code>getIntAttribute("attr", mapping, defaultKey, false)</code> returns
3.1221 + * <code>1</code>.
3.1222 + *
3.1223 + * @param name
3.1224 + * The name of the attribute.
3.1225 + * @param valueSet
3.1226 + * Hashtable mapping keys to values.
3.1227 + * @param defaultKey
3.1228 + * Key to use if the attribute is missing.
3.1229 + * @param allowLiteralNumbers
3.1230 + * <code>true</code> if literal numbers are valid.
3.1231 + *
3.1232 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1233 + * <ul><li><code>name != null</code>
3.1234 + * <li><code>name</code> is a valid XML identifier
3.1235 + * <li><code>valueSet</code> != null
3.1236 + * <li>the keys of <code>valueSet</code> are strings
3.1237 + * <li>the values of <code>valueSet</code> are Integer objects
3.1238 + * <li><code>defaultKey</code> is either <code>null</code>, a
3.1239 + * key in <code>valueSet</code> or an integer.
3.1240 + * </ul></dd></dl><dl>
3.1241 + *
3.1242 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.1243 + * setIntAttribute(String, int)
3.1244 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1245 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
3.1246 + * getIntAttribute(String)
3.1247 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
3.1248 + * getIntAttribute(String, int)
3.1249 + */
3.1250 + public int getIntAttribute(String name,
3.1251 + Hashtable valueSet,
3.1252 + String defaultKey,
3.1253 + boolean allowLiteralNumbers)
3.1254 + {
3.1255 + if (this.ignoreCase) {
3.1256 + name = name.toUpperCase();
3.1257 + }
3.1258 + Object key = this.attributes.get(name);
3.1259 + Integer result;
3.1260 + if (key == null) {
3.1261 + key = defaultKey;
3.1262 + }
3.1263 + try {
3.1264 + result = (Integer) valueSet.get(key);
3.1265 + } catch (ClassCastException e) {
3.1266 + throw this.invalidValueSet(name);
3.1267 + }
3.1268 + if (result == null) {
3.1269 + if (! allowLiteralNumbers) {
3.1270 + throw this.invalidValue(name, (String) key);
3.1271 + }
3.1272 + try {
3.1273 + result = Integer.valueOf((String) key);
3.1274 + } catch (NumberFormatException e) {
3.1275 + throw this.invalidValue(name, (String) key);
3.1276 + }
3.1277 + }
3.1278 + return result.intValue();
3.1279 + }
3.1280 +
3.1281 +
3.1282 + /**
3.1283 + * Returns an attribute of the element.
3.1284 + * If the attribute doesn't exist, <code>0.0</code> is returned.
3.1285 + *
3.1286 + * @param name The name of the attribute.
3.1287 + *
3.1288 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1289 + * <ul><li><code>name != null</code>
3.1290 + * <li><code>name</code> is a valid XML identifier
3.1291 + * </ul></dd></dl><dl>
3.1292 + *
3.1293 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.1294 + * setDoubleAttribute(String, double)
3.1295 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1296 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
3.1297 + * getDoubleAttribute(String, double)
3.1298 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
3.1299 + * java.util.Hashtable,
3.1300 + * java.lang.String, boolean)
3.1301 + * getDoubleAttribute(String, Hashtable, String, boolean)
3.1302 + */
3.1303 + public double getDoubleAttribute(String name)
3.1304 + {
3.1305 + return this.getDoubleAttribute(name, 0.);
3.1306 + }
3.1307 +
3.1308 +
3.1309 + /**
3.1310 + * Returns an attribute of the element.
3.1311 + * If the attribute doesn't exist, <code>defaultValue</code> is returned.
3.1312 + *
3.1313 + * @param name The name of the attribute.
3.1314 + * @param defaultValue Key to use if the attribute is missing.
3.1315 + *
3.1316 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1317 + * <ul><li><code>name != null</code>
3.1318 + * <li><code>name</code> is a valid XML identifier
3.1319 + * </ul></dd></dl><dl>
3.1320 + *
3.1321 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.1322 + * setDoubleAttribute(String, double)
3.1323 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1324 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
3.1325 + * getDoubleAttribute(String)
3.1326 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
3.1327 + * java.util.Hashtable,
3.1328 + * java.lang.String, boolean)
3.1329 + * getDoubleAttribute(String, Hashtable, String, boolean)
3.1330 + */
3.1331 + public double getDoubleAttribute(String name,
3.1332 + double defaultValue)
3.1333 + {
3.1334 + if (this.ignoreCase) {
3.1335 + name = name.toUpperCase();
3.1336 + }
3.1337 + String value = (String) this.attributes.get(name);
3.1338 + if (value == null) {
3.1339 + return defaultValue;
3.1340 + } else {
3.1341 + try {
3.1342 + return Double.valueOf(value).doubleValue();
3.1343 + } catch (NumberFormatException e) {
3.1344 + throw this.invalidValue(name, value);
3.1345 + }
3.1346 + }
3.1347 + }
3.1348 +
3.1349 +
3.1350 + /**
3.1351 + * Returns an attribute by looking up a key in a hashtable.
3.1352 + * If the attribute doesn't exist, the value corresponding to defaultKey
3.1353 + * is returned.
3.1354 + * <P>
3.1355 + * As an example, if valueSet contains the mapping <code>"one" =>
3.1356 + * 1.0</code>
3.1357 + * and the element contains the attribute <code>attr="one"</code>, then
3.1358 + * <code>getDoubleAttribute("attr", mapping, defaultKey, false)</code>
3.1359 + * returns <code>1.0</code>.
3.1360 + *
3.1361 + * @param name
3.1362 + * The name of the attribute.
3.1363 + * @param valueSet
3.1364 + * Hashtable mapping keys to values.
3.1365 + * @param defaultKey
3.1366 + * Key to use if the attribute is missing.
3.1367 + * @param allowLiteralNumbers
3.1368 + * <code>true</code> if literal numbers are valid.
3.1369 + *
3.1370 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1371 + * <ul><li><code>name != null</code>
3.1372 + * <li><code>name</code> is a valid XML identifier
3.1373 + * <li><code>valueSet != null</code>
3.1374 + * <li>the keys of <code>valueSet</code> are strings
3.1375 + * <li>the values of <code>valueSet</code> are Double objects
3.1376 + * <li><code>defaultKey</code> is either <code>null</code>, a
3.1377 + * key in <code>valueSet</code> or a double.
3.1378 + * </ul></dd></dl><dl>
3.1379 + *
3.1380 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.1381 + * setDoubleAttribute(String, double)
3.1382 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1383 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
3.1384 + * getDoubleAttribute(String)
3.1385 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
3.1386 + * getDoubleAttribute(String, double)
3.1387 + */
3.1388 + public double getDoubleAttribute(String name,
3.1389 + Hashtable valueSet,
3.1390 + String defaultKey,
3.1391 + boolean allowLiteralNumbers)
3.1392 + {
3.1393 + if (this.ignoreCase) {
3.1394 + name = name.toUpperCase();
3.1395 + }
3.1396 + Object key = this.attributes.get(name);
3.1397 + Double result;
3.1398 + if (key == null) {
3.1399 + key = defaultKey;
3.1400 + }
3.1401 + try {
3.1402 + result = (Double) valueSet.get(key);
3.1403 + } catch (ClassCastException e) {
3.1404 + throw this.invalidValueSet(name);
3.1405 + }
3.1406 + if (result == null) {
3.1407 + if (! allowLiteralNumbers) {
3.1408 + throw this.invalidValue(name, (String) key);
3.1409 + }
3.1410 + try {
3.1411 + result = Double.valueOf((String) key);
3.1412 + } catch (NumberFormatException e) {
3.1413 + throw this.invalidValue(name, (String) key);
3.1414 + }
3.1415 + }
3.1416 + return result.doubleValue();
3.1417 + }
3.1418 +
3.1419 +
3.1420 + /**
3.1421 + * Returns an attribute of the element.
3.1422 + * If the attribute doesn't exist, <code>defaultValue</code> is returned.
3.1423 + * If the value of the attribute is equal to <code>trueValue</code>,
3.1424 + * <code>true</code> is returned.
3.1425 + * If the value of the attribute is equal to <code>falseValue</code>,
3.1426 + * <code>false</code> is returned.
3.1427 + * If the value doesn't match <code>trueValue</code> or
3.1428 + * <code>falseValue</code>, an exception is thrown.
3.1429 + *
3.1430 + * @param name The name of the attribute.
3.1431 + * @param trueValue The value associated with <code>true</code>.
3.1432 + * @param falseValue The value associated with <code>true</code>.
3.1433 + * @param defaultValue Value to use if the attribute is missing.
3.1434 + *
3.1435 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1436 + * <ul><li><code>name != null</code>
3.1437 + * <li><code>name</code> is a valid XML identifier
3.1438 + * <li><code>trueValue</code> and <code>falseValue</code>
3.1439 + * are different strings.
3.1440 + * </ul></dd></dl><dl>
3.1441 + *
3.1442 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.1443 + * setAttribute(String, Object)
3.1444 + * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
3.1445 + * removeAttribute(String)
3.1446 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1447 + */
3.1448 + public boolean getBooleanAttribute(String name,
3.1449 + String trueValue,
3.1450 + String falseValue,
3.1451 + boolean defaultValue)
3.1452 + {
3.1453 + if (this.ignoreCase) {
3.1454 + name = name.toUpperCase();
3.1455 + }
3.1456 + Object value = this.attributes.get(name);
3.1457 + if (value == null) {
3.1458 + return defaultValue;
3.1459 + } else if (value.equals(trueValue)) {
3.1460 + return true;
3.1461 + } else if (value.equals(falseValue)) {
3.1462 + return false;
3.1463 + } else {
3.1464 + throw this.invalidValue(name, (String) value);
3.1465 + }
3.1466 + }
3.1467 +
3.1468 +
3.1469 + /**
3.1470 + * Returns an attribute by looking up a key in a hashtable.
3.1471 + *
3.1472 + * @deprecated Use {@link #getIntAttribute(java.lang.String,
3.1473 + * java.util.Hashtable, java.lang.String, boolean)
3.1474 + * getIntAttribute} instead.
3.1475 + */
3.1476 + public int getIntProperty(String name,
3.1477 + Hashtable valueSet,
3.1478 + String defaultKey)
3.1479 + {
3.1480 + return this.getIntAttribute(name, valueSet, defaultKey, false);
3.1481 + }
3.1482 +
3.1483 +
3.1484 + /**
3.1485 + * Returns an attribute.
3.1486 + *
3.1487 + * @deprecated Use {@link #getStringAttribute(java.lang.String)
3.1488 + * getStringAttribute} instead.
3.1489 + */
3.1490 + public String getProperty(String name)
3.1491 + {
3.1492 + return this.getStringAttribute(name);
3.1493 + }
3.1494 +
3.1495 +
3.1496 + /**
3.1497 + * Returns an attribute.
3.1498 + *
3.1499 + * @deprecated Use {@link #getStringAttribute(java.lang.String,
3.1500 + * java.lang.String) getStringAttribute} instead.
3.1501 + */
3.1502 + public String getProperty(String name,
3.1503 + String defaultValue)
3.1504 + {
3.1505 + return this.getStringAttribute(name, defaultValue);
3.1506 + }
3.1507 +
3.1508 +
3.1509 + /**
3.1510 + * Returns an attribute.
3.1511 + *
3.1512 + * @deprecated Use {@link #getIntAttribute(java.lang.String, int)
3.1513 + * getIntAttribute} instead.
3.1514 + */
3.1515 + public int getProperty(String name,
3.1516 + int defaultValue)
3.1517 + {
3.1518 + return this.getIntAttribute(name, defaultValue);
3.1519 + }
3.1520 +
3.1521 +
3.1522 + /**
3.1523 + * Returns an attribute.
3.1524 + *
3.1525 + * @deprecated Use {@link #getDoubleAttribute(java.lang.String, double)
3.1526 + * getDoubleAttribute} instead.
3.1527 + */
3.1528 + public double getProperty(String name,
3.1529 + double defaultValue)
3.1530 + {
3.1531 + return this.getDoubleAttribute(name, defaultValue);
3.1532 + }
3.1533 +
3.1534 +
3.1535 + /**
3.1536 + * Returns an attribute.
3.1537 + *
3.1538 + * @deprecated Use {@link #getBooleanAttribute(java.lang.String,
3.1539 + * java.lang.String, java.lang.String, boolean)
3.1540 + * getBooleanAttribute} instead.
3.1541 + */
3.1542 + public boolean getProperty(String key,
3.1543 + String trueValue,
3.1544 + String falseValue,
3.1545 + boolean defaultValue)
3.1546 + {
3.1547 + return this.getBooleanAttribute(key, trueValue, falseValue,
3.1548 + defaultValue);
3.1549 + }
3.1550 +
3.1551 +
3.1552 + /**
3.1553 + * Returns an attribute by looking up a key in a hashtable.
3.1554 + *
3.1555 + * @deprecated Use {@link #getAttribute(java.lang.String,
3.1556 + * java.util.Hashtable, java.lang.String, boolean)
3.1557 + * getAttribute} instead.
3.1558 + */
3.1559 + public Object getProperty(String name,
3.1560 + Hashtable valueSet,
3.1561 + String defaultKey)
3.1562 + {
3.1563 + return this.getAttribute(name, valueSet, defaultKey, false);
3.1564 + }
3.1565 +
3.1566 +
3.1567 + /**
3.1568 + * Returns an attribute by looking up a key in a hashtable.
3.1569 + *
3.1570 + * @deprecated Use {@link #getStringAttribute(java.lang.String,
3.1571 + * java.util.Hashtable, java.lang.String, boolean)
3.1572 + * getStringAttribute} instead.
3.1573 + */
3.1574 + public String getStringProperty(String name,
3.1575 + Hashtable valueSet,
3.1576 + String defaultKey)
3.1577 + {
3.1578 + return this.getStringAttribute(name, valueSet, defaultKey, false);
3.1579 + }
3.1580 +
3.1581 +
3.1582 + /**
3.1583 + * Returns an attribute by looking up a key in a hashtable.
3.1584 + *
3.1585 + * @deprecated Use {@link #getIntAttribute(java.lang.String,
3.1586 + * java.util.Hashtable, java.lang.String, boolean)
3.1587 + * getIntAttribute} instead.
3.1588 + */
3.1589 + public int getSpecialIntProperty(String name,
3.1590 + Hashtable valueSet,
3.1591 + String defaultKey)
3.1592 + {
3.1593 + return this.getIntAttribute(name, valueSet, defaultKey, true);
3.1594 + }
3.1595 +
3.1596 +
3.1597 + /**
3.1598 + * Returns an attribute by looking up a key in a hashtable.
3.1599 + *
3.1600 + * @deprecated Use {@link #getDoubleAttribute(java.lang.String,
3.1601 + * java.util.Hashtable, java.lang.String, boolean)
3.1602 + * getDoubleAttribute} instead.
3.1603 + */
3.1604 + public double getSpecialDoubleProperty(String name,
3.1605 + Hashtable valueSet,
3.1606 + String defaultKey)
3.1607 + {
3.1608 + return this.getDoubleAttribute(name, valueSet, defaultKey, true);
3.1609 + }
3.1610 +
3.1611 +
3.1612 + /**
3.1613 + * Returns the name of the element.
3.1614 + *
3.1615 + * @see nanoxml.XMLElement#setName(java.lang.String) setName(String)
3.1616 + */
3.1617 + public String getName()
3.1618 + {
3.1619 + return this.name;
3.1620 + }
3.1621 +
3.1622 +
3.1623 + /**
3.1624 + * Returns the name of the element.
3.1625 + *
3.1626 + * @deprecated Use {@link #getName() getName} instead.
3.1627 + */
3.1628 + public String getTagName()
3.1629 + {
3.1630 + return this.getName();
3.1631 + }
3.1632 +
3.1633 +
3.1634 + /**
3.1635 + * Reads one XML element from a java.io.Reader and parses it.
3.1636 + *
3.1637 + * @param reader
3.1638 + * The reader from which to retrieve the XML data.
3.1639 + *
3.1640 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1641 + * <ul><li><code>reader != null</code>
3.1642 + * <li><code>reader</code> is not closed
3.1643 + * </ul></dd></dl>
3.1644 + *
3.1645 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1646 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1647 + * parsed from the reader
3.1648 + * <li>the reader points to the first character following the last
3.1649 + * '>' character of the XML element
3.1650 + * </ul></dd></dl><dl>
3.1651 + *
3.1652 + * @throws java.io.IOException
3.1653 + * If an error occured while reading the input.
3.1654 + * @throws nanoxml.XMLParseException
3.1655 + * If an error occured while parsing the read data.
3.1656 + */
3.1657 + public void parseFromReader(Reader reader)
3.1658 + throws IOException, XMLParseException
3.1659 + {
3.1660 + this.parseFromReader(reader, /*startingLineNr*/ 1);
3.1661 + }
3.1662 +
3.1663 +
3.1664 + /**
3.1665 + * Reads one XML element from a java.io.Reader and parses it.
3.1666 + *
3.1667 + * @param reader
3.1668 + * The reader from which to retrieve the XML data.
3.1669 + * @param startingLineNr
3.1670 + * The line number of the first line in the data.
3.1671 + *
3.1672 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1673 + * <ul><li><code>reader != null</code>
3.1674 + * <li><code>reader</code> is not closed
3.1675 + * </ul></dd></dl>
3.1676 + *
3.1677 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1678 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1679 + * parsed from the reader
3.1680 + * <li>the reader points to the first character following the last
3.1681 + * '>' character of the XML element
3.1682 + * </ul></dd></dl><dl>
3.1683 + *
3.1684 + * @throws java.io.IOException
3.1685 + * If an error occured while reading the input.
3.1686 + * @throws nanoxml.XMLParseException
3.1687 + * If an error occured while parsing the read data.
3.1688 + */
3.1689 + public void parseFromReader(Reader reader,
3.1690 + int startingLineNr)
3.1691 + throws IOException, XMLParseException
3.1692 + {
3.1693 + this.name = null;
3.1694 + this.contents = "";
3.1695 + this.attributes = new Hashtable();
3.1696 + this.children = new Vector();
3.1697 + this.charReadTooMuch = '\0';
3.1698 + this.reader = reader;
3.1699 + this.parserLineNr = startingLineNr;
3.1700 +
3.1701 + for (;;) {
3.1702 + char ch = this.scanWhitespace();
3.1703 +
3.1704 + if (ch != '<') {
3.1705 + throw this.expectedInput("<");
3.1706 + }
3.1707 +
3.1708 + ch = this.readChar();
3.1709 +
3.1710 + if ((ch == '!') || (ch == '?')) {
3.1711 + this.skipSpecialTag(0);
3.1712 + } else {
3.1713 + this.unreadChar(ch);
3.1714 + this.scanElement(this);
3.1715 + return;
3.1716 + }
3.1717 + }
3.1718 + }
3.1719 +
3.1720 +
3.1721 + /**
3.1722 + * Reads one XML element from a String and parses it.
3.1723 + *
3.1724 + * @param reader
3.1725 + * The reader from which to retrieve the XML data.
3.1726 + *
3.1727 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1728 + * <ul><li><code>string != null</code>
3.1729 + * <li><code>string.length() > 0</code>
3.1730 + * </ul></dd></dl>
3.1731 + *
3.1732 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1733 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1734 + * parsed from the reader
3.1735 + * </ul></dd></dl><dl>
3.1736 + *
3.1737 + * @throws nanoxml.XMLParseException
3.1738 + * If an error occured while parsing the string.
3.1739 + */
3.1740 + public void parseString(String string)
3.1741 + throws XMLParseException
3.1742 + {
3.1743 + try {
3.1744 + this.parseFromReader(new StringReader(string),
3.1745 + /*startingLineNr*/ 1);
3.1746 + } catch (IOException e) {
3.1747 + // Java exception handling suxx
3.1748 + }
3.1749 + }
3.1750 +
3.1751 +
3.1752 + /**
3.1753 + * Reads one XML element from a String and parses it.
3.1754 + *
3.1755 + * @param reader
3.1756 + * The reader from which to retrieve the XML data.
3.1757 + * @param offset
3.1758 + * The first character in <code>string</code> to scan.
3.1759 + *
3.1760 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1761 + * <ul><li><code>string != null</code>
3.1762 + * <li><code>offset < string.length()</code>
3.1763 + * <li><code>offset >= 0</code>
3.1764 + * </ul></dd></dl>
3.1765 + *
3.1766 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1767 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1768 + * parsed from the reader
3.1769 + * </ul></dd></dl><dl>
3.1770 + *
3.1771 + * @throws nanoxml.XMLParseException
3.1772 + * If an error occured while parsing the string.
3.1773 + */
3.1774 + public void parseString(String string,
3.1775 + int offset)
3.1776 + throws XMLParseException
3.1777 + {
3.1778 + this.parseString(string.substring(offset));
3.1779 + }
3.1780 +
3.1781 +
3.1782 + /**
3.1783 + * Reads one XML element from a String and parses it.
3.1784 + *
3.1785 + * @param reader
3.1786 + * The reader from which to retrieve the XML data.
3.1787 + * @param offset
3.1788 + * The first character in <code>string</code> to scan.
3.1789 + * @param end
3.1790 + * The character where to stop scanning.
3.1791 + * This character is not scanned.
3.1792 + *
3.1793 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1794 + * <ul><li><code>string != null</code>
3.1795 + * <li><code>end <= string.length()</code>
3.1796 + * <li><code>offset < end</code>
3.1797 + * <li><code>offset >= 0</code>
3.1798 + * </ul></dd></dl>
3.1799 + *
3.1800 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1801 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1802 + * parsed from the reader
3.1803 + * </ul></dd></dl><dl>
3.1804 + *
3.1805 + * @throws nanoxml.XMLParseException
3.1806 + * If an error occured while parsing the string.
3.1807 + */
3.1808 + public void parseString(String string,
3.1809 + int offset,
3.1810 + int end)
3.1811 + throws XMLParseException
3.1812 + {
3.1813 + this.parseString(string.substring(offset, end));
3.1814 + }
3.1815 +
3.1816 +
3.1817 + /**
3.1818 + * Reads one XML element from a String and parses it.
3.1819 + *
3.1820 + * @param reader
3.1821 + * The reader from which to retrieve the XML data.
3.1822 + * @param offset
3.1823 + * The first character in <code>string</code> to scan.
3.1824 + * @param end
3.1825 + * The character where to stop scanning.
3.1826 + * This character is not scanned.
3.1827 + * @param startingLineNr
3.1828 + * The line number of the first line in the data.
3.1829 + *
3.1830 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1831 + * <ul><li><code>string != null</code>
3.1832 + * <li><code>end <= string.length()</code>
3.1833 + * <li><code>offset < end</code>
3.1834 + * <li><code>offset >= 0</code>
3.1835 + * </ul></dd></dl>
3.1836 + *
3.1837 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1838 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1839 + * parsed from the reader
3.1840 + * </ul></dd></dl><dl>
3.1841 + *
3.1842 + * @throws nanoxml.XMLParseException
3.1843 + * If an error occured while parsing the string.
3.1844 + */
3.1845 + public void parseString(String string,
3.1846 + int offset,
3.1847 + int end,
3.1848 + int startingLineNr)
3.1849 + throws XMLParseException
3.1850 + {
3.1851 + string = string.substring(offset, end);
3.1852 + try {
3.1853 + this.parseFromReader(new StringReader(string), startingLineNr);
3.1854 + } catch (IOException e) {
3.1855 + // Java exception handling suxx
3.1856 + }
3.1857 + }
3.1858 +
3.1859 +
3.1860 + /**
3.1861 + * Reads one XML element from a char array and parses it.
3.1862 + *
3.1863 + * @param reader
3.1864 + * The reader from which to retrieve the XML data.
3.1865 + * @param offset
3.1866 + * The first character in <code>string</code> to scan.
3.1867 + * @param end
3.1868 + * The character where to stop scanning.
3.1869 + * This character is not scanned.
3.1870 + *
3.1871 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1872 + * <ul><li><code>input != null</code>
3.1873 + * <li><code>end <= input.length</code>
3.1874 + * <li><code>offset < end</code>
3.1875 + * <li><code>offset >= 0</code>
3.1876 + * </ul></dd></dl>
3.1877 + *
3.1878 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1879 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1880 + * parsed from the reader
3.1881 + * </ul></dd></dl><dl>
3.1882 + *
3.1883 + * @throws nanoxml.XMLParseException
3.1884 + * If an error occured while parsing the string.
3.1885 + */
3.1886 + public void parseCharArray(char[] input,
3.1887 + int offset,
3.1888 + int end)
3.1889 + throws XMLParseException
3.1890 + {
3.1891 + this.parseCharArray(input, offset, end, /*startingLineNr*/ 1);
3.1892 + }
3.1893 +
3.1894 +
3.1895 + /**
3.1896 + * Reads one XML element from a char array and parses it.
3.1897 + *
3.1898 + * @param reader
3.1899 + * The reader from which to retrieve the XML data.
3.1900 + * @param offset
3.1901 + * The first character in <code>string</code> to scan.
3.1902 + * @param end
3.1903 + * The character where to stop scanning.
3.1904 + * This character is not scanned.
3.1905 + * @param startingLineNr
3.1906 + * The line number of the first line in the data.
3.1907 + *
3.1908 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1909 + * <ul><li><code>input != null</code>
3.1910 + * <li><code>end <= input.length</code>
3.1911 + * <li><code>offset < end</code>
3.1912 + * <li><code>offset >= 0</code>
3.1913 + * </ul></dd></dl>
3.1914 + *
3.1915 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1916 + * <ul><li>the state of the receiver is updated to reflect the XML element
3.1917 + * parsed from the reader
3.1918 + * </ul></dd></dl><dl>
3.1919 + *
3.1920 + * @throws nanoxml.XMLParseException
3.1921 + * If an error occured while parsing the string.
3.1922 + */
3.1923 + public void parseCharArray(char[] input,
3.1924 + int offset,
3.1925 + int end,
3.1926 + int startingLineNr)
3.1927 + throws XMLParseException
3.1928 + {
3.1929 + try {
3.1930 + Reader reader = new CharArrayReader(input, offset, end);
3.1931 + this.parseFromReader(reader, startingLineNr);
3.1932 + } catch (IOException e) {
3.1933 + // This exception will never happen.
3.1934 + }
3.1935 + }
3.1936 +
3.1937 +
3.1938 + /**
3.1939 + * Removes a child element.
3.1940 + *
3.1941 + * @param child
3.1942 + * The child element to remove.
3.1943 + *
3.1944 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1945 + * <ul><li><code>child != null</code>
3.1946 + * <li><code>child</code> is a child element of the receiver
3.1947 + * </ul></dd></dl>
3.1948 + *
3.1949 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1950 + * <ul><li>countChildren() => old.countChildren() - 1
3.1951 + * <li>enumerateChildren() => old.enumerateChildren() - child
3.1952 + * <li>getChildren() => old.enumerateChildren() - child
3.1953 + * </ul></dd></dl><dl>
3.1954 + *
3.1955 + * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
3.1956 + * addChild(XMLElement)
3.1957 + * @see nanoxml.XMLElement#countChildren()
3.1958 + * @see nanoxml.XMLElement#enumerateChildren()
3.1959 + * @see nanoxml.XMLElement#getChildren()
3.1960 + */
3.1961 + public void removeChild(XMLElement child)
3.1962 + {
3.1963 + this.children.removeElement(child);
3.1964 + }
3.1965 +
3.1966 +
3.1967 + /**
3.1968 + * Removes an attribute.
3.1969 + *
3.1970 + * @param name
3.1971 + * The name of the attribute.
3.1972 + *
3.1973 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.1974 + * <ul><li><code>name != null</code>
3.1975 + * <li><code>name</code> is a valid XML identifier
3.1976 + * </ul></dd></dl>
3.1977 + *
3.1978 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.1979 + * <ul><li>enumerateAttributeNames()
3.1980 + * => old.enumerateAttributeNames() - name
3.1981 + * <li>getAttribute(name) => <code>null</code>
3.1982 + * </ul></dd></dl><dl>
3.1983 + *
3.1984 + * @see nanoxml.XMLElement#enumerateAttributeNames()
3.1985 + * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
3.1986 + * setDoubleAttribute(String, double)
3.1987 + * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
3.1988 + * setIntAttribute(String, int)
3.1989 + * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
3.1990 + * setAttribute(String, Object)
3.1991 + * @see nanoxml.XMLElement#getAttribute(java.lang.String)
3.1992 + * getAttribute(String)
3.1993 + * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
3.1994 + * getAttribute(String, Object)
3.1995 + * @see nanoxml.XMLElement#getAttribute(java.lang.String,
3.1996 + * java.util.Hashtable,
3.1997 + * java.lang.String, boolean)
3.1998 + * getAttribute(String, Hashtable, String, boolean)
3.1999 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
3.2000 + * getStringAttribute(String)
3.2001 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.2002 + * java.lang.String)
3.2003 + * getStringAttribute(String, String)
3.2004 + * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
3.2005 + * java.util.Hashtable,
3.2006 + * java.lang.String, boolean)
3.2007 + * getStringAttribute(String, Hashtable, String, boolean)
3.2008 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
3.2009 + * getIntAttribute(String)
3.2010 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
3.2011 + * getIntAttribute(String, int)
3.2012 + * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
3.2013 + * java.util.Hashtable,
3.2014 + * java.lang.String, boolean)
3.2015 + * getIntAttribute(String, Hashtable, String, boolean)
3.2016 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
3.2017 + * getDoubleAttribute(String)
3.2018 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
3.2019 + * getDoubleAttribute(String, double)
3.2020 + * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
3.2021 + * java.util.Hashtable,
3.2022 + * java.lang.String, boolean)
3.2023 + * getDoubleAttribute(String, Hashtable, String, boolean)
3.2024 + * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String,
3.2025 + * java.lang.String,
3.2026 + * java.lang.String, boolean)
3.2027 + * getBooleanAttribute(String, String, String, boolean)
3.2028 + */
3.2029 + public void removeAttribute(String name)
3.2030 + {
3.2031 + if (this.ignoreCase) {
3.2032 + name = name.toUpperCase();
3.2033 + }
3.2034 + this.attributes.remove(name);
3.2035 + }
3.2036 +
3.2037 +
3.2038 + /**
3.2039 + * Removes an attribute.
3.2040 + *
3.2041 + * @param name
3.2042 + * The name of the attribute.
3.2043 + *
3.2044 + * @deprecated Use {@link #removeAttribute(java.lang.String)
3.2045 + * removeAttribute} instead.
3.2046 + */
3.2047 + public void removeProperty(String name)
3.2048 + {
3.2049 + this.removeAttribute(name);
3.2050 + }
3.2051 +
3.2052 +
3.2053 + /**
3.2054 + * Removes an attribute.
3.2055 + *
3.2056 + * @param name
3.2057 + * The name of the attribute.
3.2058 + *
3.2059 + * @deprecated Use {@link #removeAttribute(java.lang.String)
3.2060 + * removeAttribute} instead.
3.2061 + */
3.2062 + public void removeChild(String name)
3.2063 + {
3.2064 + this.removeAttribute(name);
3.2065 + }
3.2066 +
3.2067 +
3.2068 + /**
3.2069 + * Creates a new similar XML element.
3.2070 + * <P>
3.2071 + * You should override this method when subclassing XMLElement.
3.2072 + */
3.2073 + protected XMLElement createAnotherElement()
3.2074 + {
3.2075 + return new XMLElement(this.entities,
3.2076 + this.ignoreWhitespace,
3.2077 + false,
3.2078 + this.ignoreCase);
3.2079 + }
3.2080 +
3.2081 +
3.2082 + /**
3.2083 + * Changes the content string.
3.2084 + *
3.2085 + * @param content
3.2086 + * The new content string.
3.2087 + */
3.2088 + public void setContent(String content)
3.2089 + {
3.2090 + this.contents = content;
3.2091 + }
3.2092 +
3.2093 +
3.2094 + /**
3.2095 + * Changes the name of the element.
3.2096 + *
3.2097 + * @param name
3.2098 + * The new name.
3.2099 + *
3.2100 + * @deprecated Use {@link #setName(java.lang.String) setName} instead.
3.2101 + */
3.2102 + public void setTagName(String name)
3.2103 + {
3.2104 + this.setName(name);
3.2105 + }
3.2106 +
3.2107 +
3.2108 + /**
3.2109 + * Changes the name of the element.
3.2110 + *
3.2111 + * @param name
3.2112 + * The new name.
3.2113 + *
3.2114 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2115 + * <ul><li><code>name != null</code>
3.2116 + * <li><code>name</code> is a valid XML identifier
3.2117 + * </ul></dd></dl>
3.2118 + *
3.2119 + * @see nanoxml.XMLElement#getName()
3.2120 + */
3.2121 + public void setName(String name)
3.2122 + {
3.2123 + this.name = name;
3.2124 + }
3.2125 +
3.2126 +
3.2127 + /**
3.2128 + * Writes the XML element to a string.
3.2129 + *
3.2130 + * @see nanoxml.XMLElement#write(java.io.Writer) write(Writer)
3.2131 + */
3.2132 + public String toString()
3.2133 + {
3.2134 + try {
3.2135 + ByteArrayOutputStream out = new ByteArrayOutputStream();
3.2136 + OutputStreamWriter writer = new OutputStreamWriter(out);
3.2137 + this.write(writer);
3.2138 + writer.flush();
3.2139 + return new String(out.toByteArray());
3.2140 + } catch (IOException e) {
3.2141 + // Java exception handling suxx
3.2142 + return super.toString();
3.2143 + }
3.2144 + }
3.2145 +
3.2146 +
3.2147 + /**
3.2148 + * Writes the XML element to a writer.
3.2149 + *
3.2150 + * @param writer
3.2151 + * The writer to write the XML data to.
3.2152 + *
3.2153 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2154 + * <ul><li><code>writer != null</code>
3.2155 + * <li><code>writer</code> is not closed
3.2156 + * </ul></dd></dl>
3.2157 + *
3.2158 + * @throws java.io.IOException
3.2159 + * If the data could not be written to the writer.
3.2160 + *
3.2161 + * @see nanoxml.XMLElement#toString()
3.2162 + */
3.2163 + public void write(Writer writer)
3.2164 + throws IOException
3.2165 + {
3.2166 + if (this.name == null) {
3.2167 + this.writeEncoded(writer, this.contents);
3.2168 + return;
3.2169 + }
3.2170 + writer.write('<');
3.2171 + writer.write(this.name);
3.2172 + if (! this.attributes.isEmpty()) {
3.2173 + Enumeration enumV = this.attributes.keys();
3.2174 + while (enumV.hasMoreElements()) {
3.2175 + writer.write(' ');
3.2176 + String key = (String) enumV.nextElement();
3.2177 + String value = (String) this.attributes.get(key);
3.2178 + writer.write(key);
3.2179 + writer.write('='); writer.write('"');
3.2180 + this.writeEncoded(writer, value);
3.2181 + writer.write('"');
3.2182 + }
3.2183 + }
3.2184 + if ((this.contents != null) && (this.contents.length() > 0)) {
3.2185 + writer.write('>');
3.2186 + this.writeEncoded(writer, this.contents);
3.2187 + writer.write('<'); writer.write('/');
3.2188 + writer.write(this.name);
3.2189 + writer.write('>');
3.2190 + } else if (this.children.isEmpty()) {
3.2191 + writer.write('/'); writer.write('>');
3.2192 + } else {
3.2193 + writer.write('>');
3.2194 + Enumeration enumV = this.enumerateChildren();
3.2195 + while (enumV.hasMoreElements()) {
3.2196 + XMLElement child = (XMLElement) enumV.nextElement();
3.2197 + child.write(writer);
3.2198 + }
3.2199 + writer.write('<'); writer.write('/');
3.2200 + writer.write(this.name);
3.2201 + writer.write('>');
3.2202 + }
3.2203 + }
3.2204 +
3.2205 +
3.2206 + /**
3.2207 + * Writes a string encoded to a writer.
3.2208 + *
3.2209 + * @param writer
3.2210 + * The writer to write the XML data to.
3.2211 + * @param str
3.2212 + * The string to write encoded.
3.2213 + *
3.2214 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2215 + * <ul><li><code>writer != null</code>
3.2216 + * <li><code>writer</code> is not closed
3.2217 + * <li><code>str != null</code>
3.2218 + * </ul></dd></dl>
3.2219 + */
3.2220 + protected void writeEncoded(Writer writer,
3.2221 + String str)
3.2222 + throws IOException
3.2223 + {
3.2224 + for (int i = 0; i < str.length(); i += 1) {
3.2225 + char ch = str.charAt(i);
3.2226 + switch (ch) {
3.2227 + case '<':
3.2228 + writer.write('&'); writer.write('l'); writer.write('t');
3.2229 + writer.write(';');
3.2230 + break;
3.2231 + case '>':
3.2232 + writer.write('&'); writer.write('g'); writer.write('t');
3.2233 + writer.write(';');
3.2234 + break;
3.2235 + case '&':
3.2236 + writer.write('&'); writer.write('a'); writer.write('m');
3.2237 + writer.write('p'); writer.write(';');
3.2238 + break;
3.2239 + case '"':
3.2240 + writer.write('&'); writer.write('q'); writer.write('u');
3.2241 + writer.write('o'); writer.write('t'); writer.write(';');
3.2242 + break;
3.2243 + case '\'':
3.2244 + writer.write('&'); writer.write('a'); writer.write('p');
3.2245 + writer.write('o'); writer.write('s'); writer.write(';');
3.2246 + break;
3.2247 + default:
3.2248 + int unicode = (int) ch;
3.2249 + if ((unicode < 32) || (unicode > 126)) {
3.2250 + writer.write('&'); writer.write('#');
3.2251 + writer.write('x');
3.2252 + writer.write(Integer.toString(unicode, 16));
3.2253 + writer.write(';');
3.2254 + } else {
3.2255 + writer.write(ch);
3.2256 + }
3.2257 + }
3.2258 + }
3.2259 + }
3.2260 +
3.2261 +
3.2262 + /**
3.2263 + * Scans an identifier from the current reader.
3.2264 + * The scanned identifier is appended to <code>result</code>.
3.2265 + *
3.2266 + * @param result
3.2267 + * The buffer in which the scanned identifier will be put.
3.2268 + *
3.2269 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2270 + * <ul><li><code>result != null</code>
3.2271 + * <li>The next character read from the reader is a valid first
3.2272 + * character of an XML identifier.
3.2273 + * </ul></dd></dl>
3.2274 + *
3.2275 + * <dl><dt><b>Postconditions:</b></dt><dd>
3.2276 + * <ul><li>The next character read from the reader won't be an identifier
3.2277 + * character.
3.2278 + * </ul></dd></dl><dl>
3.2279 + */
3.2280 + protected void scanIdentifier(StringBuffer result)
3.2281 + throws IOException
3.2282 + {
3.2283 + for (;;) {
3.2284 + char ch = this.readChar();
3.2285 + if (((ch < 'A') || (ch > 'Z')) && ((ch < 'a') || (ch > 'z'))
3.2286 + && ((ch < '0') || (ch > '9')) && (ch != '_') && (ch != '.')
3.2287 + && (ch != ':') && (ch != '-') && (ch <= '\u007E')) {
3.2288 + this.unreadChar(ch);
3.2289 + return;
3.2290 + }
3.2291 + result.append(ch);
3.2292 + }
3.2293 + }
3.2294 +
3.2295 +
3.2296 + /**
3.2297 + * This method scans an identifier from the current reader.
3.2298 + *
3.2299 + * @return the next character following the whitespace.
3.2300 + */
3.2301 + protected char scanWhitespace()
3.2302 + throws IOException
3.2303 + {
3.2304 + for (;;) {
3.2305 + char ch = this.readChar();
3.2306 + switch (ch) {
3.2307 + case ' ':
3.2308 + case '\t':
3.2309 + case '\n':
3.2310 + case '\r':
3.2311 + break;
3.2312 + default:
3.2313 + return ch;
3.2314 + }
3.2315 + }
3.2316 + }
3.2317 +
3.2318 +
3.2319 + /**
3.2320 + * This method scans an identifier from the current reader.
3.2321 + * The scanned whitespace is appended to <code>result</code>.
3.2322 + *
3.2323 + * @return the next character following the whitespace.
3.2324 + *
3.2325 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2326 + * <ul><li><code>result != null</code>
3.2327 + * </ul></dd></dl>
3.2328 + */
3.2329 + protected char scanWhitespace(StringBuffer result)
3.2330 + throws IOException
3.2331 + {
3.2332 + for (;;) {
3.2333 + char ch = this.readChar();
3.2334 + switch (ch) {
3.2335 + case ' ':
3.2336 + case '\t':
3.2337 + case '\n':
3.2338 + result.append(ch);
3.2339 + case '\r':
3.2340 + break;
3.2341 + default:
3.2342 + return ch;
3.2343 + }
3.2344 + }
3.2345 + }
3.2346 +
3.2347 +
3.2348 + /**
3.2349 + * This method scans a delimited string from the current reader.
3.2350 + * The scanned string without delimiters is appended to
3.2351 + * <code>string</code>.
3.2352 + *
3.2353 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2354 + * <ul><li><code>string != null</code>
3.2355 + * <li>the next char read is the string delimiter
3.2356 + * </ul></dd></dl>
3.2357 + */
3.2358 + protected void scanString(StringBuffer string)
3.2359 + throws IOException
3.2360 + {
3.2361 + char delimiter = this.readChar();
3.2362 + if ((delimiter != '\'') && (delimiter != '"')) {
3.2363 + throw this.expectedInput("' or \"");
3.2364 + }
3.2365 + for (;;) {
3.2366 + char ch = this.readChar();
3.2367 + if (ch == delimiter) {
3.2368 + return;
3.2369 + } else if (ch == '&') {
3.2370 + this.resolveEntity(string);
3.2371 + } else {
3.2372 + string.append(ch);
3.2373 + }
3.2374 + }
3.2375 + }
3.2376 +
3.2377 +
3.2378 + /**
3.2379 + * Scans a #PCDATA element. CDATA sections and entities are resolved.
3.2380 + * The next < char is skipped.
3.2381 + * The scanned data is appended to <code>data</code>.
3.2382 + *
3.2383 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2384 + * <ul><li><code>data != null</code>
3.2385 + * </ul></dd></dl>
3.2386 + */
3.2387 + protected void scanPCData(StringBuffer data)
3.2388 + throws IOException
3.2389 + {
3.2390 + for (;;) {
3.2391 + char ch = this.readChar();
3.2392 + if (ch == '<') {
3.2393 + ch = this.readChar();
3.2394 + if (ch == '!') {
3.2395 + this.checkCDATA(data);
3.2396 + } else {
3.2397 + this.unreadChar(ch);
3.2398 + return;
3.2399 + }
3.2400 + } else if (ch == '&') {
3.2401 + this.resolveEntity(data);
3.2402 + } else {
3.2403 + data.append(ch);
3.2404 + }
3.2405 + }
3.2406 + }
3.2407 +
3.2408 +
3.2409 + /**
3.2410 + * Scans a special tag and if the tag is a CDATA section, append its
3.2411 + * content to <code>buf</code>.
3.2412 + *
3.2413 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2414 + * <ul><li><code>buf != null</code>
3.2415 + * <li>The first < has already been read.
3.2416 + * </ul></dd></dl>
3.2417 + */
3.2418 + protected boolean checkCDATA(StringBuffer buf)
3.2419 + throws IOException
3.2420 + {
3.2421 + char ch = this.readChar();
3.2422 + if (ch != '[') {
3.2423 + this.unreadChar(ch);
3.2424 + this.skipSpecialTag(0);
3.2425 + return false;
3.2426 + } else if (! this.checkLiteral("CDATA[")) {
3.2427 + this.skipSpecialTag(1); // one [ has already been read
3.2428 + return false;
3.2429 + } else {
3.2430 + int delimiterCharsSkipped = 0;
3.2431 + while (delimiterCharsSkipped < 3) {
3.2432 + ch = this.readChar();
3.2433 + switch (ch) {
3.2434 + case ']':
3.2435 + if (delimiterCharsSkipped < 2) {
3.2436 + delimiterCharsSkipped += 1;
3.2437 + } else {
3.2438 + buf.append(']');
3.2439 + buf.append(']');
3.2440 + delimiterCharsSkipped = 0;
3.2441 + }
3.2442 + break;
3.2443 + case '>':
3.2444 + if (delimiterCharsSkipped < 2) {
3.2445 + for (int i = 0; i < delimiterCharsSkipped; i++) {
3.2446 + buf.append(']');
3.2447 + }
3.2448 + delimiterCharsSkipped = 0;
3.2449 + buf.append('>');
3.2450 + } else {
3.2451 + delimiterCharsSkipped = 3;
3.2452 + }
3.2453 + break;
3.2454 + default:
3.2455 + for (int i = 0; i < delimiterCharsSkipped; i += 1) {
3.2456 + buf.append(']');
3.2457 + }
3.2458 + buf.append(ch);
3.2459 + delimiterCharsSkipped = 0;
3.2460 + }
3.2461 + }
3.2462 + return true;
3.2463 + }
3.2464 + }
3.2465 +
3.2466 +
3.2467 + /**
3.2468 + * Skips a comment.
3.2469 + *
3.2470 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2471 + * <ul><li>The first <!-- has already been read.
3.2472 + * </ul></dd></dl>
3.2473 + */
3.2474 + protected void skipComment()
3.2475 + throws IOException
3.2476 + {
3.2477 + int dashesToRead = 2;
3.2478 + while (dashesToRead > 0) {
3.2479 + char ch = this.readChar();
3.2480 + if (ch == '-') {
3.2481 + dashesToRead -= 1;
3.2482 + } else {
3.2483 + dashesToRead = 2;
3.2484 + }
3.2485 + }
3.2486 + if (this.readChar() != '>') {
3.2487 + throw this.expectedInput(">");
3.2488 + }
3.2489 + }
3.2490 +
3.2491 +
3.2492 + /**
3.2493 + * Skips a special tag or comment.
3.2494 + *
3.2495 + * @param bracketLevel The number of open square brackets ([) that have
3.2496 + * already been read.
3.2497 + *
3.2498 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2499 + * <ul><li>The first <! has already been read.
3.2500 + * <li><code>bracketLevel >= 0</code>
3.2501 + * </ul></dd></dl>
3.2502 + */
3.2503 + protected void skipSpecialTag(int bracketLevel)
3.2504 + throws IOException
3.2505 + {
3.2506 + int tagLevel = 1; // <
3.2507 + char stringDelimiter = '\0';
3.2508 + if (bracketLevel == 0) {
3.2509 + char ch = this.readChar();
3.2510 + if (ch == '[') {
3.2511 + bracketLevel += 1;
3.2512 + } else if (ch == '-') {
3.2513 + ch = this.readChar();
3.2514 + if (ch == '[') {
3.2515 + bracketLevel += 1;
3.2516 + } else if (ch == ']') {
3.2517 + bracketLevel -= 1;
3.2518 + } else if (ch == '-') {
3.2519 + this.skipComment();
3.2520 + return;
3.2521 + }
3.2522 + }
3.2523 + }
3.2524 + while (tagLevel > 0) {
3.2525 + char ch = this.readChar();
3.2526 + if (stringDelimiter == '\0') {
3.2527 + if ((ch == '"') || (ch == '\'')) {
3.2528 + stringDelimiter = ch;
3.2529 + } else if (bracketLevel <= 0) {
3.2530 + if (ch == '<') {
3.2531 + tagLevel += 1;
3.2532 + } else if (ch == '>') {
3.2533 + tagLevel -= 1;
3.2534 + }
3.2535 + }
3.2536 + if (ch == '[') {
3.2537 + bracketLevel += 1;
3.2538 + } else if (ch == ']') {
3.2539 + bracketLevel -= 1;
3.2540 + }
3.2541 + } else {
3.2542 + if (ch == stringDelimiter) {
3.2543 + stringDelimiter = '\0';
3.2544 + }
3.2545 + }
3.2546 + }
3.2547 + }
3.2548 +
3.2549 +
3.2550 + /**
3.2551 + * Scans the data for literal text.
3.2552 + * Scanning stops when a character does not match or after the complete
3.2553 + * text has been checked, whichever comes first.
3.2554 + *
3.2555 + * @param literal the literal to check.
3.2556 + *
3.2557 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2558 + * <ul><li><code>literal != null</code>
3.2559 + * </ul></dd></dl>
3.2560 + */
3.2561 + protected boolean checkLiteral(String literal)
3.2562 + throws IOException
3.2563 + {
3.2564 + int length = literal.length();
3.2565 + for (int i = 0; i < length; i += 1) {
3.2566 + if (this.readChar() != literal.charAt(i)) {
3.2567 + return false;
3.2568 + }
3.2569 + }
3.2570 + return true;
3.2571 + }
3.2572 +
3.2573 +
3.2574 + /**
3.2575 + * Reads a character from a reader.
3.2576 + */
3.2577 + protected char readChar()
3.2578 + throws IOException
3.2579 + {
3.2580 + if (this.charReadTooMuch != '\0') {
3.2581 + char ch = this.charReadTooMuch;
3.2582 + this.charReadTooMuch = '\0';
3.2583 + return ch;
3.2584 + } else {
3.2585 + int i = this.reader.read();
3.2586 + if (i < 0) {
3.2587 + throw this.unexpectedEndOfData();
3.2588 + } else if (i == 10) {
3.2589 + this.parserLineNr += 1;
3.2590 + return '\n';
3.2591 + } else {
3.2592 + return (char) i;
3.2593 + }
3.2594 + }
3.2595 + }
3.2596 +
3.2597 +
3.2598 + /**
3.2599 + * Scans an XML element.
3.2600 + *
3.2601 + * @param elt The element that will contain the result.
3.2602 + *
3.2603 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2604 + * <ul><li>The first < has already been read.
3.2605 + * <li><code>elt != null</code>
3.2606 + * </ul></dd></dl>
3.2607 + */
3.2608 + protected void scanElement(XMLElement elt)
3.2609 + throws IOException
3.2610 + {
3.2611 + StringBuffer buf = new StringBuffer();
3.2612 + this.scanIdentifier(buf);
3.2613 + String name = buf.toString();
3.2614 + elt.setName(name);
3.2615 + char ch = this.scanWhitespace();
3.2616 + while ((ch != '>') && (ch != '/')) {
3.2617 + buf.setLength(0);
3.2618 + this.unreadChar(ch);
3.2619 + this.scanIdentifier(buf);
3.2620 + String key = buf.toString();
3.2621 + ch = this.scanWhitespace();
3.2622 + if (ch != '=') {
3.2623 + throw this.expectedInput("=");
3.2624 + }
3.2625 + this.unreadChar(this.scanWhitespace());
3.2626 + buf.setLength(0);
3.2627 + this.scanString(buf);
3.2628 + elt.setAttribute(key, buf);
3.2629 + ch = this.scanWhitespace();
3.2630 + }
3.2631 + if (ch == '/') {
3.2632 + ch = this.readChar();
3.2633 + if (ch != '>') {
3.2634 + throw this.expectedInput(">");
3.2635 + }
3.2636 + return;
3.2637 + }
3.2638 + buf.setLength(0);
3.2639 + ch = this.scanWhitespace(buf);
3.2640 + if (ch != '<') {
3.2641 + this.unreadChar(ch);
3.2642 + this.scanPCData(buf);
3.2643 + } else {
3.2644 + for (;;) {
3.2645 + ch = this.readChar();
3.2646 + if (ch == '!') {
3.2647 + if (this.checkCDATA(buf)) {
3.2648 + this.scanPCData(buf);
3.2649 + break;
3.2650 + } else {
3.2651 + ch = this.scanWhitespace(buf);
3.2652 + if (ch != '<') {
3.2653 + this.unreadChar(ch);
3.2654 + this.scanPCData(buf);
3.2655 + break;
3.2656 + }
3.2657 + }
3.2658 + } else {
3.2659 + if ((ch != '/') || this.ignoreWhitespace) {
3.2660 + buf.setLength(0);
3.2661 + }
3.2662 + if (ch == '/') {
3.2663 + this.unreadChar(ch);
3.2664 + }
3.2665 + break;
3.2666 + }
3.2667 + }
3.2668 + }
3.2669 + if (buf.length() == 0) {
3.2670 + while (ch != '/') {
3.2671 + if (ch == '!') {
3.2672 + ch = this.readChar();
3.2673 + if (ch != '-') {
3.2674 + throw this.expectedInput("Comment or Element");
3.2675 + }
3.2676 + ch = this.readChar();
3.2677 + if (ch != '-') {
3.2678 + throw this.expectedInput("Comment or Element");
3.2679 + }
3.2680 + this.skipComment();
3.2681 + } else {
3.2682 + this.unreadChar(ch);
3.2683 + XMLElement child = this.createAnotherElement();
3.2684 + this.scanElement(child);
3.2685 + elt.addChild(child);
3.2686 + }
3.2687 + ch = this.scanWhitespace();
3.2688 + if (ch != '<') {
3.2689 + throw this.expectedInput("<");
3.2690 + }
3.2691 + ch = this.readChar();
3.2692 + }
3.2693 + this.unreadChar(ch);
3.2694 + } else {
3.2695 + if (this.ignoreWhitespace) {
3.2696 + elt.setContent(buf.toString().trim());
3.2697 + } else {
3.2698 + elt.setContent(buf.toString());
3.2699 + }
3.2700 + }
3.2701 + ch = this.readChar();
3.2702 + if (ch != '/') {
3.2703 + throw this.expectedInput("/");
3.2704 + }
3.2705 + this.unreadChar(this.scanWhitespace());
3.2706 + if (! this.checkLiteral(name)) {
3.2707 + throw this.expectedInput(name);
3.2708 + }
3.2709 + if (this.scanWhitespace() != '>') {
3.2710 + throw this.expectedInput(">");
3.2711 + }
3.2712 + }
3.2713 +
3.2714 +
3.2715 + /**
3.2716 + * Resolves an entity. The name of the entity is read from the reader.
3.2717 + * The value of the entity is appended to <code>buf</code>.
3.2718 + *
3.2719 + * @param buf Where to put the entity value.
3.2720 + *
3.2721 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2722 + * <ul><li>The first & has already been read.
3.2723 + * <li><code>buf != null</code>
3.2724 + * </ul></dd></dl>
3.2725 + */
3.2726 + protected void resolveEntity(StringBuffer buf)
3.2727 + throws IOException
3.2728 + {
3.2729 + char ch = '\0';
3.2730 + StringBuffer keyBuf = new StringBuffer();
3.2731 + for (;;) {
3.2732 + ch = this.readChar();
3.2733 + if (ch == ';') {
3.2734 + break;
3.2735 + }
3.2736 + keyBuf.append(ch);
3.2737 + }
3.2738 + String key = keyBuf.toString();
3.2739 + if (key.charAt(0) == '#') {
3.2740 + try {
3.2741 + if (key.charAt(1) == 'x') {
3.2742 + ch = (char) Integer.parseInt(key.substring(2), 16);
3.2743 + } else {
3.2744 + ch = (char) Integer.parseInt(key.substring(1), 10);
3.2745 + }
3.2746 + } catch (NumberFormatException e) {
3.2747 + throw this.unknownEntity(key);
3.2748 + }
3.2749 + buf.append(ch);
3.2750 + } else {
3.2751 + char[] value = (char[]) this.entities.get(key);
3.2752 + if (value == null) {
3.2753 + throw this.unknownEntity(key);
3.2754 + }
3.2755 + buf.append(value);
3.2756 + }
3.2757 + }
3.2758 +
3.2759 +
3.2760 + /**
3.2761 + * Pushes a character back to the read-back buffer.
3.2762 + *
3.2763 + * @param ch The character to push back.
3.2764 + *
3.2765 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2766 + * <ul><li>The read-back buffer is empty.
3.2767 + * <li><code>ch != '\0'</code>
3.2768 + * </ul></dd></dl>
3.2769 + */
3.2770 + protected void unreadChar(char ch)
3.2771 + {
3.2772 + this.charReadTooMuch = ch;
3.2773 + }
3.2774 +
3.2775 +
3.2776 + /**
3.2777 + * Creates a parse exception for when an invalid valueset is given to
3.2778 + * a method.
3.2779 + *
3.2780 + * @param name The name of the entity.
3.2781 + *
3.2782 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2783 + * <ul><li><code>name != null</code>
3.2784 + * </ul></dd></dl>
3.2785 + */
3.2786 + protected XMLParseException invalidValueSet(String name)
3.2787 + {
3.2788 + String msg = "Invalid value set (entity name = \"" + name + "\")";
3.2789 + return new XMLParseException(this.getName(), this.parserLineNr, msg);
3.2790 + }
3.2791 +
3.2792 +
3.2793 + /**
3.2794 + * Creates a parse exception for when an invalid value is given to a
3.2795 + * method.
3.2796 + *
3.2797 + * @param name The name of the entity.
3.2798 + * @param value The value of the entity.
3.2799 + *
3.2800 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2801 + * <ul><li><code>name != null</code>
3.2802 + * <li><code>value != null</code>
3.2803 + * </ul></dd></dl>
3.2804 + */
3.2805 + protected XMLParseException invalidValue(String name,
3.2806 + String value)
3.2807 + {
3.2808 + String msg = "Attribute \"" + name + "\" does not contain a valid "
3.2809 + + "value (\"" + value + "\")";
3.2810 + return new XMLParseException(this.getName(), this.parserLineNr, msg);
3.2811 + }
3.2812 +
3.2813 +
3.2814 + /**
3.2815 + * Creates a parse exception for when the end of the data input has been
3.2816 + * reached.
3.2817 + */
3.2818 + protected XMLParseException unexpectedEndOfData()
3.2819 + {
3.2820 + String msg = "Unexpected end of data reached";
3.2821 + return new XMLParseException(this.getName(), this.parserLineNr, msg);
3.2822 + }
3.2823 +
3.2824 +
3.2825 + /**
3.2826 + * Creates a parse exception for when a syntax error occured.
3.2827 + *
3.2828 + * @param context The context in which the error occured.
3.2829 + *
3.2830 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2831 + * <ul><li><code>context != null</code>
3.2832 + * <li><code>context.length() > 0</code>
3.2833 + * </ul></dd></dl>
3.2834 + */
3.2835 + protected XMLParseException syntaxError(String context)
3.2836 + {
3.2837 + String msg = "Syntax error while parsing " + context;
3.2838 + return new XMLParseException(this.getName(), this.parserLineNr, msg);
3.2839 + }
3.2840 +
3.2841 +
3.2842 + /**
3.2843 + * Creates a parse exception for when the next character read is not
3.2844 + * the character that was expected.
3.2845 + *
3.2846 + * @param charSet The set of characters (in human readable form) that was
3.2847 + * expected.
3.2848 + *
3.2849 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2850 + * <ul><li><code>charSet != null</code>
3.2851 + * <li><code>charSet.length() > 0</code>
3.2852 + * </ul></dd></dl>
3.2853 + */
3.2854 + protected XMLParseException expectedInput(String charSet)
3.2855 + {
3.2856 + String msg = "Expected: " + charSet;
3.2857 + return new XMLParseException(this.getName(), this.parserLineNr, msg);
3.2858 + }
3.2859 +
3.2860 +
3.2861 + /**
3.2862 + * Creates a parse exception for when an entity could not be resolved.
3.2863 + *
3.2864 + * @param name The name of the entity.
3.2865 + *
3.2866 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
3.2867 + * <ul><li><code>name != null</code>
3.2868 + * <li><code>name.length() > 0</code>
3.2869 + * </ul></dd></dl>
3.2870 + */
3.2871 + protected XMLParseException unknownEntity(String name)
3.2872 + {
3.2873 + String msg = "Unknown or invalid entity: &" + name + ";";
3.2874 + return new XMLParseException(this.getName(), this.parserLineNr, msg);
3.2875 + }
3.2876 +
3.2877 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/share/classes/sun/util/xml/XMLParseException.java Wed Jun 24 16:38:24 2009 +0200
4.3 @@ -0,0 +1,129 @@
4.4 +/* XMLParseException.java
4.5 + *
4.6 + * $Revision: 1.4 $
4.7 + * $Date: 2002/03/24 10:27:59 $
4.8 + * $Name: RELEASE_2_2_1 $
4.9 + *
4.10 + * This file is part of NanoXML 2 Lite.
4.11 + * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
4.12 + *
4.13 + * This software is provided 'as-is', without any express or implied warranty.
4.14 + * In no event will the authors be held liable for any damages arising from the
4.15 + * use of this software.
4.16 + *
4.17 + * Permission is granted to anyone to use this software for any purpose,
4.18 + * including commercial applications, and to alter it and redistribute it
4.19 + * freely, subject to the following restrictions:
4.20 + *
4.21 + * 1. The origin of this software must not be misrepresented; you must not
4.22 + * claim that you wrote the original software. If you use this software in
4.23 + * a product, an acknowledgment in the product documentation would be
4.24 + * appreciated but is not required.
4.25 + *
4.26 + * 2. Altered source versions must be plainly marked as such, and must not be
4.27 + * misrepresented as being the original software.
4.28 + *
4.29 + * 3. This notice may not be removed or altered from any source distribution.
4.30 + *****************************************************************************/
4.31 +
4.32 +
4.33 + package sun.util.xml;
4.34 +
4.35 +
4.36 +/**
4.37 + * An XMLParseException is thrown when an error occures while parsing an XML
4.38 + * string.
4.39 + * <P>
4.40 + * $Revision: 1.4 $<BR>
4.41 + * $Date: 2002/03/24 10:27:59 $<P>
4.42 + *
4.43 + * @see nanoxml.XMLElement
4.44 + *
4.45 + * @author Marc De Scheemaecker
4.46 + * @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
4.47 + */
4.48 +class XMLParseException extends RuntimeException
4.49 +{
4.50 +
4.51 + /**
4.52 + * Indicates that no line number has been associated with this exception.
4.53 + */
4.54 + public static final int NO_LINE = -1;
4.55 +
4.56 +
4.57 + /**
4.58 + * The line number in the source code where the error occurred, or
4.59 + * <code>NO_LINE</code> if the line number is unknown.
4.60 + *
4.61 + * <dl><dt><b>Invariants:</b></dt><dd>
4.62 + * <ul><li><code>lineNr > 0 || lineNr == NO_LINE</code>
4.63 + * </ul></dd></dl>
4.64 + */
4.65 + private int lineNr;
4.66 +
4.67 +
4.68 + /**
4.69 + * Creates an exception.
4.70 + *
4.71 + * @param name The name of the element where the error is located.
4.72 + * @param message A message describing what went wrong.
4.73 + *
4.74 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
4.75 + * <ul><li><code>message != null</code>
4.76 + * </ul></dd></dl>
4.77 + *
4.78 + * <dl><dt><b>Postconditions:</b></dt><dd>
4.79 + * <ul><li>getLineNr() => NO_LINE
4.80 + * </ul></dd></dl><dl>
4.81 + */
4.82 + public XMLParseException(String name,
4.83 + String message)
4.84 + {
4.85 + super("XML Parse Exception during parsing of "
4.86 + + ((name == null) ? "the XML definition"
4.87 + : ("a " + name + " element"))
4.88 + + ": " + message);
4.89 + this.lineNr = XMLParseException.NO_LINE;
4.90 + }
4.91 +
4.92 +
4.93 + /**
4.94 + * Creates an exception.
4.95 + *
4.96 + * @param name The name of the element where the error is located.
4.97 + * @param lineNr The number of the line in the input.
4.98 + * @param message A message describing what went wrong.
4.99 + *
4.100 + * </dl><dl><dt><b>Preconditions:</b></dt><dd>
4.101 + * <ul><li><code>message != null</code>
4.102 + * <li><code>lineNr > 0</code>
4.103 + * </ul></dd></dl>
4.104 + *
4.105 + * <dl><dt><b>Postconditions:</b></dt><dd>
4.106 + * <ul><li>getLineNr() => lineNr
4.107 + * </ul></dd></dl><dl>
4.108 + */
4.109 + public XMLParseException(String name,
4.110 + int lineNr,
4.111 + String message)
4.112 + {
4.113 + super("XML Parse Exception during parsing of "
4.114 + + ((name == null) ? "the XML definition"
4.115 + : ("a " + name + " element"))
4.116 + + " at line " + lineNr + ": " + message);
4.117 + this.lineNr = lineNr;
4.118 + }
4.119 +
4.120 +
4.121 + /**
4.122 + * Where the error occurred, or <code>NO_LINE</code> if the line number is
4.123 + * unknown.
4.124 + *
4.125 + * @see nanoxml.XMLParseException#NO_LINE
4.126 + */
4.127 + public int getLineNr()
4.128 + {
4.129 + return this.lineNr;
4.130 + }
4.131 +
4.132 +}
5.1 --- a/test/java/util/Properties/XMLReadAndWriteTest.java Wed Jun 24 14:53:01 2009 +0200
5.2 +++ b/test/java/util/Properties/XMLReadAndWriteTest.java Wed Jun 24 16:38:24 2009 +0200
5.3 @@ -3,6 +3,7 @@
5.4 * and open the template in the editor.
5.5 */
5.6
5.7 +import java.io.ByteArrayInputStream;
5.8 import sun.util.xml.PropertiesXMLUtils;
5.9
5.10 import java.io.ByteArrayOutputStream;
5.11 @@ -22,6 +23,7 @@
5.12 public static void main(String[] args) throws Exception {
5.13 XMLReadAndWriteTest test = new XMLReadAndWriteTest();
5.14 test.testCompareOutput();
5.15 + test.testCompareInput();
5.16 }
5.17
5.18
5.19 @@ -48,4 +50,34 @@
5.20 }
5.21 }
5.22
5.23 + public void testCompareInput() throws IOException {
5.24 + String text = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" +
5.25 + " <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'>" +
5.26 + "<properties>\n" +
5.27 + "<comment>my commment on beginging\n" +
5.28 + "and on the second line" +
5.29 + "</comment>" +
5.30 + "<entry key=\"ahoj\">simple</entry>\n" +
5.31 + " <entry key=\"kuk\">buk</entry>" +
5.32 + " <entry key='multi'>one\n" +
5.33 + "two\n" +
5.34 + "three\n" +
5.35 + "four</entry>\n</properties>";
5.36 +
5.37 + Properties p1 = new Properties();
5.38 + {
5.39 + ByteArrayInputStream is = new ByteArrayInputStream(text.getBytes("UTF-8"));
5.40 + FULL.load(p1, is);
5.41 + }
5.42 +
5.43 + Properties p2 = new Properties();
5.44 + {
5.45 + ByteArrayInputStream is = new ByteArrayInputStream(text.getBytes("UTF-8"));
5.46 + SIMPLE.load(p2, is);
5.47 + }
5.48 +
5.49 + assert p1.equals(p2) : "P1: " + p1 + "\nP2: " + p2;
5.50 + System.err.println("OK: testCompareInput");
5.51 + }
5.52 +
5.53 }
5.54 \ No newline at end of file