123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 |
- /* Properties.java -- a set of persistent properties
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package java.util;
- import gnu.java.lang.CPStringBuilder;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.io.PrintStream;
- import java.io.PrintWriter;
- import java.io.Reader;
- import javax.xml.stream.XMLInputFactory;
- import javax.xml.stream.XMLStreamConstants;
- import javax.xml.stream.XMLStreamException;
- import javax.xml.stream.XMLStreamReader;
- import org.w3c.dom.Document;
- import org.w3c.dom.DocumentType;
- import org.w3c.dom.DOMImplementation;
- import org.w3c.dom.Element;
- import org.w3c.dom.bootstrap.DOMImplementationRegistry;
- import org.w3c.dom.ls.DOMImplementationLS;
- import org.w3c.dom.ls.LSOutput;
- import org.w3c.dom.ls.LSSerializer;
- /**
- * A set of persistent properties, which can be saved or loaded from a stream.
- * A property list may also contain defaults, searched if the main list
- * does not contain a property for a given key.
- *
- * An example of a properties file for the german language is given
- * here. This extends the example given in ListResourceBundle.
- * Create a file MyResource_de.properties with the following contents
- * and put it in the CLASSPATH. (The character
- * <code>\</code><code>u00e4</code> is the german umlaut)
- *
- *
- <pre>s1=3
- s2=MeineDisk
- s3=3. M\<code></code>u00e4rz 96
- s4=Die Diskette ''{1}'' enth\<code></code>u00e4lt {0} in {2}.
- s5=0
- s6=keine Dateien
- s7=1
- s8=eine Datei
- s9=2
- s10={0,number} Dateien
- s11=Das Formatieren schlug fehl mit folgender Exception: {0}
- s12=FEHLER
- s13=Ergebnis
- s14=Dialog
- s15=Auswahlkriterium
- s16=1,3</pre>
- *
- * <p>Although this is a sub class of a hash table, you should never
- * insert anything other than strings to this property, or several
- * methods, that need string keys and values, will fail. To ensure
- * this, you should use the <code>get/setProperty</code> method instead
- * of <code>get/put</code>.
- *
- * Properties are saved in ISO 8859-1 encoding, using Unicode escapes with
- * a single <code>u</code> for any character which cannot be represented.
- *
- * @author Jochen Hoenicke
- * @author Eric Blake (ebb9@email.byu.edu)
- * @see PropertyResourceBundle
- * @status updated to 1.4
- */
- public class Properties extends Hashtable<Object, Object>
- {
- // WARNING: Properties is a CORE class in the bootstrap cycle. See the
- // comments in vm/reference/java/lang/Runtime for implications of this fact.
- /**
- * The property list that contains default values for any keys not
- * in this property list.
- *
- * @serial the default properties
- */
- protected Properties defaults;
- /**
- * Compatible with JDK 1.0+.
- */
- private static final long serialVersionUID = 4112578634029874840L;
- /**
- * Creates a new empty property list with no default values.
- */
- public Properties()
- {
- }
- /**
- * Create a new empty property list with the specified default values.
- *
- * @param defaults a Properties object containing the default values
- */
- public Properties(Properties defaults)
- {
- this.defaults = defaults;
- }
- /**
- * Adds the given key/value pair to this properties. This calls
- * the hashtable method put.
- *
- * @param key the key for this property
- * @param value the value for this property
- * @return The old value for the given key
- * @see #getProperty(String)
- * @since 1.2
- */
- public Object setProperty(String key, String value)
- {
- return put(key, value);
- }
- /**
- * Reads a property list from a character stream. The stream should
- * have the following format: <br>
- *
- * An empty line or a line starting with <code>#</code> or
- * <code>!</code> is ignored. An backslash (<code>\</code>) at the
- * end of the line makes the line continueing on the next line
- * (but make sure there is no whitespace after the backslash).
- * Otherwise, each line describes a key/value pair. <br>
- *
- * The chars up to the first whitespace, = or : are the key. You
- * can include this caracters in the key, if you precede them with
- * a backslash (<code>\</code>). The key is followed by optional
- * whitespaces, optionally one <code>=</code> or <code>:</code>,
- * and optionally some more whitespaces. The rest of the line is
- * the resource belonging to the key. <br>
- *
- * Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a
- * space), and unicode characters with the
- * <code>\\u</code><em>xxxx</em> notation are detected, and
- * converted to the corresponding single character. <br>
- *
- *
- <pre># This is a comment
- key = value
- k\:5 \ a string starting with space and ending with newline\n
- # This is a multiline specification; note that the value contains
- # no white space.
- weekdays: Sunday,Monday,Tuesday,Wednesday,\\
- Thursday,Friday,Saturday
- # The safest way to include a space at the end of a value:
- label = Name:\\u0020</pre>
- *
- * @param inReader the input {@link java.io.Reader}.
- * @throws IOException if an error occurred when reading the input
- * @throws NullPointerException if in is null
- * @since 1.6
- */
- public void load(Reader inReader) throws IOException
- {
- BufferedReader reader = new BufferedReader(inReader);
- String line;
- while ((line = reader.readLine()) != null)
- {
- char c = 0;
- int pos = 0;
- // Leading whitespaces must be deleted first.
- while (pos < line.length()
- && Character.isWhitespace(c = line.charAt(pos)))
- pos++;
- // If empty line or begins with a comment character, skip this line.
- if ((line.length() - pos) == 0
- || line.charAt(pos) == '#' || line.charAt(pos) == '!')
- continue;
- // The characters up to the next Whitespace, ':', or '='
- // describe the key. But look for escape sequences.
- // Try to short-circuit when there is no escape char.
- int start = pos;
- boolean needsEscape = line.indexOf('\\', pos) != -1;
- CPStringBuilder key = needsEscape ? new CPStringBuilder() : null;
- while (pos < line.length()
- && ! Character.isWhitespace(c = line.charAt(pos++))
- && c != '=' && c != ':')
- {
- if (needsEscape && c == '\\')
- {
- if (pos == line.length())
- {
- // The line continues on the next line. If there
- // is no next line, just treat it as a key with an
- // empty value.
- line = reader.readLine();
- if (line == null)
- line = "";
- pos = 0;
- while (pos < line.length()
- && Character.isWhitespace(c = line.charAt(pos)))
- pos++;
- }
- else
- {
- c = line.charAt(pos++);
- switch (c)
- {
- case 'n':
- key.append('\n');
- break;
- case 't':
- key.append('\t');
- break;
- case 'r':
- key.append('\r');
- break;
- case 'u':
- if (pos + 4 <= line.length())
- {
- char uni = (char) Integer.parseInt
- (line.substring(pos, pos + 4), 16);
- key.append(uni);
- pos += 4;
- } // else throw exception?
- break;
- default:
- key.append(c);
- break;
- }
- }
- }
- else if (needsEscape)
- key.append(c);
- }
- boolean isDelim = (c == ':' || c == '=');
- String keyString;
- if (needsEscape)
- keyString = key.toString();
- else if (isDelim || Character.isWhitespace(c))
- keyString = line.substring(start, pos - 1);
- else
- keyString = line.substring(start, pos);
- while (pos < line.length()
- && Character.isWhitespace(c = line.charAt(pos)))
- pos++;
- if (! isDelim && (c == ':' || c == '='))
- {
- pos++;
- while (pos < line.length()
- && Character.isWhitespace(c = line.charAt(pos)))
- pos++;
- }
- // Short-circuit if no escape chars found.
- if (!needsEscape)
- {
- put(keyString, line.substring(pos));
- continue;
- }
- // Escape char found so iterate through the rest of the line.
- StringBuilder element = new StringBuilder(line.length() - pos);
- while (pos < line.length())
- {
- c = line.charAt(pos++);
- if (c == '\\')
- {
- if (pos == line.length())
- {
- // The line continues on the next line.
- line = reader.readLine();
- // We might have seen a backslash at the end of
- // the file. The JDK ignores the backslash in
- // this case, so we follow for compatibility.
- if (line == null)
- break;
- pos = 0;
- while (pos < line.length()
- && Character.isWhitespace(c = line.charAt(pos)))
- pos++;
- element.ensureCapacity(line.length() - pos +
- element.length());
- }
- else
- {
- c = line.charAt(pos++);
- switch (c)
- {
- case 'n':
- element.append('\n');
- break;
- case 't':
- element.append('\t');
- break;
- case 'r':
- element.append('\r');
- break;
- case 'u':
- if (pos + 4 <= line.length())
- {
- char uni = (char) Integer.parseInt
- (line.substring(pos, pos + 4), 16);
- element.append(uni);
- pos += 4;
- } // else throw exception?
- break;
- default:
- element.append(c);
- break;
- }
- }
- }
- else
- element.append(c);
- }
- put(keyString, element.toString());
- }
- }
- /**
- * Reads a property list from the supplied input stream.
- * This method has the same functionality as {@link #load(Reader)}
- * but the character encoding is assumed to be ISO-8859-1.
- * Unicode characters not within the Latin1 set supplied by
- * ISO-8859-1 should be escaped using '\\uXXXX' where XXXX
- * is the UTF-16 code unit in hexadecimal.
- *
- * @param inStream the byte stream to read the property list from.
- * @throws IOException if an I/O error occurs.
- * @see #load(Reader)
- * @since 1.2
- */
- public void load(InputStream inStream) throws IOException
- {
- load(new InputStreamReader(inStream, "ISO-8859-1"));
- }
- /**
- * Calls <code>store(OutputStream out, String header)</code> and
- * ignores the IOException that may be thrown.
- *
- * @param out the stream to write to
- * @param header a description of the property list
- * @throws ClassCastException if this property contains any key or
- * value that are not strings
- * @deprecated use {@link #store(OutputStream, String)} instead
- */
- @Deprecated
- public void save(OutputStream out, String header)
- {
- try
- {
- store(out, header);
- }
- catch (IOException ex)
- {
- }
- }
- /**
- * Writes the key/value pairs to the given output stream, in a format
- * suitable for <code>load</code>.<br>
- *
- * If header is not null, this method writes a comment containing
- * the header as first line to the stream. The next line (or first
- * line if header is null) contains a comment with the current date.
- * Afterwards the key/value pairs are written to the stream in the
- * following format.<br>
- *
- * Each line has the form <code>key = value</code>. Newlines,
- * Returns and tabs are written as <code>\n,\t,\r</code> resp.
- * The characters <code>\, !, #, =</code> and <code>:</code> are
- * preceeded by a backslash. Spaces are preceded with a backslash,
- * if and only if they are at the beginning of the key. Characters
- * that are not in the ascii range 33 to 127 are written in the
- * <code>\</code><code>u</code>xxxx Form.<br>
- *
- * Following the listing, the output stream is flushed but left open.
- *
- * @param out the output stream
- * @param header the header written in the first line, may be null
- * @throws ClassCastException if this property contains any key or
- * value that isn't a string
- * @throws IOException if writing to the stream fails
- * @throws NullPointerException if out is null
- * @since 1.2
- */
- public void store(OutputStream out, String header) throws IOException
- {
- // The spec says that the file must be encoded using ISO-8859-1.
- PrintWriter writer
- = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1"));
- if (header != null)
- writer.println("#" + header);
- writer.println ("#" + Calendar.getInstance ().getTime ());
- Iterator iter = entrySet ().iterator ();
- int i = size ();
- CPStringBuilder s = new CPStringBuilder (); // Reuse the same buffer.
- while (--i >= 0)
- {
- Map.Entry entry = (Map.Entry) iter.next ();
- formatForOutput ((String) entry.getKey (), s, true);
- s.append ('=');
- formatForOutput ((String) entry.getValue (), s, false);
- writer.println (s);
- }
- writer.flush ();
- }
- /**
- * Gets the property with the specified key in this property list.
- * If the key is not found, the default property list is searched.
- * If the property is not found in the default, null is returned.
- *
- * @param key The key for this property
- * @return the value for the given key, or null if not found
- * @throws ClassCastException if this property contains any key or
- * value that isn't a string
- * @see #defaults
- * @see #setProperty(String, String)
- * @see #getProperty(String, String)
- */
- public String getProperty(String key)
- {
- Properties prop = this;
- // Eliminate tail recursion.
- do
- {
- String value = (String) prop.get(key);
- if (value != null)
- return value;
- prop = prop.defaults;
- }
- while (prop != null);
- return null;
- }
- /**
- * Gets the property with the specified key in this property list. If
- * the key is not found, the default property list is searched. If the
- * property is not found in the default, the specified defaultValue is
- * returned.
- *
- * @param key The key for this property
- * @param defaultValue A default value
- * @return The value for the given key
- * @throws ClassCastException if this property contains any key or
- * value that isn't a string
- * @see #defaults
- * @see #setProperty(String, String)
- */
- public String getProperty(String key, String defaultValue)
- {
- String prop = getProperty(key);
- if (prop == null)
- prop = defaultValue;
- return prop;
- }
- /**
- * Returns an enumeration of all keys in this property list, including
- * the keys in the default property list.
- *
- * @return an Enumeration of all defined keys
- */
- public Enumeration<?> propertyNames()
- {
- // We make a new Set that holds all the keys, then return an enumeration
- // for that. This prevents modifications from ruining the enumeration,
- // as well as ignoring duplicates.
- Properties prop = this;
- Set s = new HashSet();
- // Eliminate tail recursion.
- do
- {
- s.addAll(prop.keySet());
- prop = prop.defaults;
- }
- while (prop != null);
- return Collections.enumeration(s);
- }
- /**
- * Prints the key/value pairs to the given print stream. This is
- * mainly useful for debugging purposes.
- *
- * @param out the print stream, where the key/value pairs are written to
- * @throws ClassCastException if this property contains a key or a
- * value that isn't a string
- * @see #list(PrintWriter)
- */
- public void list(PrintStream out)
- {
- PrintWriter writer = new PrintWriter (out);
- list (writer);
- }
- /**
- * Prints the key/value pairs to the given print writer. This is
- * mainly useful for debugging purposes.
- *
- * @param out the print writer where the key/value pairs are written to
- * @throws ClassCastException if this property contains a key or a
- * value that isn't a string
- * @see #list(PrintStream)
- * @since 1.1
- */
- public void list(PrintWriter out)
- {
- out.println ("-- listing properties --");
- Iterator iter = entrySet ().iterator ();
- int i = size ();
- while (--i >= 0)
- {
- Map.Entry entry = (Map.Entry) iter.next ();
- out.print ((String) entry.getKey () + "=");
- // JDK 1.3/1.4 restrict the printed value, but not the key,
- // to 40 characters, including the truncating ellipsis.
- String s = (String ) entry.getValue ();
- if (s != null && s.length () > 40)
- out.println (s.substring (0, 37) + "...");
- else
- out.println (s);
- }
- out.flush ();
- }
- /**
- * Formats a key or value for output in a properties file.
- * See store for a description of the format.
- *
- * @param str the string to format
- * @param buffer the buffer to add it to
- * @param key true if all ' ' must be escaped for the key, false if only
- * leading spaces must be escaped for the value
- * @see #store(OutputStream, String)
- */
- private void formatForOutput(String str, CPStringBuilder buffer, boolean key)
- {
- if (key)
- {
- buffer.setLength(0);
- buffer.ensureCapacity(str.length());
- }
- else
- buffer.ensureCapacity(buffer.length() + str.length());
- boolean head = true;
- int size = str.length();
- for (int i = 0; i < size; i++)
- {
- char c = str.charAt(i);
- switch (c)
- {
- case '\n':
- buffer.append("\\n");
- break;
- case '\r':
- buffer.append("\\r");
- break;
- case '\t':
- buffer.append("\\t");
- break;
- case ' ':
- buffer.append(head ? "\\ " : " ");
- break;
- case '\\':
- case '!':
- case '#':
- case '=':
- case ':':
- buffer.append('\\').append(c);
- break;
- default:
- if (c < ' ' || c > '~')
- {
- String hex = Integer.toHexString(c);
- buffer.append("\\u0000".substring(0, 6 - hex.length()));
- buffer.append(hex);
- }
- else
- buffer.append(c);
- }
- if (c != ' ')
- head = key;
- }
- }
- /**
- * <p>
- * Encodes the properties as an XML file using the UTF-8 encoding.
- * The format of the XML file matches the DTD
- * <a href="http://java.sun.com/dtd/properties.dtd">
- * http://java.sun.com/dtd/properties.dtd</a>.
- * </p>
- * <p>
- * Invoking this method provides the same behaviour as invoking
- * <code>storeToXML(os, comment, "UTF-8")</code>.
- * </p>
- *
- * @param os the stream to output to.
- * @param comment a comment to include at the top of the XML file, or
- * <code>null</code> if one is not required.
- * @throws IOException if the serialization fails.
- * @throws NullPointerException if <code>os</code> is null.
- * @since 1.5
- */
- public void storeToXML(OutputStream os, String comment)
- throws IOException
- {
- storeToXML(os, comment, "UTF-8");
- }
- /**
- * <p>
- * Encodes the properties as an XML file using the supplied encoding.
- * The format of the XML file matches the DTD
- * <a href="http://java.sun.com/dtd/properties.dtd">
- * http://java.sun.com/dtd/properties.dtd</a>.
- * </p>
- *
- * @param os the stream to output to.
- * @param comment a comment to include at the top of the XML file, or
- * <code>null</code> if one is not required.
- * @param encoding the encoding to use for the XML output.
- * @throws IOException if the serialization fails.
- * @throws NullPointerException if <code>os</code> or <code>encoding</code>
- * is null.
- * @since 1.5
- */
- public void storeToXML(OutputStream os, String comment, String encoding)
- throws IOException
- {
- if (os == null)
- throw new NullPointerException("Null output stream supplied.");
- if (encoding == null)
- throw new NullPointerException("Null encoding supplied.");
- try
- {
- DOMImplementationRegistry registry =
- DOMImplementationRegistry.newInstance();
- DOMImplementation domImpl = registry.getDOMImplementation("LS 3.0");
- DocumentType doctype =
- domImpl.createDocumentType("properties", null,
- "http://java.sun.com/dtd/properties.dtd");
- Document doc = domImpl.createDocument(null, "properties", doctype);
- Element root = doc.getDocumentElement();
- if (comment != null)
- {
- Element commentElement = doc.createElement("comment");
- commentElement.appendChild(doc.createTextNode(comment));
- root.appendChild(commentElement);
- }
- Iterator iterator = entrySet().iterator();
- while (iterator.hasNext())
- {
- Map.Entry entry = (Map.Entry) iterator.next();
- Element entryElement = doc.createElement("entry");
- entryElement.setAttribute("key", (String) entry.getKey());
- entryElement.appendChild(doc.createTextNode((String)
- entry.getValue()));
- root.appendChild(entryElement);
- }
- DOMImplementationLS loadAndSave = (DOMImplementationLS) domImpl;
- LSSerializer serializer = loadAndSave.createLSSerializer();
- LSOutput output = loadAndSave.createLSOutput();
- output.setByteStream(os);
- output.setEncoding(encoding);
- serializer.write(doc, output);
- }
- catch (ClassNotFoundException e)
- {
- throw (IOException)
- new IOException("The XML classes could not be found.").initCause(e);
- }
- catch (InstantiationException e)
- {
- throw (IOException)
- new IOException("The XML classes could not be instantiated.")
- .initCause(e);
- }
- catch (IllegalAccessException e)
- {
- throw (IOException)
- new IOException("The XML classes could not be accessed.")
- .initCause(e);
- }
- }
- /**
- * <p>
- * Decodes the contents of the supplied <code>InputStream</code> as
- * an XML file, which represents a set of properties. The format of
- * the XML file must match the DTD
- * <a href="http://java.sun.com/dtd/properties.dtd">
- * http://java.sun.com/dtd/properties.dtd</a>.
- * </p>
- *
- * @param in the input stream from which to receive the XML data.
- * @throws IOException if an I/O error occurs in reading the input data.
- * @throws InvalidPropertiesFormatException if the input data does not
- * constitute an XML properties
- * file.
- * @throws NullPointerException if <code>in</code> is null.
- * @since 1.5
- */
- public void loadFromXML(InputStream in)
- throws IOException, InvalidPropertiesFormatException
- {
- if (in == null)
- throw new NullPointerException("Null input stream supplied.");
- try
- {
- XMLInputFactory factory = XMLInputFactory.newInstance();
- // Don't resolve external entity references
- factory.setProperty("javax.xml.stream.isSupportingExternalEntities",
- Boolean.FALSE);
- XMLStreamReader reader = factory.createXMLStreamReader(in);
- String name, key = null;
- CPStringBuilder buf = null;
- while (reader.hasNext())
- {
- switch (reader.next())
- {
- case XMLStreamConstants.START_ELEMENT:
- name = reader.getLocalName();
- if (buf == null && "entry".equals(name))
- {
- key = reader.getAttributeValue(null, "key");
- if (key == null)
- {
- String msg = "missing 'key' attribute";
- throw new InvalidPropertiesFormatException(msg);
- }
- buf = new CPStringBuilder();
- }
- else if (!"properties".equals(name) && !"comment".equals(name))
- {
- String msg = "unexpected element name '" + name + "'";
- throw new InvalidPropertiesFormatException(msg);
- }
- break;
- case XMLStreamConstants.END_ELEMENT:
- name = reader.getLocalName();
- if (buf != null && "entry".equals(name))
- {
- put(key, buf.toString());
- buf = null;
- }
- else if (!"properties".equals(name) && !"comment".equals(name))
- {
- String msg = "unexpected element name '" + name + "'";
- throw new InvalidPropertiesFormatException(msg);
- }
- break;
- case XMLStreamConstants.CHARACTERS:
- case XMLStreamConstants.SPACE:
- case XMLStreamConstants.CDATA:
- if (buf != null)
- buf.append(reader.getText());
- break;
- }
- }
- reader.close();
- }
- catch (XMLStreamException e)
- {
- throw (InvalidPropertiesFormatException)
- new InvalidPropertiesFormatException("Error in parsing XML.").
- initCause(e);
- }
- }
- } // class Properties
|