summaryrefslogtreecommitdiff
path: root/java/util/Properties.java
diff options
context:
space:
mode:
authorAaron M. Renn <arenn@urbanophile.com>1998-12-13 04:43:45 +0000
committerAaron M. Renn <arenn@urbanophile.com>1998-12-13 04:43:45 +0000
commit2fe7dde85c530d48b60fc4b9a32110e7330839f1 (patch)
tree596845e6f10ff05e877f9a4b98a6bc5fd1b46dd7 /java/util/Properties.java
parentfa91f0ef97c914b0cf40f447c49041542676760f (diff)
downloadclasspath-2fe7dde85c530d48b60fc4b9a32110e7330839f1.tar.gz
Initial Checkin
Diffstat (limited to 'java/util/Properties.java')
-rw-r--r--java/util/Properties.java430
1 files changed, 430 insertions, 0 deletions
diff --git a/java/util/Properties.java b/java/util/Properties.java
new file mode 100644
index 000000000..b0b3bd7c6
--- /dev/null
+++ b/java/util/Properties.java
@@ -0,0 +1,430 @@
+/*
+ * java.util.PropertyResourceBundle: part of the Java Class Libraries project.
+ * Copyright (C) 1998 Jochen Hoenicke
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+package java.util;
+import java.io.*;
+
+/**
+ * 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 char <code>\u00e4<char> is the
+ * german &auml;)
+ *
+ * <pre>
+ * s1=3
+ * s2=MeineDisk
+ * s3=3. M\u00e4rz 96
+ * s4=Die Diskette ''{1}'' enth\u00e4lt {0} in {2}.
+ * s5=0
+ * s6=keine Dateien
+ * s7=1
+ * s8=eine Datei
+ * s9=2
+ * s10={0,number} Dateien
+ * s11=Die Formatierung warf eine Exception: {0}
+ * s12=FEHLER
+ * s13=Ergebnis
+ * s14=Dialog
+ * s15=Auswahlkriterium
+ * s16=1,3
+ * </pre>
+ *
+ * @see PropertyResourceBundle
+ * @author Jochen Hoenicke
+ */
+public class Properties extends Hashtable {
+ /**
+ * The property list that contains default values for any keys not
+ * in this property list.
+ */
+ private Properties defaults;
+
+ /**
+ * Creates a new empty property list.
+ */
+ public Properties() {
+ this.defaults = null;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Reads a property list from an input stream. The stream should
+ * have the following format:
+ *
+ * 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.
+ * Otherwise, each line describes a key/value pair.
+ *
+ * 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.
+ *
+ * Escape sequences <code>\t, \n, \r, \\, \", \', \ <code>(a
+ * space), and unicode characters with the
+ * <code>\</code><code>u</code>xxxx notation are detected, and
+ * converted to the corresponding single character.
+ *
+ * XXX - examples
+ *
+ * @param in the input stream
+ * @throws IOException if an error occured when reading
+ * from the input. */
+ public void load(InputStream inStream) throws IOException {
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(inStream));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ char c = 0;
+ int pos = 0;
+ while (pos < line.length()
+ && Character.isWhitespace(c = line.charAt(pos)))
+ pos++;
+
+ // If line is empty or begins with a comment character,
+ // skip this line.
+ if (pos == line.length() || c == '#' || c == '!')
+ continue;
+
+ // The characaters up to the next Whitespace, ':', or '='
+ // describe the key. But look for escape sequences.
+ StringBuffer key = new StringBuffer();
+ while (pos < line.length()
+ && !Character.isWhitespace(c = line.charAt(pos++))
+ && c != '=' && c != ':') {
+ if (c == '\\') {
+ if (pos == line.length()) {
+ // The line continues on the next line.
+ line = reader.readLine();
+ 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 '\\':
+ key.append('\\');
+ break;
+ case '"':
+ key.append('\"');
+ break;
+ case '\'':
+ key.append('\'');
+ break;
+ case ':':
+ key.append(':');
+ break;
+ case '=':
+ key.append('=');
+ break;
+ case ' ':
+ key.append(' ');
+ break;
+ case 'u':
+ if (pos+4 <= line.length()) {
+ char uni = (char) Integer.parseInt
+ (line.substring(pos, pos+4), 16);
+ key.append(uni);
+ } // else throw exception?
+ break;
+ }
+ }
+ } else
+ key.append(c);
+ }
+
+ boolean isDelim = (c == ':' || c == '=');
+ 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++;
+ }
+
+ StringBuffer element = new StringBuffer();
+ while (pos < line.length()) {
+ c = line.charAt(pos++);
+ if (c == '\\') {
+ if (pos == line.length()) {
+ // The line continues on the next line.
+ line = reader.readLine();
+ pos = 0;
+ while (pos < line.length()
+ && Character.isWhitespace(c = line.charAt(pos)))
+ pos++;
+ } 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 '\\':
+ element.append('\\');
+ break;
+ case '"':
+ element.append('\"');
+ break;
+ case '\'':
+ element.append('\'');
+ break;
+ case ':':
+ element.append(':');
+ break;
+ case '=':
+ element.append('=');
+ break;
+ case ' ':
+ element.append(' ');
+ break;
+ case 'u':
+ if (pos+4 <= line.length()) {
+ char uni = (char) Integer.parseInt
+ (line.substring(pos, pos+4), 16);
+ element.append(uni);
+ } // else throw exception?
+ break;
+ }
+ }
+ } else
+ element.append(c);
+ }
+
+ put(key.toString(), element.toString());
+ }
+ }
+
+ /**
+ * Calls <code>store(OutputStream out, String header)</code> and
+ * ignores the IOException that may be thrown.
+ * @deprecated use store instead.
+ */
+ public void save(OutputStream out, String header) {
+ try {
+ store(out,header);
+ } catch (IOException ex) {
+ }
+ }
+
+ public void store(OutputStream out, String header) throws IOException {
+ PrintWriter writer = new PrintWriter(out);
+ if (header != null)
+ writer.println("#"+header);
+ writer.println("#"+new Date().toString());
+ list(writer);
+ }
+
+ /**
+ * 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.
+ * @since JDK1.2 */
+ public Object setProperty(String key, String value) {
+ return put(key,value);
+ }
+
+ /**
+ * 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 default or the default of
+ * default, null is returned.
+ * @param key The key for this property.
+ * @param defaulValue A default value
+ * @return The value for the given key, or null if not found. */
+ public String getProperty(String key) {
+ return getProperty(key, 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 default or the default of default, the
+ * specified defaultValue is returned.
+ * @param key The key for this property.
+ * @param defaulValue A default value
+ * @return The value for the given key.
+ */
+ public String getProperty(String key, String defaultValue) {
+ Properties prop = this;
+ // Eliminate tail recursion.
+ do {
+ String value = (String) get(key);
+ if (value != null)
+ return value;
+ prop = defaults;
+ } while (prop != null);
+ return defaultValue;
+ }
+
+ /**
+ * Returns an enumeration of all keys in this property list, including
+ * the keys in the default property list.
+ */
+ public Enumeration propertyNames() {
+ return (defaults == null) ? keys()
+ : new DoubleEnumeration(keys(), defaults.propertyNames());
+ }
+
+ /**
+ * Formats a key/value pair for output in a properties file.
+ * See store for a description of the format.
+ * @param key the key.
+ * @param value the value.
+ */
+ private String formatForOutput(String key, String value) {
+ StringBuffer result = new StringBuffer();
+ boolean head = true;
+ for (int i=0; i< key.length(); i++) {
+ char c = key.charAt(i);
+ switch (c) {
+ case '\n':
+ result.append("\\n");
+ break;
+ case '\r':
+ result.append("\\r");
+ break;
+ case '\t':
+ result.append("\\t");
+ break;
+ case '\\':
+ result.append("\\\\");
+ break;
+ case '!':
+ result.append("\\!");
+ break;
+ case '#':
+ result.append("\\#");
+ break;
+ case '=':
+ result.append("\\=");
+ break;
+ case ':':
+ result.append("\\:");
+ break;
+ default:
+ if (c < 32 || c > '~') {
+ String hex = Integer.toHexString(c);
+ result.append("\\u0000".substring(0, 6-hex.length()));
+ result.append(hex);
+ } else if (c == 32 && head)
+ result.append("\\ ");
+ else
+ result.append(c);
+ }
+ if (c != 32)
+ head = false;
+ }
+ result.append('=');
+ head=true;
+ for (int i=0; i< value.length(); i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '\n':
+ result.append("\\n");
+ break;
+ case '\r':
+ result.append("\\r");
+ break;
+ case '\t':
+ result.append("\\t");
+ break;
+ case '\\':
+ result.append("\\\\");
+ break;
+ case '!':
+ result.append("\\!");
+ break;
+ case '#':
+ result.append("\\#");
+ break;
+ default:
+ if (c < 32 || c > '~') {
+ String hex = Integer.toHexString(c);
+ result.append("\\u0000".substring(0, 6-hex.length()));
+ result.append(hex);
+ } else if (c == 32 && head)
+ result.append("\\ ");
+ else
+ result.append(c);
+ }
+ if (c != 32)
+ head = false;
+ }
+ return result.toString();
+ }
+
+ public void list(PrintStream out) {
+ Enumeration keys = keys();
+ Enumeration elts = elements();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String elt = (String) elts.nextElement();
+ String output = formatForOutput(key,elt);
+ out.println(output);
+ }
+ }
+
+ /**
+ *
+ * @since JDK1.1
+ */
+ public void list(PrintWriter out) {
+ Enumeration keys = keys();
+ Enumeration elts = elements();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ String elt = (String) elts.nextElement();
+ String output = formatForOutput(key,elt);
+ out.println(output);
+ }
+ }
+}