Properties.java revision 1593
0N/A * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Sun designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Sun in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A * The <code>Properties</code> class represents a persistent set of 0N/A * properties. The <code>Properties</code> can be saved to a stream 0N/A * or loaded from a stream. Each key and its corresponding value in 0N/A * the property list is a string. 0N/A * A property list can contain another property list as its 0N/A * "defaults"; this second property list is searched if 0N/A * the property key is not found in the original property list. 0N/A * Because <code>Properties</code> inherits from <code>Hashtable</code>, the 0N/A * <code>put</code> and <code>putAll</code> methods can be applied to a 0N/A * <code>Properties</code> object. Their use is strongly discouraged as they 0N/A * allow the caller to insert entries whose keys or values are not 0N/A * <code>Strings</code>. The <code>setProperty</code> method should be used 0N/A * instead. If the <code>store</code> or <code>save</code> method is called 0N/A * on a "compromised" <code>Properties</code> object that contains a 0N/A * non-<code>String</code> key or value, the call will fail. Similarly, 0N/A * the call to the <code>propertyNames</code> or <code>list</code> method 0N/A * will fail if it is called on a "compromised" <code>Properties</code> 0N/A * object that contains a non-<code>String</code> key. 0N/A * The {@link #load(java.io.Reader) load(Reader)} <tt>/</tt> 0N/A * {@link #store(java.io.Writer, java.lang.String) store(Writer, String)} 0N/A * methods load and store properties from and to a character based stream 0N/A * in a simple line-oriented format specified below. 0N/A * The {@link #load(java.io.InputStream) load(InputStream)} <tt>/</tt> 0N/A * {@link #store(java.io.OutputStream, java.lang.String) store(OutputStream, String)} 0N/A * methods work the same way as the load(Reader)/store(Writer, String) pair, except 0N/A * the input/output stream is encoded in ISO 8859-1 character encoding. 0N/A * Characters that cannot be directly represented in this encoding can be written using 0N/A * ; only a single 'u' character is allowed in an escape 0N/A * sequence. The native2ascii tool can be used to convert property files to and 0N/A * from other character encodings. 0N/A * <p> The {@link #loadFromXML(InputStream)} and {@link 0N/A * #storeToXML(OutputStream, String, String)} methods load and store properties 0N/A * in a simple XML format. By default the UTF-8 character encoding is used, 0N/A * however a specific encoding may be specified if required. An XML properties 0N/A * document has the following DOCTYPE declaration: 0N/A * <i>not</i> accessed when exporting or importing properties; it merely 0N/A * serves as a string to uniquely identify the DTD, which is: 0N/A * <?xml version="1.0" encoding="UTF-8"?> 0N/A * <!-- DTD for properties --> 0N/A * <!ELEMENT properties ( comment?, entry* ) > 0N/A * <!ATTLIST properties version CDATA #FIXED "1.0"> 0N/A * <!ELEMENT comment (#PCDATA) > 0N/A * <!ELEMENT entry (#PCDATA) > 0N/A * <!ATTLIST entry key CDATA #REQUIRED> 1593N/A * <p>This class is thread-safe: multiple threads can share a single 1593N/A * <tt>Properties</tt> object without the need for external synchronization. 0N/A * @author Arthur van Hoff 0N/A * @author Michael McCloskey 0N/A * @author Xueming Shen 0N/A * use serialVersionUID from JDK 1.1.X for interoperability 0N/A * A property list that contains default values for any keys not 0N/A * found in this property list. 0N/A * Creates an empty property list with no default values. 0N/A * Creates an empty property list with the specified defaults. 0N/A * @param defaults the defaults. 0N/A * Calls the <tt>Hashtable</tt> method <code>put</code>. Provided for 0N/A * parallelism with the <tt>getProperty</tt> method. Enforces use of 0N/A * strings for property keys and values. The value returned is the 0N/A * result of the <tt>Hashtable</tt> call to <code>put</code>. 0N/A * @param key the key to be placed into this property list. 0N/A * @param value the value corresponding to <tt>key</tt>. 0N/A * @return the previous value of the specified key in this property 0N/A * list, or <code>null</code> if it did not have one. 0N/A * Reads a property list (key and element pairs) from the input 0N/A * character stream in a simple line-oriented format. 0N/A * Properties are processed in terms of lines. There are two 0N/A * kinds of line, <i>natural lines</i> and <i>logical lines</i>. 0N/A * A natural line is defined as a line of 0N/A * characters that is terminated either by a set of line terminator 0N/A * characters (<code>\n</code> or <code>\r</code> or <code>\r\n</code>) 0N/A * or by the end of the stream. A natural line may be either a blank line, 0N/A * a comment line, or hold all or some of a key-element pair. A logical 0N/A * line holds all the data of a key-element pair, which may be spread 0N/A * out across several adjacent natural lines by escaping 0N/A * the line terminator sequence with a backslash character 0N/A * <code>\</code>. Note that a comment line cannot be extended 0N/A * in this manner; every natural line that is a comment must have 0N/A * its own comment indicator, as described below. Lines are read from 0N/A * input until the end of the stream is reached. 0N/A * A natural line that contains only white space characters is 0N/A * considered blank and is ignored. A comment line has an ASCII 0N/A * <code>'#'</code> or <code>'!'</code> as its first non-white 0N/A * space character; comment lines are also ignored and do not 0N/A * encode key-element information. In addition to line 0N/A * terminators, this format considers the characters space 0N/A * (<code>' '</code>, <code>'\u0020'</code>), tab 0N/A * (<code>'\t'</code>, <code>'\u0009'</code>), and form feed 0N/A * (<code>'\f'</code>, <code>'\u000C'</code>) to be white 0N/A * If a logical line is spread across several natural lines, the 0N/A * backslash escaping the line terminator sequence, the line 0N/A * terminator sequence, and any white space at the start of the 0N/A * following line have no affect on the key or element values. 0N/A * The remainder of the discussion of key and element parsing 0N/A * (when loading) will assume all the characters constituting 0N/A * the key and element appear on a single natural line after 0N/A * line continuation characters have been removed. Note that 0N/A * it is <i>not</i> sufficient to only examine the character 0N/A * preceding a line terminator sequence to decide if the line 0N/A * terminator is escaped; there must be an odd number of 0N/A * contiguous backslashes for the line terminator to be escaped. 0N/A * Since the input is processed from left to right, a 0N/A * non-zero even number of 2<i>n</i> contiguous backslashes 0N/A * before a line terminator (or elsewhere) encodes <i>n</i> 0N/A * backslashes after escape processing. 0N/A * The key contains all of the characters in the line starting 0N/A * with the first non-white space character and up to, but not 0N/A * including, the first unescaped <code>'='</code>, 0N/A * <code>':'</code>, or white space character other than a line 0N/A * terminator. All of these key termination characters may be 0N/A * included in the key by escaping them with a preceding backslash 0N/A * character; for example,<p> 0N/A * <code>\:\=</code><p> 0N/A * would be the two-character key <code>":="</code>. Line 0N/A * terminator characters can be included using <code>\r</code> and 0N/A * <code>\n</code> escape sequences. Any white space after the 0N/A * key is skipped; if the first non-white space character after 0N/A * the key is <code>'='</code> or <code>':'</code>, then it is 0N/A * ignored and any white space characters after it are also 0N/A * skipped. All remaining characters on the line become part of 0N/A * the associated element string; if there are no remaining 0N/A * characters, the element is the empty string 0N/A * <code>""</code>. Once the raw character sequences 0N/A * constituting the key and element are identified, escape 0N/A * processing is performed as described above. 0N/A * As an example, each of the following three lines specifies the key 0N/A * <code>"Truth"</code> and the associated element value 0N/A * <code>"Beauty"</code>: 0N/A * As another example, the following three lines specify a single 0N/A * fruits apple, banana, pear, \ 0N/A * cantaloupe, watermelon, \ 0N/A * The key is <code>"fruits"</code> and the associated element is: 0N/A * <pre>"apple, banana, pear, cantaloupe, watermelon, kiwi, mango"</pre> 0N/A * Note that a space appears before each <code>\</code> so that a space 0N/A * will appear after each comma in the final result; the <code>\</code>, 0N/A * line terminator, and leading white space on the continuation line are 0N/A * merely discarded and are <i>not</i> replaced by one or more other 0N/A * As a third example, the line: 0N/A * specifies that the key is <code>"cheeses"</code> and the associated 0N/A * element is the empty string <code>""</code>.<p> 0N/A * <a name="unicodeescapes"></a> 0N/A * Characters in keys and elements can be represented in escape 0N/A * sequences similar to those used for character and string literals 0N/A * of the <i>Java Language Specification</i>). 0N/A * The differences from the character escape sequences and Unicode 0N/A * escapes used for characters and strings are: 0N/A * <li> Octal escapes are not recognized. 0N/A * <li> The character sequence <code>\b</code> does <i>not</i> 0N/A * represent a backspace character. 0N/A * <li> The method does not treat a backslash character, 0N/A * <code>\</code>, before a non-valid escape character as an 0N/A * error; the backslash is silently dropped. For example, in a 0N/A * Java string the sequence <code>"\z"</code> would cause a 0N/A * compile time error. In contrast, this method silently drops 0N/A * the backslash. Therefore, this method treats the two character 0N/A * sequence <code>"\b"</code> as equivalent to the single 0N/A * character <code>'b'</code>. 0N/A * <li> Escapes are not necessary for single and double quotes; 0N/A * however, by the rule above, single and double quote characters 0N/A * preceded by a backslash still yield single and double quote 0N/A * characters, respectively. 0N/A * <li> Only a single 'u' character is allowed in a Uniocde escape 0N/A * The specified stream remains open after this method returns. 0N/A * @param reader the input character stream. 0N/A * @throws IOException if an error occurred when reading from the 0N/A * @throws IllegalArgumentException if a malformed Unicode escape 0N/A * appears in the input. 0N/A * Reads a property list (key and element pairs) from the input 0N/A * byte stream. The input stream is in a simple line-oriented 0N/A * format as specified in 0N/A * {@link #load(java.io.Reader) load(Reader)} and is assumed to use 0N/A * the ISO 8859-1 character encoding; that is each byte is one Latin1 0N/A * character. Characters not in Latin1, and certain special characters, 0N/A * are represented in keys and elements using 0N/A * The specified stream remains open after this method returns. 0N/A * @param inStream the input stream. 0N/A * @exception IOException if an error occurred when reading from the 0N/A * @throws IllegalArgumentException if the input stream contains a 0N/A * malformed Unicode escape sequence. 0N/A //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">"); 0N/A //need check if escaped. 0N/A if (c !=
' ' && c !=
'\t' && c !=
'\f') {
0N/A * and blank lines and filter out those leading whitespace characters 0N/A * (\u0020, \u0009 and \u000c) from the beginning of a "natural line". 0N/A * Method returns the char length of the "logical line" and stores 0N/A * the line in "lineBuf". 0N/A //The line below is equivalent to calling a 0N/A //ISO8859-1 decoder. 0N/A if (c ==
' ' || c ==
'\t' || c ==
'\f') {
0N/A if (c ==
'#' || c ==
'!') {
0N/A if (c !=
'\n' && c !=
'\r') {
0N/A //flip the preceding backslash flag 0N/A //skip the leading whitespace characters in following line 0N/A * Converts encoded \uxxxx to unicode chars 0N/A * and changes special saved chars to their original forms 0N/A for (
int i=
0; i<
4; i++) {
0N/A case '0':
case '1':
case '2':
case '3':
case '4':
0N/A case '5':
case '6':
case '7':
case '8':
case '9':
0N/A case 'a':
case 'b':
case 'c':
0N/A case 'd':
case 'e':
case 'f':
0N/A case 'A':
case 'B':
case 'C':
0N/A case 'D':
case 'E':
case 'F':
0N/A "Malformed \\uxxxx encoding.");
0N/A * Converts unicodes to encoded \uxxxx and escapes 0N/A * special characters with a preceding slash 0N/A // Handle common case first, selecting largest block that 0N/A // avoids the specials below 0N/A case '=':
// Fall through 0N/A case ':':
// Fall through 0N/A case '#':
// Fall through 0N/A if (c >
'\u00ff' || c ==
'\n' || c ==
'\r') {
0N/A * Calls the <code>store(OutputStream out, String comments)</code> method 0N/A * and suppresses IOExceptions that were thrown. 0N/A * @deprecated This method does not throw an IOException if an I/O error 0N/A * occurs while saving the property list. The preferred way to save a 0N/A * properties list is via the <code>store(OutputStream out, 0N/A * String comments)</code> method or the 0N/A * <code>storeToXML(OutputStream os, String comment)</code> method. 0N/A * @param out an output stream. 0N/A * @param comments a description of the property list. 0N/A * @exception ClassCastException if this <code>Properties</code> object 0N/A * contains any keys or values that are not 0N/A * <code>Strings</code>. 0N/A * Writes this property list (key and element pairs) in this 0N/A * <code>Properties</code> table to the output character stream in a 0N/A * format suitable for using the {@link #load(java.io.Reader) load(Reader)} 0N/A * Properties from the defaults table of this <code>Properties</code> 0N/A * table (if any) are <i>not</i> written out by this method. 0N/A * If the comments argument is not null, then an ASCII <code>#</code> 0N/A * character, the comments string, and a line separator are first written 0N/A * to the output stream. Thus, the <code>comments</code> can serve as an 0N/A * identifying comment. Any one of a line feed ('\n'), a carriage 0N/A * return ('\r'), or a carriage return followed immediately by a line feed 0N/A * in comments is replaced by a line separator generated by the <code>Writer</code> 0N/A * and if the next character in comments is not character <code>#</code> or 0N/A * character <code>!</code> then an ASCII <code>#</code> is written out 0N/A * after that line separator. 0N/A * Next, a comment line is always written, consisting of an ASCII 0N/A * <code>#</code> character, the current date and time (as if produced 0N/A * by the <code>toString</code> method of <code>Date</code> for the 0N/A * current time), and a line separator as generated by the <code>Writer</code>. 0N/A * Then every entry in this <code>Properties</code> table is 0N/A * written out, one per line. For each entry the key string is 0N/A * written, then an ASCII <code>=</code>, then the associated 0N/A * element string. For the key, all space characters are 0N/A * written with a preceding <code>\</code> character. For the 0N/A * element, leading space characters, but not embedded or trailing 0N/A * space characters, are written with a preceding <code>\</code> 0N/A * character. The key and element characters <code>#</code>, 0N/A * <code>!</code>, <code>=</code>, and <code>:</code> are written 0N/A * with a preceding backslash to ensure that they are properly loaded. 0N/A * After the entries have been written, the output stream is flushed. 0N/A * The output stream remains open after this method returns. 0N/A * @param writer an output character stream writer. 0N/A * @param comments a description of the property list. 0N/A * @exception IOException if writing this property list to the specified 0N/A * output stream throws an <tt>IOException</tt>. 0N/A * @exception ClassCastException if this <code>Properties</code> object 0N/A * contains any keys or values that are not <code>Strings</code>. 0N/A * @exception NullPointerException if <code>writer</code> is null. 0N/A * Writes this property list (key and element pairs) in this 0N/A * <code>Properties</code> table to the output stream in a format suitable 0N/A * for loading into a <code>Properties</code> table using the 0N/A * {@link #load(InputStream) load(InputStream)} method. 0N/A * Properties from the defaults table of this <code>Properties</code> 0N/A * table (if any) are <i>not</i> written out by this method. 0N/A * This method outputs the comments, properties keys and values in 0N/A * the same format as specified in 0N/A * {@link #store(java.io.Writer, java.lang.String) store(Writer)}, 0N/A * with the following differences: 0N/A * <li>The stream is written using the ISO 8859-1 character encoding. 0N/A * <li>Characters not in Latin-1 in the comments are written as 0N/A * <code>\u</code><i>xxxx</i> for their appropriate unicode 0N/A * hexadecimal value <i>xxxx</i>. 0N/A * <li>Characters less than <code>\u0020</code> and characters greater 0N/A * than <code>\u007E</code> in property keys or values are written 0N/A * as <code>\u</code><i>xxxx</i> for the appropriate hexadecimal 0N/A * value <i>xxxx</i>. 0N/A * After the entries have been written, the output stream is flushed. 0N/A * The output stream remains open after this method returns. 0N/A * @param out an output stream. 0N/A * @param comments a description of the property list. 0N/A * @exception IOException if writing this property list to the specified 0N/A * output stream throws an <tt>IOException</tt>. 0N/A * @exception ClassCastException if this <code>Properties</code> object 0N/A * contains any keys or values that are not <code>Strings</code>. 0N/A * @exception NullPointerException if <code>out</code> is null. 0N/A synchronized (
this) {
0N/A /* No need to escape embedded and trailing spaces for value, hence 0N/A * pass false to flag. 0N/A * Loads all of the properties represented by the XML document on the 0N/A * specified input stream into this properties table. 0N/A * <p>The XML document must have the following DOCTYPE declaration: 0N/A * Furthermore, the document must satisfy the properties DTD described 0N/A * <p>The specified stream is closed after this method returns. 0N/A * @param in the input stream from which to read the XML document. 0N/A * @throws IOException if reading from the specified input stream 0N/A * results in an <tt>IOException</tt>. 0N/A * @throws InvalidPropertiesFormatException Data on input stream does not 0N/A * constitute a valid XML document with the mandated document type. 0N/A * @throws NullPointerException if <code>in</code> is null. 0N/A * @see #storeToXML(OutputStream, String, String) 0N/A * Emits an XML document representing all of the properties contained 0N/A * <p> An invocation of this method of the form <tt>props.storeToXML(os, 0N/A * comment)</tt> behaves in exactly the same way as the invocation 0N/A * <tt>props.storeToXML(os, comment, "UTF-8");</tt>. 0N/A * @param os the output stream on which to emit the XML document. 0N/A * @param comment a description of the property list, or <code>null</code> 0N/A * if no comment is desired. 0N/A * @throws IOException if writing to the specified output stream 0N/A * results in an <tt>IOException</tt>. 0N/A * @throws NullPointerException if <code>os</code> is null. 0N/A * @throws ClassCastException if this <code>Properties</code> object 0N/A * contains any keys or values that are not 0N/A * <code>Strings</code>. 0N/A * @see #loadFromXML(InputStream) 0N/A * Emits an XML document representing all of the properties contained 0N/A * in this table, using the specified encoding. 0N/A * <p>The XML document will have the following DOCTYPE declaration: 0N/A *<p>If the specified comment is <code>null</code> then no comment 0N/A * will be stored in the document. 0N/A * <p>The specified stream remains open after this method returns. 0N/A * @param os the output stream on which to emit the XML document. 0N/A * @param comment a description of the property list, or <code>null</code> 0N/A * if no comment is desired. 0N/A * @throws IOException if writing to the specified output stream 0N/A * results in an <tt>IOException</tt>. 0N/A * @throws NullPointerException if <code>os</code> is <code>null</code>, 0N/A * or if <code>encoding</code> is <code>null</code>. 0N/A * @throws ClassCastException if this <code>Properties</code> object 0N/A * contains any keys or values that are not 0N/A * <code>Strings</code>. 0N/A * @see #loadFromXML(InputStream) 0N/A * Searches for the property with the specified key in this property list. 0N/A * If the key is not found in this property list, the default property list, 0N/A * and its defaults, recursively, are then checked. The method returns 0N/A * <code>null</code> if the property is not found. 0N/A * @param key the property key. 0N/A * @return the value in this property list with the specified key value. 0N/A * Searches for the property with the specified key in this property list. 0N/A * If the key is not found in this property list, the default property list, 0N/A * and its defaults, recursively, are then checked. The method returns the 0N/A * default value argument if the property is not found. 0N/A * @param key the hashtable key. 0N/A * @param defaultValue a default value. 0N/A * @return the value in this property list with the specified key value. 0N/A * Returns an enumeration of all the keys in this property list, 0N/A * including distinct keys in the default property list if a key 0N/A * of the same name has not already been found from the main 0N/A * @return an enumeration of all the keys in this property list, including 0N/A * the keys in the default property list. 0N/A * @throws ClassCastException if any key in this property list 0N/A * @see java.util.Enumeration 0N/A * @see #stringPropertyNames 0N/A * Returns a set of keys in this property list where 0N/A * the key and its corresponding value are strings, 0N/A * including distinct keys in the default property list if a key 0N/A * of the same name has not already been found from the main 0N/A * properties list. Properties whose key or value is not 0N/A * of type <tt>String</tt> are omitted. 0N/A * The returned set is not backed by the <tt>Properties</tt> object. 0N/A * Changes to this <tt>Properties</tt> are not reflected in the set, 0N/A * @return a set of keys in this property list where 0N/A * the key and its corresponding value are strings, 0N/A * including the keys in the default property list. 0N/A * Prints this property list out to the specified output stream. 0N/A * This method is useful for debugging. 0N/A * @param out an output stream. 0N/A * @throws ClassCastException if any key in this property list 0N/A * Prints this property list out to the specified output stream. 0N/A * This method is useful for debugging. 0N/A * @param out an output stream. 0N/A * @throws ClassCastException if any key in this property list 0N/A * Rather than use an anonymous inner class to share common code, this 0N/A * method is duplicated in order to ensure that a non-1.1 compiler can 0N/A * compile this file. 0N/A * Enumerates all key/value pairs in the specified hashtable. 0N/A * @param h the hashtable 0N/A * @throws ClassCastException if any of the property keys 0N/A * is not of String type. 0N/A * Enumerates all key/value pairs in the specified hashtable 0N/A * and omits the property if the key or value is not a string. 0N/A * @param h the hashtable 0N/A * Convert a nibble to a hex character 0N/A * @param nibble the nibble to convert. 0N/A /** A table of hex digits */ 0N/A '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'