summaryrefslogtreecommitdiffstats
path: root/luni
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2010-03-31 13:59:55 -0700
committerElliott Hughes <enh@google.com>2010-03-31 13:59:55 -0700
commit565a85d06ab8bc321d39f12012468cdfb65f5cfe (patch)
tree87684fc0a1c44c223191e5c906546daf2f61419e /luni
parentda759115c60aed5f46c5dfa46016c48f0ac26057 (diff)
downloadlibcore-565a85d06ab8bc321d39f12012468cdfb65f5cfe.zip
libcore-565a85d06ab8bc321d39f12012468cdfb65f5cfe.tar.gz
libcore-565a85d06ab8bc321d39f12012468cdfb65f5cfe.tar.bz2
Add Java 6's ResourceBundle/Properties API.
I've pretty much taken the upstream ResourceBundle implementations as-is, putting back our string-to-locale conversion, removing a bit of duplication and non-free, non-spec EBCDIC support, and hard-coding the text of the MissingResourceExceptions (since harmony's changed its message catalog from ours, so I had to touch those bits of the code anyway). (Why haven't I bothered to pay much attention to the resource bundle implementations? Because I already rewrote our only code that was using them to not use them, and third-party developers should be using Android's resource system instead. There's very little chance anyone needs Java resource bundles. I paid some attention to Properties, because they're still somewhat useful.) Also remove various unused messages, and update our tests. I've mostly _not_ taken the upstream tests, because it would require a lot of work that we'll be doing anyway when we switch to using their test suite properly. I ran the jtreg tests we're able to run, and the normal-case ones (plus the stress test) seemed okay. Bug: 2497395 Change-Id: I91606df0dc1a45e6974fbb27a0d334af87254f0b
Diffstat (limited to 'luni')
-rw-r--r--luni/src/main/java/java/util/ListResourceBundle.java23
-rw-r--r--luni/src/main/java/java/util/Properties.java200
-rw-r--r--luni/src/main/java/java/util/PropertyResourceBundle.java37
-rw-r--r--luni/src/main/java/java/util/ResourceBundle.java785
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties5
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties102
-rw-r--r--luni/src/test/java/tests/api/java/util/PropertiesTest.java1057
-rw-r--r--luni/src/test/java/tests/api/java/util/ResourceBundleTest.java2
8 files changed, 1646 insertions, 565 deletions
diff --git a/luni/src/main/java/java/util/ListResourceBundle.java b/luni/src/main/java/java/util/ListResourceBundle.java
index 6206ee6..278f130 100644
--- a/luni/src/main/java/java/util/ListResourceBundle.java
+++ b/luni/src/main/java/java/util/ListResourceBundle.java
@@ -21,7 +21,7 @@ package java.util;
* {@code ListResourceBundle} is the abstract superclass of classes which provide
* resources by implementing the {@code getContents()} method to return
* the list of resources.
- *
+ *
* @see ResourceBundle
* @since 1.1
*/
@@ -36,20 +36,15 @@ public abstract class ListResourceBundle extends ResourceBundle {
}
/**
- * Returns an {@code Object} array which contains the resources of this
+ * Returns an {@code Object} array containing the resources of this
* {@code ListResourceBundle}. Each element in the array is an array of two
* elements, the first is the resource key string and the second is the
* resource.
- *
+ *
* @return a {@code Object} array containing the resources.
*/
protected abstract Object[][] getContents();
- /**
- * Returns the names of the resources contained in this {@code ListResourceBundle}.
- *
- * @return an {@code Enumeration} of the resource names.
- */
@Override
public Enumeration<String> getKeys() {
initializeTable();
@@ -131,4 +126,16 @@ public abstract class ListResourceBundle extends ResourceBundle {
}
}
}
+
+ /**
+ * Returns a set of the keys in this ResourceBundle but not in its parents.
+ *
+ * @return a set of the keys in this ResourceBundle but not in its parents.
+ * @since 1.6
+ * @hide
+ */
+ protected Set<String> handleKeySet() {
+ initializeTable();
+ return table.keySet();
+ }
}
diff --git a/luni/src/main/java/java/util/Properties.java b/luni/src/main/java/java/util/Properties.java
index ce42f9a..45bbb6f 100644
--- a/luni/src/main/java/java/util/Properties.java
+++ b/luni/src/main/java/java/util/Properties.java
@@ -17,14 +17,17 @@
package java.util;
+import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.BufferedInputStream;
+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 java.io.StringReader;
+import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
@@ -43,10 +46,8 @@ import org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
-// BEGIN android-added
import org.w3c.dom.Node;
import org.w3c.dom.Text;
-// END android-added
import org.apache.harmony.luni.internal.nls.Messages;
import org.apache.harmony.luni.util.PriviAction;
@@ -106,7 +107,7 @@ public class Properties extends Hashtable<Object, Object> {
private void dumpString(StringBuilder buffer, String string, boolean key) {
int i = 0;
if (!key && i < string.length() && string.charAt(i) == ' ') {
- buffer.append("\\ "); //$NON-NLS-1$
+ buffer.append("\\ ");
i++;
}
@@ -114,16 +115,16 @@ public class Properties extends Hashtable<Object, Object> {
char ch = string.charAt(i);
switch (ch) {
case '\t':
- buffer.append("\\t"); //$NON-NLS-1$
+ buffer.append("\\t");
break;
case '\n':
- buffer.append("\\n"); //$NON-NLS-1$
+ buffer.append("\\n");
break;
case '\f':
- buffer.append("\\f"); //$NON-NLS-1$
+ buffer.append("\\f");
break;
case '\r':
- buffer.append("\\r"); //$NON-NLS-1$
+ buffer.append("\\r");
break;
default:
if ("\\#!=:".indexOf(ch) >= 0 || (key && ch == ' ')) {
@@ -133,9 +134,9 @@ public class Properties extends Hashtable<Object, Object> {
buffer.append(ch);
} else {
String hex = Integer.toHexString(ch);
- buffer.append("\\u"); //$NON-NLS-1$
+ buffer.append("\\u");
for (int j = 0; j < 4 - hex.length(); j++) {
- buffer.append("0"); //$NON-NLS-1$
+ buffer.append("0");
}
buffer.append(hex);
}
@@ -212,7 +213,7 @@ public class Properties extends Hashtable<Object, Object> {
}
if (property.length() > 40) {
buffer.append(property.substring(0, 37));
- buffer.append("..."); //$NON-NLS-1$
+ buffer.append("...");
} else {
buffer.append(property);
}
@@ -248,7 +249,7 @@ public class Properties extends Hashtable<Object, Object> {
}
if (property.length() > 40) {
buffer.append(property.substring(0, 37));
- buffer.append("..."); //$NON-NLS-1$
+ buffer.append("...");
} else {
buffer.append(property);
}
@@ -259,33 +260,45 @@ public class Properties extends Hashtable<Object, Object> {
/**
* Loads properties from the specified {@code InputStream}. The encoding is
- * ISO8859-1. The {@code Properties} file is interpreted according to the
- * following rules:
+ * ISO8859-1.
+ * @param in the {@code InputStream}
+ * @throws IOException
+ */
+ public synchronized void load(InputStream in) throws IOException {
+ if (in == null) {
+ throw new NullPointerException();
+ }
+ load(new InputStreamReader(in, "ISO8859_1"));
+ }
+
+ /**
+ * Loads properties from the specified {@code Reader}.
+ * The properties file is interpreted according to the following rules:
* <ul>
* <li>Empty lines are ignored.</li>
* <li>Lines starting with either a "#" or a "!" are comment lines and are
* ignored.</li>
* <li>A backslash at the end of the line escapes the following newline
- * character ("\r", "\n", "\r\n"). If there's a whitespace after the
+ * character ("\r", "\n", "\r\n"). If there's whitespace after the
* backslash it will just escape that whitespace instead of concatenating
* the lines. This does not apply to comment lines.</li>
* <li>A property line consists of the key, the space between the key and
* the value, and the value. The key goes up to the first whitespace, "=" or
* ":" that is not escaped. The space between the key and the value contains
- * either one whitespace, one "=" or one ":" and any number of additional
- * whitespaces before and after that character. The value starts with the
+ * either one whitespace, one "=" or one ":" and any amount of additional
+ * whitespace before and after that character. The value starts with the
* first character after the space between the key and the value.</li>
* <li>Following escape sequences are recognized: "\ ", "\\", "\r", "\n",
* "\!", "\#", "\t", "\b", "\f", and "&#92;uXXXX" (unicode character).</li>
* </ul>
*
- * @param in
- * the {@code InputStream}.
+ * @param in the {@code Reader}
* @throws IOException
- * if error occurs during reading from the {@code InputStream}.
+ * @since 1.6
+ * @hide
*/
@SuppressWarnings("fallthrough")
- public synchronized void load(InputStream in) throws IOException {
+ public synchronized void load(Reader in) throws IOException {
if (in == null) {
throw new NullPointerException();
}
@@ -294,25 +307,14 @@ public class Properties extends Hashtable<Object, Object> {
int offset = 0, keyLength = -1, intVal;
boolean firstChar = true;
- BufferedInputStream bis = new BufferedInputStream(in);
+ BufferedReader br = new BufferedReader(in);
while (true) {
- intVal = bis.read();
+ intVal = br.read();
if (intVal == -1) {
- // if mode is UNICODE but has less than 4 hex digits, should
- // throw an IllegalArgumentException
- // luni.08=Invalid Unicode sequence: expected format \\uxxxx
- if (mode == UNICODE && count < 4) {
- throw new IllegalArgumentException(Messages.getString("luni.08")); //$NON-NLS-1$
- }
- // if mode is SLASH and no data is read, should append '\u0000'
- // to buf
- if (mode == SLASH) {
- buf[offset++] = '\u0000';
- }
break;
}
- nextChar = (char) (intVal & 0xff);
+ nextChar = (char) intVal;
if (offset == buf.length) {
char[] newBuf = new char[buf.length * 2];
@@ -327,8 +329,7 @@ public class Properties extends Hashtable<Object, Object> {
continue;
}
} else if (count <= 4) {
- // luni.09=Invalid Unicode sequence: illegal character
- throw new IllegalArgumentException(Messages.getString("luni.09")); //$NON-NLS-1$
+ throw new IllegalArgumentException("Invalid Unicode sequence: illegal character");
}
mode = NONE;
buf[offset++] = (char) unicode;
@@ -371,11 +372,10 @@ public class Properties extends Hashtable<Object, Object> {
case '!':
if (firstChar) {
while (true) {
- intVal = bis.read();
+ intVal = br.read();
if (intVal == -1) {
break;
}
- // & 0xff not required
nextChar = (char) intVal;
if (nextChar == '\r' || nextChar == '\n') {
break;
@@ -443,39 +443,67 @@ public class Properties extends Hashtable<Object, Object> {
}
buf[offset++] = nextChar;
}
+ if (mode == UNICODE && count <= 4) {
+ throw new IllegalArgumentException("Invalid Unicode sequence: expected format \\uxxxx");
+ }
if (keyLength == -1 && offset > 0) {
keyLength = offset;
}
if (keyLength >= 0) {
String temp = new String(buf, 0, offset);
- put(temp.substring(0, keyLength), temp.substring(keyLength));
+ String key = temp.substring(0, keyLength);
+ String value = temp.substring(keyLength);
+ if (mode == SLASH) {
+ value += "\u0000";
+ }
+ put(key, value);
}
}
/**
- * Returns all of the property names that this {@code Properties} object
- * contains.
- *
- * @return an {@code Enumeration} containing the names of all properties
- * that this {@code Properties} object contains.
+ * Returns all of the property names (keys) in this {@code Properties} object.
*/
public Enumeration<?> propertyNames() {
- if (defaults == null) {
- return keys();
- }
+ Hashtable<Object, Object> selected = new Hashtable<Object, Object>();
+ selectProperties(selected, false);
+ return selected.keys();
+ }
- Hashtable<Object, Object> set = new Hashtable<Object, Object>(defaults
- .size()
- + size());
- Enumeration<?> keys = defaults.propertyNames();
- while (keys.hasMoreElements()) {
- set.put(keys.nextElement(), set);
+ /**
+ * Returns those property names (keys) in this {@code Properties} object for which
+ * both key and value are strings.
+ *
+ * @return a set of keys in the property list
+ * @since 1.6
+ * @hide
+ */
+ public Set<String> stringPropertyNames() {
+ Hashtable<String, String> stringProperties = new Hashtable<String, String>();
+ selectProperties(stringProperties, true);
+ return Collections.unmodifiableSet(stringProperties.keySet());
+ }
+
+ private void selectProperties(Hashtable selectProperties, final boolean isStringOnly) {
+ if (defaults != null) {
+ defaults.selectProperties(selectProperties, isStringOnly);
}
- keys = keys();
+ Enumeration<?> keys = keys();
+ Object key, value;
while (keys.hasMoreElements()) {
- set.put(keys.nextElement(), set);
+ key = keys.nextElement();
+ if (isStringOnly) {
+ // Only select property with string key and value
+ if (key instanceof String) {
+ value = get(key);
+ if (value instanceof String) {
+ selectProperties.put(key, value);
+ }
+ }
+ } else {
+ value = get(key);
+ selectProperties.put(key, value);
+ }
}
- return set.keys();
}
/**
@@ -514,39 +542,48 @@ public class Properties extends Hashtable<Object, Object> {
return put(name, value);
}
+ /**
+ * Stores the mappings in this {@code Properties} object to {@code out},
+ * putting the specified comment at the beginning. The encoding is
+ * ISO8859-1.
+ *
+ * @param out the {@code OutputStream}
+ * @param comment an optional comment to be written, or null
+ * @throws IOException
+ * @throws ClassCastException if a key or value is not a string
+ */
+ public synchronized void store(OutputStream out, String comment) throws IOException {
+ store(new OutputStreamWriter(out, "ISO8859_1"), comment);
+ }
+
private static String lineSeparator;
/**
- * Stores the mappings in this {@code Properties} to the specified {@code
- * OutputStream}, putting the specified comment at the beginning. The output
- * from this method is suitable for being read by the
- * {@link #load(InputStream)} method.
- *
- * @param out the {@code OutputStream} to write to.
- * @param comment the comment to put at the beginning.
- * @throws IOException if an error occurs during the write to the {@code
- * OutputStream}.
- * @throws ClassCastException if the key or value of a mapping is not a
- * {@code String}.
+ * Stores the mappings in this {@code Properties} object to {@code out},
+ * putting the specified comment at the beginning.
+ *
+ * @param out the {@code Writer}
+ * @param comment an optional comment to be written, or null
+ * @throws IOException
+ * @throws ClassCastException if a key or value is not a string
+ * @since 1.6
+ * @hide
*/
- public synchronized void store(OutputStream out, String comment)
- throws IOException {
+ public synchronized void store(Writer writer, String comment) throws IOException {
if (lineSeparator == null) {
- lineSeparator = AccessController
- .doPrivileged(new PriviAction<String>("line.separator")); //$NON-NLS-1$
+ lineSeparator = AccessController.doPrivileged(new PriviAction<String>("line.separator"));
}
- StringBuilder buffer = new StringBuilder(200);
- OutputStreamWriter writer = new OutputStreamWriter(out, "ISO8859_1"); //$NON-NLS-1$
if (comment != null) {
- writer.write("#"); //$NON-NLS-1$
+ writer.write("#");
writer.write(comment);
writer.write(lineSeparator);
}
- writer.write("#"); //$NON-NLS-1$
+ writer.write("#");
writer.write(new Date().toString());
writer.write(lineSeparator);
+ StringBuilder buffer = new StringBuilder(200);
for (Map.Entry<Object, Object> entry : entrySet()) {
String key = (String) entry.getKey();
dumpString(buffer, key, true);
@@ -585,7 +622,7 @@ public class Properties extends Hashtable<Object, Object> {
if (builder == null) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- // BEGIN android-removed
+ // BEGIN android-removed: we still don't support validation.
// factory.setValidating(true);
// END android-removed
@@ -635,12 +672,7 @@ public class Properties extends Hashtable<Object, Object> {
for (int i = 0; i < entriesListLength; i++) {
Element entry = (Element) entries.item(i);
String key = entry.getAttribute("key");
- // BEGIN android-removed
- // String value = entry.getTextContent();
- // END android-removed
- // BEGIN android-added
String value = getTextContent(entry);
- // END android-added
/*
* key != null & value != null but key or(and) value can be
@@ -673,7 +705,7 @@ public class Properties extends Hashtable<Object, Object> {
* @throws IOException if an error occurs during writing to the output.
*/
public void storeToXML(OutputStream os, String comment) throws IOException {
- storeToXML(os, comment, "UTF-8"); //$NON-NLS-1$
+ storeToXML(os, comment, "UTF-8");
}
/**
@@ -764,7 +796,7 @@ public class Properties extends Hashtable<Object, Object> {
"&quot;");
}
- // BEGIN android-added
+ // BEGIN android-added: our SAX parser still doesn't do this for us.
private String getTextContent(Node node) {
String result = (node instanceof Text ? ((Text) node).getData() : "");
diff --git a/luni/src/main/java/java/util/PropertyResourceBundle.java b/luni/src/main/java/java/util/PropertyResourceBundle.java
index 835e892..5d96ead 100644
--- a/luni/src/main/java/java/util/PropertyResourceBundle.java
+++ b/luni/src/main/java/java/util/PropertyResourceBundle.java
@@ -19,6 +19,7 @@ package java.util;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
/**
* {@code PropertyResourceBundle} loads resources from an {@code InputStream}. All resources are
@@ -44,21 +45,35 @@ public class PropertyResourceBundle extends ResourceBundle {
* {@code InputStream}.
*/
public PropertyResourceBundle(InputStream stream) throws IOException {
+ if (stream == null) {
+ throw new NullPointerException();
+ }
resources = new Properties();
resources.load(stream);
}
-
+
+ /**
+ * Constructs a new resource bundle with properties read from {@code reader}.
+ *
+ * @param reader the {@code Reader}
+ * @throws IOException
+ * @since 1.6
+ * @hide
+ */
+ public PropertyResourceBundle(Reader reader) throws IOException {
+ resources = new Properties();
+ resources.load(reader);
+ }
+
+ protected Set<String> handleKeySet(){
+ return resources.stringPropertyNames();
+ }
+
@SuppressWarnings("unchecked")
private Enumeration<String> getLocalKeys() {
return (Enumeration<String>) resources.propertyNames();
}
- /**
- * Returns the names of the resources contained in this
- * PropertyResourceBundle.
- *
- * @return an Enumeration of the resource names
- */
@Override
public Enumeration<String> getKeys() {
if (parent == null) {
@@ -107,14 +122,6 @@ public class PropertyResourceBundle extends ResourceBundle {
};
}
- /**
- * Returns the named resource from this PropertyResourceBundle, or null if
- * the resource is not found.
- *
- * @param key
- * the name of the resource
- * @return the resource object
- */
@Override
public Object handleGetObject(String key) {
return resources.get(key);
diff --git a/luni/src/main/java/java/util/ResourceBundle.java b/luni/src/main/java/java/util/ResourceBundle.java
index 452ba8a..8901e45 100644
--- a/luni/src/main/java/java/util/ResourceBundle.java
+++ b/luni/src/main/java/java/util/ResourceBundle.java
@@ -18,17 +18,16 @@
package java.util;
import com.ibm.icu4jni.util.Resources;
+import dalvik.system.VMStack;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedAction;
-// BEGIN android-changed
-// import org.apache.harmony.kernel.vm.VM;
-import dalvik.system.VMStack;
-// END android-changed
-import org.apache.harmony.luni.util.Msg;
-
/**
* {@code ResourceBundle} is an abstract class which is the superclass of classes which
* provide {@code Locale}-specific resources. A bundle contains a number of named
@@ -81,6 +80,10 @@ import org.apache.harmony.luni.util.Msg;
*/
public abstract class ResourceBundle {
+ private static final String UNDER_SCORE = "_"; //$NON-NLS-1$
+
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
/**
* The parent of this {@code ResourceBundle} that is used if this bundle doesn't
* include the requested resource.
@@ -89,6 +92,8 @@ public abstract class ResourceBundle {
private Locale locale;
+ private long lastLoadTime = 0;
+
static class MissingBundle extends ResourceBundle {
@Override
public Enumeration<String> getKeys() {
@@ -107,10 +112,6 @@ public abstract class ResourceBundle {
private static final WeakHashMap<Object, Hashtable<String, ResourceBundle>> cache = new WeakHashMap<Object, Hashtable<String, ResourceBundle>>();
- // BEGIN android-added
- private static Locale defaultLocale = Locale.getDefault();
- // END android-added
-
/**
* Constructs a new instance of this class.
*/
@@ -121,25 +122,21 @@ public abstract class ResourceBundle {
/**
* Finds the named resource bundle for the default {@code Locale} and the caller's
* {@code ClassLoader}.
- *
+ *
* @param bundleName
* the name of the {@code ResourceBundle}.
* @return the requested {@code ResourceBundle}.
* @throws MissingResourceException
* if the {@code ResourceBundle} cannot be found.
*/
- public static final ResourceBundle getBundle(String bundleName)
- throws MissingResourceException {
- // BEGIN android-changed
- return getBundleImpl(bundleName, Locale.getDefault(), VMStack
- .getCallingClassLoader());
- // END android-changed
+ public static final ResourceBundle getBundle(String bundleName) throws MissingResourceException {
+ return getBundleImpl(bundleName, Locale.getDefault(), VMStack.getCallingClassLoader());
}
/**
* Finds the named {@code ResourceBundle} for the specified {@code Locale} and the caller
* {@code ClassLoader}.
- *
+ *
* @param bundleName
* the name of the {@code ResourceBundle}.
* @param locale
@@ -148,17 +145,13 @@ public abstract class ResourceBundle {
* @throws MissingResourceException
* if the resource bundle cannot be found.
*/
- public static final ResourceBundle getBundle(String bundleName,
- Locale locale) {
- // BEGIN android-changed
- return getBundleImpl(bundleName, locale,
- VMStack.getCallingClassLoader());
- // END android-changed
+ public static final ResourceBundle getBundle(String bundleName, Locale locale) {
+ return getBundleImpl(bundleName, locale, VMStack.getCallingClassLoader());
}
/**
* Finds the named resource bundle for the specified {@code Locale} and {@code ClassLoader}.
- *
+ *
* The passed base name and {@code Locale} are used to create resource bundle names.
* The first name is created by concatenating the base name with the result
* of {@link Locale#toString()}. From this name all parent bundle names are
@@ -210,25 +203,215 @@ public abstract class ResourceBundle {
if (loader == null) {
throw new NullPointerException();
}
- // BEGIN android-changed
- return getBundleImpl(bundleName, locale, loader);
- // END android-changed
+ if (bundleName != null) {
+ ResourceBundle bundle;
+ if (!locale.equals(Locale.getDefault())) {
+ if ((bundle = handleGetBundle(bundleName, UNDER_SCORE + locale,
+ false, loader)) != null) {
+ return bundle;
+ }
+ }
+ if ((bundle = handleGetBundle(bundleName, UNDER_SCORE
+ + Locale.getDefault(), true, loader)) != null) {
+ return bundle;
+ }
+ throw missingResourceException(bundleName + '_' + locale, "");
+ }
+ throw new NullPointerException();
+ }
+
+ private static MissingResourceException missingResourceException(String className, String key) {
+ String detail = "Can't find resource for bundle '" + className + "', key '" + key + "'";
+ throw new MissingResourceException(detail, className, key);
+ }
+
+ /**
+ * Finds the named resource bundle for the specified base name and control.
+ *
+ * @param baseName
+ * the base name of a resource bundle
+ * @param control
+ * the control that control the access sequence
+ * @return the named resource bundle
+ *
+ * @since 1.6
+ * @hide
+ */
+ public static final ResourceBundle getBundle(String baseName, ResourceBundle.Control control) {
+ return getBundle(baseName, Locale.getDefault(), getLoader(), control);
+ }
+
+ /**
+ * Finds the named resource bundle for the specified base name and control.
+ *
+ * @param baseName
+ * the base name of a resource bundle
+ * @param targetLocale
+ * the target locale of the resource bundle
+ * @param control
+ * the control that control the access sequence
+ * @return the named resource bundle
+ *
+ * @since 1.6
+ * @hide
+ */
+ public static final ResourceBundle getBundle(String baseName,
+ Locale targetLocale, ResourceBundle.Control control) {
+ return getBundle(baseName, targetLocale, getLoader(), control);
+ }
+
+ private static ClassLoader getLoader() {
+ return AccessController
+ .doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ ClassLoader cl = this.getClass().getClassLoader();
+ if (null == cl) {
+ cl = ClassLoader.getSystemClassLoader();
+ }
+ return cl;
+ }
+ });
+ }
+
+ /**
+ * Finds the named resource bundle for the specified base name and control.
+ *
+ * @param baseName
+ * the base name of a resource bundle
+ * @param targetLocale
+ * the target locale of the resource bundle
+ * @param loader
+ * the class loader to load resource
+ * @param control
+ * the control that control the access sequence
+ * @return the named resource bundle
+ *
+ * @since 1.6
+ * @hide
+ */
+ public static ResourceBundle getBundle(String baseName,
+ Locale targetLocale, ClassLoader loader,
+ ResourceBundle.Control control) {
+ boolean expired = false;
+ String bundleName = control.toBundleName(baseName, targetLocale);
+ Object cacheKey = loader != null ? (Object) loader : (Object) "null"; //$NON-NLS-1$
+ Hashtable<String, ResourceBundle> loaderCache;
+ // try to find in cache
+ synchronized (cache) {
+ loaderCache = cache.get(cacheKey);
+ if (loaderCache == null) {
+ loaderCache = new Hashtable<String, ResourceBundle>();
+ cache.put(cacheKey, loaderCache);
+ }
+ }
+ ResourceBundle result = loaderCache.get(bundleName);
+ if (result != null) {
+ long time = control.getTimeToLive(baseName, targetLocale);
+ if (time == 0 || time == Control.TTL_NO_EXPIRATION_CONTROL
+ || time + result.lastLoadTime < System.currentTimeMillis()) {
+ if (MISSING == result) {
+ throw new MissingResourceException(null, bundleName + '_'
+ + targetLocale, EMPTY_STRING);
+ }
+ return result;
+ }
+ expired = true;
+ }
+ // try to load
+ ResourceBundle ret = processGetBundle(baseName, targetLocale, loader,
+ control, expired, result);
+
+ if (null != ret) {
+ loaderCache.put(bundleName, ret);
+ ret.lastLoadTime = System.currentTimeMillis();
+ return ret;
+ }
+ loaderCache.put(bundleName, MISSING);
+ throw new MissingResourceException(null, bundleName + '_'
+ + targetLocale, EMPTY_STRING);
+ }
+
+ private static ResourceBundle processGetBundle(String baseName,
+ Locale targetLocale, ClassLoader loader,
+ ResourceBundle.Control control, boolean expired,
+ ResourceBundle result) {
+ List<Locale> locales = control.getCandidateLocales(baseName,
+ targetLocale);
+ if (null == locales) {
+ throw new IllegalArgumentException();
+ }
+ List<String> formats = control.getFormats(baseName);
+ if (Control.FORMAT_CLASS == formats
+ || Control.FORMAT_PROPERTIES == formats
+ || Control.FORMAT_DEFAULT == formats) {
+ throw new IllegalArgumentException();
+ }
+ ResourceBundle ret = null;
+ ResourceBundle currentBundle = null;
+ ResourceBundle bundle = null;
+ for (Locale locale : locales) {
+ for (String format : formats) {
+ try {
+ if (expired) {
+ bundle = control.newBundle(baseName, locale, format,
+ loader, control.needsReload(baseName, locale,
+ format, loader, result, System
+ .currentTimeMillis()));
+
+ } else {
+ try {
+ bundle = control.newBundle(baseName, locale,
+ format, loader, false);
+ } catch (IllegalArgumentException e) {
+ // do nothing
+ }
+ }
+ } catch (IllegalAccessException e) {
+ // do nothing
+ } catch (InstantiationException e) {
+ // do nothing
+ } catch (IOException e) {
+ // do nothing
+ }
+ if (null != bundle) {
+ if (null != currentBundle) {
+ currentBundle.setParent(bundle);
+ currentBundle = bundle;
+ } else {
+ if (null == ret) {
+ ret = bundle;
+ currentBundle = ret;
+ }
+ }
+ }
+ if (null != bundle) {
+ break;
+ }
+ }
+ }
+
+ if ((null == ret)
+ || (Locale.ROOT.equals(ret.getLocale()) && (!(locales.size() == 1 && locales
+ .contains(Locale.ROOT))))) {
+ Locale nextLocale = control.getFallbackLocale(baseName,
+ targetLocale);
+ if (null != nextLocale) {
+ ret = processGetBundle(baseName, nextLocale, loader, control,
+ expired, result);
+ }
+ }
+
+ return ret;
}
private static ResourceBundle getBundleImpl(String bundleName,
Locale locale, ClassLoader loader) throws MissingResourceException {
if (bundleName != null) {
ResourceBundle bundle;
- // BEGIN android-added
- if (!defaultLocale.equals(Locale.getDefault())) {
- cache.clear();
- defaultLocale = Locale.getDefault();
- }
- // END android-added
if (!locale.equals(Locale.getDefault())) {
String localeName = locale.toString();
if (localeName.length() > 0) {
- localeName = "_" + localeName; //$NON-NLS-1$
+ localeName = UNDER_SCORE + localeName;
}
if ((bundle = handleGetBundle(bundleName, localeName, false,
loader)) != null) {
@@ -237,20 +420,19 @@ public abstract class ResourceBundle {
}
String localeName = Locale.getDefault().toString();
if (localeName.length() > 0) {
- localeName = "_" + localeName; //$NON-NLS-1$
+ localeName = UNDER_SCORE + localeName;
}
if ((bundle = handleGetBundle(bundleName, localeName, true, loader)) != null) {
return bundle;
}
- throw new MissingResourceException(Msg.getString("KA029", bundleName, locale), bundleName + '_' + locale, //$NON-NLS-1$
- ""); //$NON-NLS-1$
+ throw missingResourceException(bundleName + '_' + locale, "");
}
throw new NullPointerException();
}
/**
* Returns the names of the resources contained in this {@code ResourceBundle}.
- *
+ *
* @return an {@code Enumeration} of the resource names.
*/
public abstract Enumeration<String> getKeys();
@@ -259,7 +441,7 @@ public abstract class ResourceBundle {
* Gets the {@code Locale} of this {@code ResourceBundle}. In case a bundle was not
* found for the requested {@code Locale}, this will return the actual {@code Locale} of
* this resource bundle that was found after doing a fallback.
- *
+ *
* @return the {@code Locale} of this {@code ResourceBundle}.
*/
public Locale getLocale() {
@@ -271,7 +453,7 @@ public abstract class ResourceBundle {
* cannot be found in this bundle, it falls back to the parent bundle (if
* it's not null) by calling the {@link #handleGetObject} method. If the resource still
* can't be found it throws a {@code MissingResourceException}.
- *
+ *
* @param key
* the name of the resource.
* @return the resource object.
@@ -288,12 +470,12 @@ public abstract class ResourceBundle {
last = theParent;
theParent = theParent.parent;
} while (theParent != null);
- throw new MissingResourceException(Msg.getString("KA029", last.getClass().getName(), key), last.getClass().getName(), key); //$NON-NLS-1$
+ throw missingResourceException(last.getClass().getName(), key);
}
/**
* Returns the named string resource from this {@code ResourceBundle}.
- *
+ *
* @param key
* the name of the resource.
* @return the resource string.
@@ -309,7 +491,7 @@ public abstract class ResourceBundle {
/**
* Returns the named resource from this {@code ResourceBundle}.
- *
+ *
* @param key
* the name of the resource.
* @return the resource string array.
@@ -356,7 +538,7 @@ public abstract class ResourceBundle {
try {
Class<?> bundleClass = Class.forName(bundleName, true, loader);
-
+
if (ResourceBundle.class.isAssignableFrom(bundleClass)) {
bundle = (ResourceBundle) bundleClass.newInstance();
}
@@ -381,12 +563,13 @@ public abstract class ResourceBundle {
if (stream != null) {
try {
try {
- bundle = new PropertyResourceBundle(stream);
+ bundle = new PropertyResourceBundle(new InputStreamReader(stream));
} finally {
stream.close();
}
bundle.setLocale(locale);
} catch (IOException e) {
+ // do nothing
}
}
}
@@ -418,7 +601,7 @@ public abstract class ResourceBundle {
/**
* Returns the named resource from this {@code ResourceBundle}, or null if the
* resource is not found.
- *
+ *
* @param key
* the name of the resource.
* @return the resource object.
@@ -428,7 +611,7 @@ public abstract class ResourceBundle {
/**
* Sets the parent resource bundle of this {@code ResourceBundle}. The parent is
* searched for resources which are not found in this {@code ResourceBundle}.
- *
+ *
* @param bundle
* the parent {@code ResourceBundle}.
*/
@@ -444,9 +627,509 @@ public abstract class ResourceBundle {
return null;
}
+ private void setLocale(Locale locale) {
+ this.locale = locale;
+ }
+
private void setLocale(String name) {
- // BEGIN android-changed: remove duplication.
- locale = Resources.localeFromString(name);
- // END android-changed
+ setLocale(Resources.localeFromString(name));
+ }
+
+ public static final void clearCache() {
+ cache.remove(ClassLoader.getSystemClassLoader());
+ }
+
+ public static final void clearCache(ClassLoader loader) {
+ if (null == loader) {
+ throw new NullPointerException();
+ }
+ cache.remove(loader);
+ }
+
+ public boolean containsKey(String key) {
+ if (null == key) {
+ throw new NullPointerException();
+ }
+ return keySet().contains(key);
+ }
+
+ public Set<String> keySet() {
+ Set<String> ret = new HashSet<String>();
+ Enumeration<String> keys = getKeys();
+ while (keys.hasMoreElements()) {
+ ret.add(keys.nextElement());
+ }
+ return ret;
+ }
+
+ protected Set<String> handleKeySet() {
+ Set<String> set = keySet();
+ Set<String> ret = new HashSet<String>();
+ for (String key : set) {
+ if (null != handleGetObject(key)) {
+ ret.add(key);
+ }
+ }
+ return ret;
+ }
+
+ private static class NoFallbackControl extends Control {
+
+ static final Control NOFALLBACK_FORMAT_PROPERTIES_CONTROL = new NoFallbackControl(
+ JAVAPROPERTIES);
+
+ static final Control NOFALLBACK_FORMAT_CLASS_CONTROL = new NoFallbackControl(
+ JAVACLASS);
+
+ static final Control NOFALLBACK_FORMAT_DEFAULT_CONTROL = new NoFallbackControl(
+ listDefault);
+
+ public NoFallbackControl(String format) {
+ super();
+ listClass = new ArrayList<String>();
+ listClass.add(format);
+ super.format = Collections.unmodifiableList(listClass);
+ }
+
+ public NoFallbackControl(List<String> list) {
+ super();
+ super.format = list;
+ }
+
+ @Override
+ public Locale getFallbackLocale(String baseName, Locale locale) {
+ if (null == baseName || null == locale) {
+ throw new NullPointerException();
+ }
+ return null;
+ }
+ }
+
+ private static class SimpleControl extends Control {
+ public SimpleControl(String format) {
+ super();
+ listClass = new ArrayList<String>();
+ listClass.add(format);
+ super.format = Collections.unmodifiableList(listClass);
+ }
+ }
+
+ @SuppressWarnings("nls")
+ /**
+ * ResourceBundle.Control is a static utility class defines ResourceBundle
+ * load access methods, its default access order is as the same as before.
+ * However users can implement their own control.
+ *
+ * @since 1.6
+ * @hide
+ */
+ public static class Control {
+ static List<String> listDefault = new ArrayList<String>();
+
+ static List<String> listClass = new ArrayList<String>();
+
+ static List<String> listProperties = new ArrayList<String>();
+
+ static String JAVACLASS = "java.class";
+
+ static String JAVAPROPERTIES = "java.properties";
+
+ static {
+ listDefault.add(JAVACLASS);
+ listDefault.add(JAVAPROPERTIES);
+ listClass.add(JAVACLASS);
+ listProperties.add(JAVAPROPERTIES);
+ }
+
+ /**
+ * a list defines default format
+ */
+ public static final List<String> FORMAT_DEFAULT = Collections
+ .unmodifiableList(listDefault);
+
+ /**
+ * a list defines java class format
+ */
+ public static final List<String> FORMAT_CLASS = Collections
+ .unmodifiableList(listClass);
+
+ /**
+ * a list defines property format
+ */
+ public static final List<String> FORMAT_PROPERTIES = Collections
+ .unmodifiableList(listProperties);
+
+ /**
+ * a constant that indicates cache will not be used.
+ */
+ public static final long TTL_DONT_CACHE = -1L;
+
+ /**
+ * a constant that indicates cache will not be expired.
+ */
+ public static final long TTL_NO_EXPIRATION_CONTROL = -2L;
+
+ private static final Control FORMAT_PROPERTIES_CONTROL = new SimpleControl(
+ JAVAPROPERTIES);
+
+ private static final Control FORMAT_CLASS_CONTROL = new SimpleControl(
+ JAVACLASS);
+
+ private static final Control FORMAT_DEFAULT_CONTROL = new Control();
+
+ List<String> format;
+
+ /**
+ * default constructor
+ *
+ */
+ protected Control() {
+ super();
+ listClass = new ArrayList<String>();
+ listClass.add(JAVACLASS);
+ listClass.add(JAVAPROPERTIES);
+ format = Collections.unmodifiableList(listClass);
+ }
+
+ /**
+ * Answers a control according to the given format list
+ *
+ * @param formats
+ * a format to use
+ * @return a control according to the given format list
+ */
+ public static final Control getControl(List<String> formats) {
+ switch (formats.size()) {
+ case 1:
+ if (formats.contains(JAVACLASS)) {
+ return FORMAT_CLASS_CONTROL;
+ }
+ if (formats.contains(JAVAPROPERTIES)) {
+ return FORMAT_PROPERTIES_CONTROL;
+ }
+ break;
+ case 2:
+ if (formats.equals(FORMAT_DEFAULT)) {
+ return FORMAT_DEFAULT_CONTROL;
+ }
+ break;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Answers a control according to the given format list whose fallback
+ * locale is null
+ *
+ * @param formats
+ * a format to use
+ * @return a control according to the given format list whose fallback
+ * locale is null
+ */
+ public static final Control getNoFallbackControl(List<String> formats) {
+ switch (formats.size()) {
+ case 1:
+ if (formats.contains(JAVACLASS)) {
+ return NoFallbackControl.NOFALLBACK_FORMAT_CLASS_CONTROL;
+ }
+ if (formats.contains(JAVAPROPERTIES)) {
+ return NoFallbackControl.NOFALLBACK_FORMAT_PROPERTIES_CONTROL;
+ }
+ break;
+ case 2:
+ if (formats.equals(FORMAT_DEFAULT)) {
+ return NoFallbackControl.NOFALLBACK_FORMAT_DEFAULT_CONTROL;
+ }
+ break;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Answers a list of candidate locales according to the base name and
+ * locale
+ *
+ * @param baseName
+ * the base name to use
+ * @param locale
+ * the locale
+ * @return the candidate locales according to the base name and locale
+ */
+ public List<Locale> getCandidateLocales(String baseName, Locale locale) {
+ if (null == baseName || null == locale) {
+ throw new NullPointerException();
+ }
+ List<Locale> retList = new ArrayList<Locale>();
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+ if (!EMPTY_STRING.equals(variant)) {
+ retList.add(new Locale(language, country, variant));
+ }
+ if (!EMPTY_STRING.equals(country)) {
+ retList.add(new Locale(language, country));
+ }
+ if (!EMPTY_STRING.equals(language)) {
+ retList.add(new Locale(language));
+ }
+ retList.add(Locale.ROOT);
+ return retList;
+ }
+
+ /**
+ * Answers a list of strings of formats according to the base name
+ *
+ * @param baseName
+ * the base name to use
+ * @return a list of strings of formats according to the base name
+ */
+ public List<String> getFormats(String baseName) {
+ if (null == baseName) {
+ throw new NullPointerException();
+ }
+ return format;
+ }
+
+ /**
+ * Answers a list of strings of locales according to the base name
+ *
+ * @param baseName
+ * the base name to use
+ * @return a list of strings of locales according to the base name
+ */
+ public Locale getFallbackLocale(String baseName, Locale locale) {
+ if (null == baseName || null == locale) {
+ throw new NullPointerException();
+ }
+ if (Locale.getDefault() != locale) {
+ return Locale.getDefault();
+ }
+ return null;
+ }
+
+ /**
+ * Answers a new ResourceBundle according to the give parameters
+ *
+ * @param baseName
+ * the base name to use
+ * @param locale
+ * the given locale
+ * @param format
+ * the format, default is "java.class" or "java.properities"
+ * @param loader
+ * the classloader to use
+ * @param reload
+ * if reload the resource
+ * @return a new ResourceBundle according to the give parameters
+ * @throws IllegalAccessException
+ * if can not access resources
+ * @throws InstantiationException
+ * if can not instante a resource class
+ * @throws IOException
+ * if other I/O exception happens
+ */
+ public ResourceBundle newBundle(String baseName, Locale locale,
+ String format, ClassLoader loader, boolean reload)
+ throws IllegalAccessException, InstantiationException,
+ IOException {
+ if (null == format || null == loader) {
+ throw new NullPointerException();
+ }
+ InputStream streams = null;
+ final String bundleName = toBundleName(baseName, locale);
+ final ClassLoader clsloader = loader;
+ ResourceBundle ret;
+ Class<?> cls = null;
+ if (JAVACLASS == format) {
+ cls = AccessController
+ .doPrivileged(new PrivilegedAction<Class<?>>() {
+ public Class<?> run() {
+ try {
+ return clsloader.loadClass(bundleName);
+ } catch (Exception e) {
+ return null;
+ } catch (NoClassDefFoundError e) {
+ return null;
+ }
+ }
+ });
+ if (null == cls) {
+ return null;
+ }
+ try {
+ ResourceBundle bundle = (ResourceBundle) cls.newInstance();
+ bundle.setLocale(locale);
+ return bundle;
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+ if (JAVAPROPERTIES == format) {
+ final String resourceName = toResourceName(bundleName,
+ "properties");
+ if (reload) {
+ URL url = null;
+ try {
+ url = loader.getResource(resourceName);
+ } catch (NullPointerException e) {
+ // do nothing
+ }
+ if (null != url) {
+ URLConnection con = url.openConnection();
+ con.setUseCaches(false);
+ streams = con.getInputStream();
+ }
+ } else {
+ try {
+ streams = AccessController
+ .doPrivileged(new PrivilegedAction<InputStream>() {
+ public InputStream run() {
+ return clsloader
+ .getResourceAsStream(resourceName);
+ }
+ });
+ } catch (NullPointerException e) {
+ // do nothing
+ }
+ }
+ if (streams != null) {
+ try {
+ ret = new PropertyResourceBundle(new InputStreamReader(streams));
+ ret.setLocale(locale);
+ streams.close();
+ } catch (IOException e) {
+ return null;
+ }
+ return ret;
+ }
+ return null;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Answers the time to live of the ResourceBundle, default is
+ * TTL_NO_EXPIRATION_CONTROL
+ *
+ * @param baseName
+ * the base name to use
+ * @param locale
+ * the locale to use
+ * @return TTL_NO_EXPIRATION_CONTROL
+ */
+ public long getTimeToLive(String baseName, Locale locale) {
+ if (null == baseName || null == locale) {
+ throw new NullPointerException();
+ }
+ return TTL_NO_EXPIRATION_CONTROL;
+ }
+
+ /**
+ * Answers if the ResourceBundle needs to reload
+ *
+ * @param baseName
+ * the base name of the ResourceBundle
+ * @param locale
+ * the locale of the ResourceBundle
+ * @param format
+ * the format to load
+ * @param loader
+ * the ClassLoader to load resource
+ * @param bundle
+ * the ResourceBundle
+ * @param loadTime
+ * the expired time
+ * @return if the ResourceBundle needs to reload
+ */
+ public boolean needsReload(String baseName, Locale locale,
+ String format, ClassLoader loader, ResourceBundle bundle,
+ long loadTime) {
+ if (null == bundle) {
+ // FIXME what's the use of bundle?
+ throw new NullPointerException();
+ }
+ String bundleName = toBundleName(baseName, locale);
+ String suffix = format;
+ if (JAVACLASS == format) {
+ suffix = "class";
+ }
+ if (JAVAPROPERTIES == format) {
+ suffix = "properties";
+ }
+ String urlname = toResourceName(bundleName, suffix);
+ URL url = loader.getResource(urlname);
+ if (null != url) {
+ String fileName = url.getFile();
+ long lastModified = new File(fileName).lastModified();
+ if (lastModified > loadTime) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * a utility method to answer the name of a resource bundle according to
+ * the given base name and locale
+ *
+ * @param baseName
+ * the given base name
+ * @param locale
+ * the locale to use
+ * @return the name of a resource bundle according to the given base
+ * name and locale
+ */
+ public String toBundleName(String baseName, Locale locale) {
+ final String emptyString = EMPTY_STRING;
+ final String preString = UNDER_SCORE;
+ final String underline = UNDER_SCORE;
+ if (null == baseName) {
+ throw new NullPointerException();
+ }
+ StringBuilder ret = new StringBuilder();
+ StringBuilder prefix = new StringBuilder();
+ ret.append(baseName);
+ if (!locale.getLanguage().equals(emptyString)) {
+ ret.append(underline);
+ ret.append(locale.getLanguage());
+ } else {
+ prefix.append(preString);
+ }
+ if (!locale.getCountry().equals(emptyString)) {
+ ret.append((CharSequence) prefix);
+ ret.append(underline);
+ ret.append(locale.getCountry());
+ prefix = new StringBuilder();
+ } else {
+ prefix.append(preString);
+ }
+ if (!locale.getVariant().equals(emptyString)) {
+ ret.append((CharSequence) prefix);
+ ret.append(underline);
+ ret.append(locale.getVariant());
+ }
+ return ret.toString();
+ }
+
+ /**
+ * a utility method to answer the name of a resource according to the
+ * given bundleName and suffix
+ *
+ * @param bundleName
+ * the given bundle name
+ * @param suffix
+ * the suffix
+ * @return the name of a resource according to the given bundleName and
+ * suffix
+ */
+ public final String toResourceName(String bundleName, String suffix) {
+ if (null == suffix) {
+ throw new NullPointerException();
+ }
+ StringBuilder ret = new StringBuilder(bundleName.replace('.', '/'));
+ ret.append('.');
+ ret.append(suffix);
+ return ret.toString();
+ }
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties b/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
index 8869880..4b8ce5c 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
@@ -18,11 +18,6 @@ luni.00=Connection has not been established yet
luni.01=Could not make SSL Tunneling. Got response: {0} ({1})
luni.02=Hostname <{0}> was not verified
luni.03=The enum constant {0}.{1} is missing
-luni.04=this Map
luni.05=Attempt to insert {0} element into collection with element type {1}
luni.06=The string argument is null
luni.07=The stream is corrupted
-luni.08=Invalid Unicode sequence: expected format \\uxxxx
-luni.09=Invalid Unicode sequence: illegal character
-luni.0A=Index: {0}, Size: {1}
-luni.0B=Array index out of range: {0}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
index b6cbcef..2c7d605 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
+++ b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
@@ -15,38 +15,13 @@
# External Messages for EN locale
K0006=Negative index specified
-K0007=attempt to write after finish
-K0008=Cannot read version
-K0009=Missing version string\: {0}
-K000a=Entry is not named
-K000b=Invalid attribute {0}
-K000c=cannot resolve subclasses
-K000d=Unknown attribute
-K000e=Cannot add attributes to empty string
-K0014=Unquoted {0} in suffix\: {1}
-K0015=Unexpected {0} in fraction\: {1}
-K0016=Unexpected {0} in {1}
-K0017=Missing pattern before {0} in {1}
-K0018=Missing exponent format {0}
-K0019=Unterminated quote {0}
-K001a=Missing grouping format {0}
-K001b=Invalid exponent format {0}
-K001c=Invalid pattern char {0} in {1}
-K001d=Invalid argument number
-K001e=Missing element format
-K001f=Unknown element format
-K0020=Unknown format
-K002b=Unknown pattern character - '{0}'
-K002c=Access denied {0}
K002e=Offset out of bounds \: {0}
K002f=Arguments out of bounds
K0032=Address null or destination port out of range
-K0033=Unknown socket type
K0034=Packet address mismatch with connected address
K0035=Zero or negative buffer size
K0036=Invalid negative timeout
K0037=Connection already established
-K0038=No host name provided
K0039=Attempted to join a non-multicast group
K003a=Attempted to leave a non-multicast group
K003c=TimeToLive out of bounds
@@ -54,7 +29,6 @@ K003d=Socket is closed
K003e=SOCKS connection failed\: {0}
K003f=Unable to connect to SOCKS server\: {0}
K0040=Invalid SOCKS client.
-K0041=Socket implementation does not support SOCKS.
K0042=Socket implementation factory already set
K0044=The factory has already been set
K0045=Attempted to set a negative SoLinger
@@ -67,19 +41,11 @@ K004b=Attempt to set factory more than once.
K004c=Package is sealed
K004d=Does not support writing to the input stream
K004e=Duplicate Factory
-K004f=rounding necessary
-K0050=wrong rounding mode
K0051=scale value < than zero
K0052=Array index out of range\: {0}
-K0053=Package {0} already defined.
K0055=String index out of range\: {0}
-K0056=Already destroyed
-K0057=Has threads
K0058=size must be > 0
K0059=Stream is closed
-# // BEGIN android-deleted
-# // K005a=Mark has been invalidated.
-# // END android-deleted
K005b=BufferedReader is closed
K005c=Invalid Mark.
K005d=Writer is closed.
@@ -90,9 +56,7 @@ K0062=Second byte at {0} does not match UTF8 Specification
K0063=Third byte at {0} does not match UTF8 Specification
K0064=Second or third byte at {0} does not match UTF8 Specification
K0065=Input at {0} does not match UTF8 Specification
-K0066=Entry already exists: {0}
K0068=String is too long
-K0069=File cannot compare to non File
K006a=time must be positive
K006b=Prefix must be at least 3 characters
K006c=FileDescriptor is null
@@ -102,11 +66,9 @@ K006f=invalid permission\: {0}
K0070=InputStreamReader is closed.
K0071=Error fetching SUID\: {0}
K0072={0} computing SHA-1 / SUID
-K0073=OutputStreamWriter is closed.
K0074=Not connected
K0075=InputStream is closed
K0076=Pipe broken
-K0077=Crc mismatch
K0078=Pipe is closed
K0079=Already connected
K007a=Pipe already connected
@@ -117,13 +79,6 @@ K0080=Reader is closed
K0081=Mode must be one of "r" or "rw"
K0083=StringReader is closed.
K0084=can only instantiate one BootstrapClassLoader
-K0086=Referenced reflect object is no longer valid
-K0087=Referenced reflect object is no longer valid\: {0}
-K0088=Incorrect end of BER tag
-K0089=Unknown type\: {0}
-K008a=Read {0} bytes trying to read {1} bytes from {2}
-K008b=Position\: {0}
-K008c=Invalid Base64 char\:{0}
K008d=This protocol does not support input
K008e=Does not support output
K008f=This method does not support writing\: {0}
@@ -139,20 +94,13 @@ K0098=Unable to log into server\: {0}
K0099=Unable to configure data port
K009a=Unable to store file
K009b=Unable to set transfer type
-K00a2=Parsing policy file\: {0}, expected quoted {1}, found unquoted\: {2}
-K00a3=Parsing policy file\: {0}, found unexpected\: {1}
K00a4=Content-Length underflow
K00a5=Invalid parameter - {0}
-K00a8=Parsing policy file\: {0}, invalid codesource URL\: {1}
-K00ab=No active entry
-K00ae=Size mismatch
K00af=Invalid proxy port\: {0}
K00b0=Proxy port out of range
K00b1=Invalid port number
K00b2=Content-Length exceeded
K00b3=Unknown protocol\: {0}
-K00b6=No entries
-K00b7=File is closed
K00c1=Illegal character
K00cd=Failure to connect to SOCKS server.
K00ce=Unable to connect to identd to verify user.
@@ -168,65 +116,27 @@ K00d8=Protocol not found\: {0}
K00d9=Callback object cannot be null
K00da=Incompatible class (SUID)\: {0} but expected {1}
K00dc=IllegalAccessException
-K00e3=Could not create specified security manager\: {0}
-K00e4=Key usage is critical and cannot be used for digital signature purposes.
K00e5=month\: {0}
K00e6=day of month\: {0}
K00e7=day of week\: {0}
K00e8=time\: {0}
K00e9=DST offset\: {0}
K00ea=era\: {0}
-K00eb={0} failed verification of {1}
-K00ec={0} has invalid digest for {1} in {2}
K00ed={0} is not an interface
K00ee={0} is not visible from class loader
K00ef={0} appears more than once
K00f0=non-public interfaces must be in the same package
K00f1=not a proxy instance
-K00f2=the methods named {0} must have the same return type
K00f3=Timer was cancelled
K00f5=Illegal delay to start the TimerTask
K00f6=TimerTask is scheduled already
K00f7=TimerTask is cancelled
K00f8=day of week in month\: {0}
-K00f9=min or max digit count too large
-K00fa=min digits greater than max digits
-K00fb=min or max digits negative
K00fc=Jar entry not specified
-K00fd=Invalid keystore
-K00fe=Incorrect password
-K0185=The alias already exists for a key entry.
-K018f=Can't convert to BMPString \: {0}
-K0190=No data to decode
-K0191=Invalid size, must be a multiple of 64 from 512 to 1024
-K0193=An identity with this name already exists in this scope
-K0194=An identity in the scope has the same public key
-K0195=The existing public key and the one contained in the certificate do not match.
-K0196=Certificate is missing
K0199=Count out of range
-K01a0=End of stream condition
-K01a4=Already shutting down
-K01a5=Illegal shutdown hook\: {0}
-K01a6=Invalid filter
-K01a7=Name too long: {0}
-K01b3=Incorrect number of arguments
-K01b4=Cannot convert {0} to {1}
K01b6=Cannot find \!/
-K01c1=File is a Directory
-K01c2=Cannot create\: {0}
-K01c3=Unable to open\: {0}
-K01c4=Invalid zip file\: {0}
-K01c6=No Main-Class specified in manifest\: {0}
-K01d1=Signers of '{0}' do not match signers of other classes in package
-K01d2={1} - protected system package '{0}'
-K01ec=key size must be a multiple of 8 bits
-K01ed=key size must be at least 512 bits
K01fe=Incomplete % sequence at\: {0}
K01ff=Invalid % sequence ({0}) at\: {1}
-K0220=UTFDataFormatException
-K0222=No Manifest found in jar file\: {0}
-K0300=Unsupported encoding
-K0301=Not signed data
K0302=Relative path
K0303=Scheme-specific part expected
K0304=Authority expected
@@ -249,7 +159,6 @@ K0315=Socket is already bound
K0316=SocketAddress {0} not supported
K0317=Host is unresolved\: {0}
K0318=SocketAddress is null
-K0319=Exception in thread "{0}"\
K031a=URI is not absolute\: {0}
K031b=URI is not hierarchical\: {0}
K031c=Expected file scheme in URI\: {0}
@@ -260,25 +169,19 @@ K0320=Socket is not connected
K0321=Socket input is shutdown
K0322=Not a supported ISO 4217 Currency Code\: {0}
K0323=Not a supported ISO 3166 Country locale\: {0}
-K0324=Needs dictionary
K0325=Port out of range\: {0}
K0326={0} at index {1}\: {2}
K0327={0}\: {1}
-K0328=Certificate not yet valid
-K0329=Certificate expired
K0330=interface name is null
K0331=address is null
K0332=Invalid IP Address is neither 4 or 16 bytes\: {0}
K0333=Urgent data not supported
K0334=Cannot set network interface with null
K0335=No addresses associated with Interface
-K0337=null type not allowed
K0338=Address not associated with an interface - not set
K0339=Invalid IP Address is neither 4 or 16 bytes
K0340={0} incompatible with {1}
K0342=Scheme expected
-K0344=Not a valid {0}, subclass should override readResolve()
-K0346=Unmatched braces in the pattern
K0347=seek position is negative
K0348=Format specifier '{0}'
K0349=Conversion is '{0}'
@@ -286,10 +189,8 @@ K034a=The flags are {0}
K034b=url and proxy can not be null
K034c=proxy should not be null
K034d=method has not been implemented yet
-K034e=Build rules empty
K0351=format is null
K0352=package is sealed
-KA000=Line too long
KA001=Argument must not be null
KA002=Unshared read of back reference
KA003=different mode already set
@@ -301,7 +202,6 @@ KA008={0} is an illegal radix
KA009=CharsetName is illegal
KA00a=File is null
KA00b=InputStream is null
-KA00c=Readable is null
KA00d=ReadableByteChannel is null
KA00e=Radix {0} is less than Character.MIN_RADIX or greater than Character.MAX_RADIX
KA00f=Socket output is shutdown
@@ -321,10 +221,8 @@ KA022=Illegal Proxy.Type or SocketAddress argument
KA023=Proxy is null or invalid type
KA024=One of urls is null
KA025=Method has not been implemented
-KA026=JAR entry {0} not found in {1}
KA027=Inputstream of the JarURLConnection has been closed
KA028=Cannot set protocol version when stream in use
-KA029=Can't find resource for bundle {0}, key {1}
KA030=Write end dead
K0031=Length out of bounds \: {0}
K0032=Source size {0} does not fit into destination
diff --git a/luni/src/test/java/tests/api/java/util/PropertiesTest.java b/luni/src/test/java/tests/api/java/util/PropertiesTest.java
index 84a81d2..d1d4c67 100644
--- a/luni/src/test/java/tests/api/java/util/PropertiesTest.java
+++ b/luni/src/test/java/tests/api/java/util/PropertiesTest.java
@@ -17,24 +17,29 @@
package tests.api.java.util;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
import java.util.Properties;
+import java.util.Scanner;
+import java.util.Set;
import tests.support.resource.Support_Resources;
-@TestTargetClass(Properties.class)
public class PropertiesTest extends junit.framework.TestCase {
Properties tProps;
@@ -44,76 +49,76 @@ public class PropertiesTest extends junit.framework.TestCase {
/**
* @tests java.util.Properties#Properties()
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "Properties",
- args = {}
- )
public void test_Constructor() {
+ // Test for method java.util.Properties()
Properties p = new Properties();
// do something to avoid getting a variable unused warning
p.clear();
+ assertTrue("Created incorrect Properties", true);
+ }
+
+ public void test_loadLjava_io_InputStream_NPE() throws Exception {
+ Properties p = new Properties();
+ try {
+ p.load((InputStream) null);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ public void test_loadsave() throws Exception{
+ Properties p = new Properties();
+ try {
+ p.load((InputStream) null);
+ fail("should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
}
/**
* @tests java.util.Properties#Properties(java.util.Properties)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "Properties",
- args = {java.util.Properties.class}
- )
public void test_ConstructorLjava_util_Properties() {
- if (System.getProperty("java.vendor") != null) {
- Properties p = new Properties(System.getProperties());
- assertNotNull("failed to construct correct properties", p
- .getProperty("java.vendor"));
+ Properties systemProperties = System.getProperties();
+ Properties properties = new Properties(systemProperties);
+ Enumeration<?> propertyNames = systemProperties.propertyNames();
+ String propertyName = null;
+ while (propertyNames.hasMoreElements()) {
+ propertyName = (String) propertyNames.nextElement();
+ assertEquals("failed to construct correct properties",
+ systemProperties.get(propertyName), properties
+ .getProperty(propertyName));
}
}
/**
* @tests java.util.Properties#getProperty(java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies positive case.",
- method = "getProperty",
- args = {java.lang.String.class}
- )
public void test_getPropertyLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.util.Properties.getProperty(java.lang.String)
assertEquals("Did not retrieve property", "this is a test property",
- tProps.getProperty("test.prop"));
+ ((String) tProps.getProperty("test.prop")));
}
/**
* @tests java.util.Properties#getProperty(java.lang.String,
* java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getProperty",
- args = {java.lang.String.class, java.lang.String.class}
- )
public void test_getPropertyLjava_lang_StringLjava_lang_String() {
+ // Test for method java.lang.String
+ // java.util.Properties.getProperty(java.lang.String, java.lang.String)
assertEquals("Did not retrieve property", "this is a test property",
- tProps.getProperty("test.prop", "Blarg"));
- assertEquals("Did not return default value", "Gabba", tProps
- .getProperty("notInThere.prop", "Gabba"));
- assertNull(tProps.getProperty("", null));
+ ((String) tProps.getProperty("test.prop", "Blarg")));
+ assertEquals("Did not return default value", "Gabba", ((String) tProps
+ .getProperty("notInThere.prop", "Gabba")));
}
/**
* @tests java.util.Properties#getProperty(java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Regression test.",
- method = "getProperty",
- args = {java.lang.String.class}
- )
public void test_getPropertyLjava_lang_String2() {
// regression test for HARMONY-3518
MyProperties props = new MyProperties();
@@ -124,16 +129,10 @@ public class PropertiesTest extends junit.framework.TestCase {
* @tests java.util.Properties#getProperty(java.lang.String,
* java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Regression test.",
- method = "getProperty",
- args = {java.lang.String.class, java.lang.String.class}
- )
public void test_getPropertyLjava_lang_StringLjava_lang_String2() {
// regression test for HARMONY-3518
MyProperties props = new MyProperties();
- assertEquals(props.getProperty("key", "defaultValue"), "defaultValue");
+ assertEquals("defaultValue", props.getProperty("key", "defaultValue"));
}
// regression testing for HARMONY-3518
@@ -146,80 +145,192 @@ public class PropertiesTest extends junit.framework.TestCase {
/**
* @tests java.util.Properties#list(java.io.PrintStream)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "list",
- args = {java.io.PrintStream.class}
- )
public void test_listLjava_io_PrintStream() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
Properties myProps = new Properties();
- String propList;
myProps.setProperty("Abba", "Cadabra");
myProps.setProperty("Open", "Sesame");
+ myProps.setProperty("LongProperty",
+ "a long long long long long long long property");
myProps.list(ps);
ps.flush();
- propList = baos.toString();
- assertTrue("Property list innacurate", (propList
- .indexOf("Abba=Cadabra") >= 0)
- && (propList.indexOf("Open=Sesame") >= 0));
+ String propList = baos.toString();
+ assertTrue("Property list innacurate",
+ propList.indexOf("Abba=Cadabra") >= 0);
+ assertTrue("Property list innacurate",
+ propList.indexOf("Open=Sesame") >= 0);
+ assertTrue("property list do not conatins \"...\"", propList
+ .indexOf("...") != -1);
+
+ ps = null;
+ try {
+ myProps.list(ps);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
}
/**
* @tests java.util.Properties#list(java.io.PrintWriter)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "list",
- args = {java.io.PrintWriter.class}
- )
public void test_listLjava_io_PrintWriter() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(baos);
Properties myProps = new Properties();
- String propList;
myProps.setProperty("Abba", "Cadabra");
myProps.setProperty("Open", "Sesame");
+ myProps.setProperty("LongProperty",
+ "a long long long long long long long property");
myProps.list(pw);
pw.flush();
- propList = baos.toString();
- assertTrue("Property list innacurate", (propList
- .indexOf("Abba=Cadabra") >= 0)
- && (propList.indexOf("Open=Sesame") >= 0));
+ String propList = baos.toString();
+ assertTrue("Property list innacurate",
+ propList.indexOf("Abba=Cadabra") >= 0);
+ assertTrue("Property list innacurate",
+ propList.indexOf("Open=Sesame") >= 0);
+ pw = null;
+ try {
+ myProps.list(pw);
+ fail("should throw NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
}
/**
- * @throws IOException
* @tests java.util.Properties#load(java.io.InputStream)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "load",
- args = {java.io.InputStream.class}
- )
- public void test_loadLjava_io_InputStream() throws IOException {
- Properties prop = new Properties();
- InputStream is = new ByteArrayInputStream(writeProperties());
- prop.load(is);
- is.close();
-
+ public void test_loadLjava_io_InputStream() {
+ // Test for method void java.util.Properties.load(java.io.InputStream)
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.load(is = new ByteArrayInputStream(writeProperties()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
assertEquals("Failed to load correct properties", "harmony.tests", prop
.getProperty("test.pkg"));
assertNull("Load failed to parse incorrectly", prop
.getProperty("commented.entry"));
prop = new Properties();
- prop.load(new ByteArrayInputStream("=".getBytes()));
+ try {
+ prop.load(new ByteArrayInputStream("=".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
assertTrue("Failed to add empty key", prop.get("").equals(""));
prop = new Properties();
- prop.load(new ByteArrayInputStream(" = ".getBytes()));
+ try {
+ prop.load(new ByteArrayInputStream(" = ".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
assertTrue("Failed to add empty key2", prop.get("").equals(""));
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(" a= b".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(" a b".getBytes()));
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream("#\u008d\u00d2\na=\u008d\u00d3"
+ .getBytes("ISO8859_1")));
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals("Failed to parse chars >= 0x80", "\u008d\u00d3", prop
+ .get("a"));
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream(
+ "#properties file\r\nfred=1\r\n#last comment"
+ .getBytes("ISO8859_1")));
+ } catch (IOException e) {
+ // expected
+ } catch (IndexOutOfBoundsException e) {
+ fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
+ }
+ assertEquals("Failed to load when last line contains a comment", "1",
+ prop.get("fred"));
+ }
+
+ /**
+ * @tests java.util.Properties#load(java.io.InputStream)
+ */
+ public void test_loadLjava_io_InputStream_subtest0() {
+ try {
+ InputStream is = Support_Resources
+ .getStream("hyts_PropertiesTest.properties");
+ Properties props = new Properties();
+ props.load(is);
+ is.close();
+ assertEquals("1", "\n \t \f", props.getProperty(" \r"));
+ assertEquals("2", "a", props.getProperty("a"));
+ assertEquals("3", "bb as,dn ", props.getProperty("b"));
+ assertEquals("4", ":: cu", props.getProperty("c\r \t\nu"));
+ assertEquals("5", "bu", props.getProperty("bu"));
+ assertEquals("6", "d\r\ne=e", props.getProperty("d"));
+ assertEquals("7", "fff", props.getProperty("f"));
+ assertEquals("8", "g", props.getProperty("g"));
+ assertEquals("9", "", props.getProperty("h h"));
+ assertEquals("10", "i=i", props.getProperty(" "));
+ assertEquals("11", " j", props.getProperty("j"));
+ assertEquals("12", " c", props.getProperty("space"));
+ assertEquals("13", "\\", props.getProperty("dblbackslash"));
+ } catch (IOException e) {
+ fail("Unexpected: " + e);
+ }
+ }
+
+ /**
+ * @throws IOException
+ * @tests java.util.Properties#load(java.io.Reader)
+ * @since 1.6
+ */
+ public void test_loadLjava_io_Reader() throws IOException {
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ is = new ByteArrayInputStream(writeProperties());
+ prop.load(new InputStreamReader(is));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "harmony.tests", prop
+ .getProperty("test.pkg"));
+ assertNull("Load failed to parse incorrectly", prop
+ .getProperty("commented.entry"));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=".getBytes()));
+ assertEquals("Failed to add empty key", "", prop.get(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream(" = ".getBytes()));
+ assertEquals("Failed to add empty key2", "", prop.get(""));
+
prop = new Properties();
prop.load(new ByteArrayInputStream(" a= b".getBytes()));
assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
@@ -229,42 +340,102 @@ public class PropertiesTest extends junit.framework.TestCase {
assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
prop = new Properties();
- prop.load(new ByteArrayInputStream("#\u008d\u00d2\na=\u008d\u00d3"
- .getBytes("ISO8859_1")));
- assertEquals("Failed to parse chars >= 0x80", "\u008d\u00d3", prop
- .get("a"));
+ prop.load(new ByteArrayInputStream("#comment\na=value"
+ .getBytes("UTF-8")));
+ assertEquals("value", prop.getProperty("a"));
prop = new Properties();
- prop.load(new ByteArrayInputStream(
- "#properties file\r\nfred=1\r\n#last comment"
- .getBytes("ISO8859_1")));
+ prop.load(new InputStreamReader(new ByteArrayInputStream(
+ "#\u008d\u00d2\na=\u008d\u00d3".getBytes("UTF-8"))));
+ try {
+ prop
+ .load(new InputStreamReader(new ByteArrayInputStream(
+ "#\u008d\u00d2\na=\\\\u008d\\\\\\uu00d3"
+ .getBytes("UTF-8"))));
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ prop = new Properties();
+ try {
+ prop.load(new InputStreamReader(new ByteArrayInputStream(
+ "#properties file\r\nfred=1\r\n#last comment"
+ .getBytes("ISO8859_1"))));
+ } catch (IndexOutOfBoundsException e) {
+ fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
+ }
assertEquals("Failed to load when last line contains a comment", "1",
prop.get("fred"));
- ByteArrayInputStream bais = new ByteArrayInputStream(new byte[]{'\\', 'u', 'x', 'x', 'x', 'x'});
+ // Regression tests for HARMONY-5414
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("a=\\u1234z".getBytes()));
+
+ prop = new Properties();
try {
- prop.load(bais);
- fail("IllegalArgumentException expected");
+ prop.load(new ByteArrayInputStream("a=\\u123".getBytes()));
+ fail("should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
- //expected
+ // Expected
+ }
+
+ prop = new Properties();
+ try {
+ prop.load(new ByteArrayInputStream("a=\\u123z".getBytes()));
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // Expected
}
+
+ prop = new Properties();
+ Properties expected = new Properties();
+ expected.put("a", "\u0000");
+ prop.load(new ByteArrayInputStream("a=\\".getBytes()));
+ assertEquals("Failed to read trailing slash value", expected, prop);
+
+ prop = new Properties();
+ expected = new Properties();
+ expected.put("a", "\u1234\u0000");
+ prop.load(new ByteArrayInputStream("a=\\u1234\\".getBytes()));
+ assertEquals("Failed to read trailing slash value #2", expected, prop);
+
+ prop = new Properties();
+ expected = new Properties();
+ expected.put("a", "q");
+ prop.load(new ByteArrayInputStream("a=\\q".getBytes()));
+ assertEquals("Failed to read slash value #3", expected, prop);
+ }
+
+ /**
+ * @tests java.util.Properties#load(java.io.InputStream)
+ */
+ public void test_loadLjava_io_InputStream_Special() throws IOException {
+ // Test for method void java.util.Properties.load(java.io.InputStream)
+ Properties prop = null;
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=".getBytes()));
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=\r\n".getBytes()));
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
+
+ prop = new Properties();
+ prop.load(new ByteArrayInputStream("=\n\r".getBytes()));
+ assertTrue("Failed to add empty key", prop.get("").equals(""));
}
/**
* @throws IOException
- * @tests java.util.Properties#load(java.io.InputStream)
+ * @tests java.util.Properties#load(java.io.Reader)
+ * @since 1.6
*/
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Doesn't verify IOException, IllegalArgumentException.",
- method = "load",
- args = {java.io.InputStream.class}
- )
- public void test_loadLjava_io_InputStream_subtest0() throws IOException {
+ public void test_loadLjava_io_Reader_subtest0() throws IOException {
InputStream is = Support_Resources
.getStream("hyts_PropertiesTest.properties");
Properties props = new Properties();
- props.load(is);
+ props.load(new InputStreamReader(is));
is.close();
assertEquals("1", "\n \t \f", props.getProperty(" \r"));
assertEquals("2", "a", props.getProperty("a"));
@@ -282,36 +453,240 @@ public class PropertiesTest extends junit.framework.TestCase {
}
/**
- * @throws IOException
+ * @tests java.util.Properties#propertyNames()
+ */
+ public void test_propertyNames() {
+ Properties myPro = new Properties(tProps);
+ Enumeration names = myPro.propertyNames();
+ int i = 0;
+ while (names.hasMoreElements()) {
+ ++i;
+ String p = (String) names.nextElement();
+ assertTrue("Incorrect names returned", p.equals("test.prop")
+ || p.equals("bogus.prop"));
+ }
+ }
+
+ public void test_propertyNames_sequence() {
+ Properties parent = new Properties();
+ parent.setProperty("parent.a.key", "parent.a.value");
+ parent.setProperty("parent.b.key", "parent.b.value");
+
+ Enumeration<?> names = parent.propertyNames();
+ assertEquals("parent.a.key", names.nextElement());
+ assertEquals("parent.b.key", names.nextElement());
+ assertFalse(names.hasMoreElements());
+
+ Properties current = new Properties(parent);
+ current.setProperty("current.a.key", "current.a.value");
+ current.setProperty("current.b.key", "current.b.value");
+
+ names = current.propertyNames();
+ assertEquals("parent.a.key", names.nextElement());
+ assertEquals("current.b.key", names.nextElement());
+ assertEquals("parent.b.key", names.nextElement());
+ assertEquals("current.a.key", names.nextElement());
+ assertFalse(names.hasMoreElements());
+
+ Properties child = new Properties(current);
+ child.setProperty("child.a.key", "child.a.value");
+ child.setProperty("child.b.key", "child.b.value");
+
+ names = child.propertyNames();
+ assertEquals("parent.a.key", names.nextElement());
+ assertEquals("child.b.key", names.nextElement());
+ assertEquals("current.b.key", names.nextElement());
+ assertEquals("parent.b.key", names.nextElement());
+ assertEquals("child.a.key", names.nextElement());
+ assertEquals("current.a.key", names.nextElement());
+ assertFalse(names.hasMoreElements());
+ }
+
+ /**
+ * @tests {@link java.util.Properties#stringPropertyNames()}
+ * @since 1.6
+ */
+ public void test_stringPropertyNames() {
+ Set<String> set = tProps.stringPropertyNames();
+ assertEquals(2, set.size());
+ assertTrue(set.contains("test.prop"));
+ assertTrue(set.contains("bogus.prop"));
+ assertNotSame(set, tProps.stringPropertyNames());
+
+ set = new Properties().stringPropertyNames();
+ assertEquals(0, set.size());
+
+ set = new Properties(System.getProperties()).stringPropertyNames();
+ assertTrue(set.size() > 0);
+
+ tProps = new Properties(tProps);
+ tProps.put("test.prop", "anotherValue");
+ tProps.put("3rdKey", "3rdValue");
+ set = tProps.stringPropertyNames();
+ assertEquals(3, set.size());
+ assertTrue(set.contains("test.prop"));
+ assertTrue(set.contains("bogus.prop"));
+ assertTrue(set.contains("3rdKey"));
+
+ tProps.put(String.class, "valueOfNonStringKey");
+ set = tProps.stringPropertyNames();
+ assertEquals(3, set.size());
+ assertTrue(set.contains("test.prop"));
+ assertTrue(set.contains("bogus.prop"));
+ assertTrue(set.contains("3rdKey"));
+
+ tProps.put("4thKey", "4thValue");
+ assertEquals(4, tProps.size());
+ assertEquals(3, set.size());
+
+ try {
+ set.add("another");
+ fail("Should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests {@link java.util.Properties#stringPropertyNames()}
+ * @since 1.6
+ */
+ public void test_stringPropertyNames_scenario1() {
+ String[] keys = new String[] { "key1", "key2", "key3" };
+ String[] values = new String[] { "value1", "value2", "value3" };
+ List<String> keyList = Arrays.asList(keys);
+
+ Properties properties = new Properties();
+ for (int index = 0; index < keys.length; index++) {
+ properties.setProperty(keys[index], values[index]);
+ }
+
+ properties = new Properties(properties);
+ Set<String> nameSet = properties.stringPropertyNames();
+ assertEquals(keys.length, nameSet.size());
+ Iterator<String> iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ Enumeration<?> nameEnum = properties.propertyNames();
+ int count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keys.length, count);
+
+ properties = new Properties(properties);
+ nameSet = properties.stringPropertyNames();
+ assertEquals(keys.length, nameSet.size());
+ iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ nameEnum = properties.propertyNames();
+ count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keys.length, count);
+ }
+
+ /**
+ * @tests {@link java.util.Properties#stringPropertyNames()}
+ * @since 1.6
+ */
+ public void test_stringPropertyNames_scenario2() {
+ String[] defaultKeys = new String[] { "defaultKey1", "defaultKey2",
+ "defaultKey3", "defaultKey4", "defaultKey5", "defaultKey6" };
+ String[] defaultValues = new String[] { "defaultValue1",
+ "defaultValue2", "defaultValue3", "defaultValue4",
+ "defaultValue5", "defaultValue6" };
+ List<String> keyList = new ArrayList<String>();
+ Properties defaults = new Properties();
+ for (int index = 0; index < 3; index++) {
+ defaults.setProperty(defaultKeys[index], defaultValues[index]);
+ keyList.add(defaultKeys[index]);
+ }
+
+ String[] keys = new String[] { "key1", "key2", "key3" };
+ String[] values = new String[] { "value1", "value2", "value3" };
+ Properties properties = new Properties(defaults);
+ for (int index = 0; index < keys.length; index++) {
+ properties.setProperty(keys[index], values[index]);
+ keyList.add(keys[index]);
+ }
+
+ Set<String> nameSet = properties.stringPropertyNames();
+ assertEquals(keyList.size(), nameSet.size());
+ Iterator<String> iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ Enumeration<?> nameEnum = properties.propertyNames();
+ int count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keyList.size(), count);
+
+ for (int index = 3; index < defaultKeys.length; index++) {
+ defaults.setProperty(defaultKeys[index], defaultValues[index]);
+ keyList.add(defaultKeys[index]);
+ }
+
+ nameSet = properties.stringPropertyNames();
+ assertEquals(keyList.size(), nameSet.size());
+ iterator = nameSet.iterator();
+ while (iterator.hasNext()) {
+ assertTrue(keyList.contains(iterator.next()));
+ }
+
+ nameEnum = properties.propertyNames();
+ count = 0;
+ while (nameEnum.hasMoreElements()) {
+ count++;
+ assertTrue(keyList.contains(nameEnum.nextElement()));
+ }
+ assertEquals(keyList.size(), count);
+ }
+
+ /**
* @tests java.util.Properties#save(java.io.OutputStream, java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "save",
- args = {java.io.OutputStream.class, java.lang.String.class}
- )
- public void test_saveLjava_io_OutputStreamLjava_lang_String()
- throws IOException {
+ public void test_saveLjava_io_OutputStreamLjava_lang_String() {
+ // Test for method void java.util.Properties.save(java.io.OutputStream,
+ // java.lang.String)
Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+
myProps.setProperty("Property A", "aye");
myProps.setProperty("Property B", "bee");
myProps.setProperty("Property C", "see");
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- myProps.save(out, "A Header");
- out.close();
-
- Properties myProps2 = new Properties();
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- myProps2.load(in);
- in.close();
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.save(out, "A Header");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.load(in);
+ in.close();
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
Enumeration e = myProps.propertyNames();
+ String nextKey;
while (e.hasMoreElements()) {
- String nextKey = (String) e.nextElement();
- assertTrue("Stored property list not equal to original", myProps2
- .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ nextKey = (String) e.nextElement();
+ assertEquals("Stored property list not equal to original", myProps
+ .getProperty(nextKey), myProps2.getProperty(nextKey));
}
}
@@ -319,13 +694,9 @@ public class PropertiesTest extends junit.framework.TestCase {
* @tests java.util.Properties#setProperty(java.lang.String,
* java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "setProperty",
- args = {java.lang.String.class, java.lang.String.class}
- )
public void test_setPropertyLjava_lang_StringLjava_lang_String() {
+ // Test for method java.lang.Object
+ // java.util.Properties.setProperty(java.lang.String, java.lang.String)
Properties myProps = new Properties();
myProps.setProperty("Yoink", "Yabba");
assertEquals("Failed to set property", "Yabba", myProps
@@ -336,93 +707,132 @@ public class PropertiesTest extends junit.framework.TestCase {
}
/**
- * @throws IOException
* @tests java.util.Properties#store(java.io.OutputStream, java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "store",
- args = {java.io.OutputStream.class, java.lang.String.class}
- )
- public void test_storeLjava_io_OutputStreamLjava_lang_String()
- throws IOException {
+ public void test_storeLjava_io_OutputStreamLjava_lang_String() {
+ // Test for method void java.util.Properties.store(java.io.OutputStream,
+ // java.lang.String)
Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+ Enumeration e;
+ String nextKey;
+
myProps.put("Property A", " aye\\\f\t\n\r\b");
myProps.put("Property B", "b ee#!=:");
myProps.put("Property C", "see");
- Properties myProps2 = new Properties();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- myProps.store(out, "A Header");
- myProps.store(out, null);
- out.close();
-
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- myProps2.load(in);
- in.close();
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.store(out, "A Header");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.load(in);
+ in.close();
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
- Enumeration e = myProps.propertyNames();
+ e = myProps.propertyNames();
while (e.hasMoreElements()) {
- String nextKey = (String) e.nextElement();
+ nextKey = (String) e.nextElement();
assertTrue("Stored property list not equal to original", myProps2
.getProperty(nextKey).equals(myProps.getProperty(nextKey)));
}
-
- try {
- myProps.store(null, "String");
- fail("NullPointerException expected");
- } catch (NullPointerException ee){
- //expected
- }
+
}
/**
* @throws IOException
- * @tests java.util.Properties#loadFromXML(java.io.InputStream)
+ * @tests java.util.Properties#store(java.io.Writer, java.lang.String)
+ * @since 1.6
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "loadFromXML",
- args = {java.io.InputStream.class}
- )
- public void test_loadFromXMLLjava_io_InputStream() throws IOException {
+ public void test_storeLjava_io_WriterLjava_lang_String() throws IOException {
Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+
myProps.put("Property A", " aye\\\f\t\n\r\b");
myProps.put("Property B", "b ee#!=:");
myProps.put("Property C", "see");
- Properties myProps2 = new Properties();
ByteArrayOutputStream out = new ByteArrayOutputStream();
- myProps.storeToXML(out, "A Header");
+ myProps.store(new OutputStreamWriter(out), "A Header");
+ Scanner scanner = new Scanner(out.toString());
+ assertTrue(scanner.nextLine().startsWith("#A Header"));
+ assertTrue(scanner.nextLine().startsWith("#"));
out.close();
-
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ myProps2.load(in);
+ in.close();
+
+ Enumeration e = myProps.propertyNames();
+ String nextKey;
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+
try {
- myProps2.loadFromXML(in);
- fail("InvalidPropertiesFormatException expected");
- } catch (InvalidPropertiesFormatException e) {
- //expected
+ myProps.store((Writer) null, "some comments");
+ fail("Should throw NullPointerException");
+ } catch (NullPointerException e1) {
+ // expected
}
- in.close();
-
-
- Properties prop = new Properties();
- InputStream is = new ByteArrayInputStream(writePropertiesXML("UTF-8"));
- prop.loadFromXML(is);
- is.close();
+ myProps.put(String.class, "wrong type");
+ try {
+ myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+ "some comments");
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e1) {
+ // expected
+ }
+ myProps.remove(String.class);
+ myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+ "some comments");
+ // it is OK
+ myProps.put("wrong type", String.class);
+ try {
+ myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+ "some comments");
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException e1) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests java.util.Properties#loadFromXML(java.io.InputStream)
+ */
+ public void test_loadFromXMLLjava_io_InputStream() throws Exception {
+ // Test for method void
+ // java.util.Properties.loadFromXML(java.io.InputStream)
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.loadFromXML(is = new ByteArrayInputStream(
+ writePropertiesXMLUTF_8()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
assertEquals("Failed to load correct properties", "value3", prop
.getProperty("key3"));
assertEquals("Failed to load correct properties", "value1", prop
.getProperty("key1"));
- prop = new Properties();
- is = new ByteArrayInputStream(writePropertiesXML("ISO-8859-1"));
- prop.loadFromXML(is);
- is.close();
-
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.loadFromXML(is = new ByteArrayInputStream(
+ writePropertiesXMLISO_8859_1()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
assertEquals("Failed to load correct properties", "value2", prop
.getProperty("key2"));
assertEquals("Failed to load correct properties", "value1", prop
@@ -430,26 +840,26 @@ public class PropertiesTest extends junit.framework.TestCase {
try {
prop.loadFromXML(null);
- fail("NullPointerException expected");
+ fail("should throw NullPointerException");
} catch (NullPointerException e) {
- //expected
+ // expected
}
}
/**
- * @throws IOException
* @tests java.util.Properties#storeToXML(java.io.OutputStream,
* java.lang.String, java.lang.String)
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "storeToXML",
- args = {java.io.OutputStream.class, java.lang.String.class, java.lang.String.class}
- )
public void test_storeToXMLLjava_io_OutputStreamLjava_lang_StringLjava_lang_String()
- throws IOException {
+ throws Exception {
+ // Test for method void
+ // java.util.Properties.storeToXML(java.io.OutputStream,
+ // java.lang.String, java.lang.String)
Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+ Enumeration e;
+ String nextKey;
+
myProps.setProperty("key1", "value1");
myProps.setProperty("key2", "value2");
myProps.setProperty("key3", "value3");
@@ -465,126 +875,153 @@ public class PropertiesTest extends junit.framework.TestCase {
myProps.setProperty("<a>&amp;key13&lt;</a>",
"&amp;&value13<b>&amp;</b>");
- // store in UTF-8 encoding
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- myProps.storeToXML(out, "comment");
- out.close();
-
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- Properties myProps2 = new Properties();
- myProps2.loadFromXML(in);
- in.close();
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
- Enumeration e = myProps.propertyNames();
- while (e.hasMoreElements()) {
- String nextKey = (String) e.nextElement();
- assertTrue("Stored property list not equal to original", myProps2
- .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ // store in UTF-8 encoding
+ myProps.storeToXML(out, "comment");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.loadFromXML(in);
+ in.close();
+ } catch (InvalidPropertiesFormatException ipfe) {
+ fail("InvalidPropertiesFormatException occurred reading file: "
+ + ipfe.getMessage());
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
}
- // store in ISO-8859-1 encoding
- out = new ByteArrayOutputStream();
- myProps.storeToXML(out, "comment", "ISO-8859-1");
- out.close();
-
- in = new ByteArrayInputStream(out.toByteArray());
- myProps2 = new Properties();
- myProps2.loadFromXML(in);
- in.close();
-
e = myProps.propertyNames();
while (e.hasMoreElements()) {
- String nextKey = (String) e.nextElement();
+ nextKey = (String) e.nextElement();
assertTrue("Stored property list not equal to original", myProps2
.getProperty(nextKey).equals(myProps.getProperty(nextKey)));
}
- out = new ByteArrayOutputStream();
- myProps.storeToXML(out, "comment", "ISO-8859-1");
- myProps.storeToXML(out, null, "ISO-8859-1");
- out.close();
-
- try {
- myProps.storeToXML(out, "comment", null);
- fail("NulPointerException expected");
- } catch (NullPointerException ee) {
- //expected
- }
-
try {
- myProps.storeToXML(null, "comment", "ISO-8859-1");
- fail("NulPointerException expected");
- } catch (NullPointerException ee) {
- //expected
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ // store in ISO-8859-1 encoding
+ myProps.storeToXML(out, "comment", "ISO-8859-1");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2 = new Properties();
+ myProps2.loadFromXML(in);
+ in.close();
+ } catch (InvalidPropertiesFormatException ipfe) {
+ fail("InvalidPropertiesFormatException occurred reading file: "
+ + ipfe.getMessage());
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
}
- }
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "storeToXML",
- args = {java.io.OutputStream.class, java.lang.String.class}
- )
- public void test_storeToXMLLjava_io_OutputStreamLjava_lang_String()
- throws IOException {
- Properties myProps = new Properties();
- myProps.put("Property A", "value 1");
- myProps.put("Property B", "value 2");
- myProps.put("Property C", "value 3");
-
- Properties myProps2 = new Properties();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- myProps.storeToXML(out, "A Header");
- out.close();
-
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- myProps2.loadFromXML(in);
- in.close();
-
- Enumeration e = myProps.propertyNames();
+ e = myProps.propertyNames();
while (e.hasMoreElements()) {
- String nextKey = (String) e.nextElement();
+ nextKey = (String) e.nextElement();
assertTrue("Stored property list not equal to original", myProps2
.getProperty(nextKey).equals(myProps.getProperty(nextKey)));
}
try {
- myProps.storeToXML(null, "String");
- fail("NullPointerException expected");
- } catch (NullPointerException ee){
- //expected
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ myProps.storeToXML(out, null, null);
+ fail("should throw nullPointerException");
+ } catch (NullPointerException ne) {
+ // expected
}
}
+
+ /**
+ * if loading from single line like "hello" without "\n\r" neither "=", it
+ * should be same as loading from "hello="
+ */
+ public void testLoadSingleLine() throws Exception{
+ Properties props = new Properties();
+ InputStream sr = new ByteArrayInputStream("hello".getBytes());
+ props.load(sr);
+ assertEquals(1, props.size());
+ }
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "propertyNames",
- args = {}
- )
- public void test_propertyNames() {
- Properties myProps = new Properties();
- myProps.put("Property A", "value 1");
- myProps.put("Property B", "value 2");
- myProps.put("Property C", "value 3");
-
- Enumeration e = myProps.propertyNames();
-
- int count = 0;
- while (e.hasMoreElements()) {
- count++;
- assertTrue(myProps.containsKey(e.nextElement()));
- }
-
- assertTrue(myProps.size() == count);
+ public void test_SequentialpropertyNames() {
+ Properties parent = new Properties();
+ parent.setProperty("parent.a.key", "parent.a.value");
+ parent.setProperty("parent.b.key", "parent.b.value");
+
+ Enumeration<?> names = parent.propertyNames();
+ assertEquals("parent.a.key", names.nextElement());
+ assertEquals("parent.b.key", names.nextElement());
+ assertFalse(names.hasMoreElements());
+
+ Properties current = new Properties(parent);
+ current.setProperty("current.a.key", "current.a.value");
+ current.setProperty("current.b.key", "current.b.value");
+
+ names = current.propertyNames();
+ assertEquals("parent.a.key", names.nextElement());
+ assertEquals("current.b.key", names.nextElement());
+ assertEquals("parent.b.key", names.nextElement());
+ assertEquals("current.a.key", names.nextElement());
+ assertFalse(names.hasMoreElements());
+
+ Properties child = new Properties(current);
+ child.setProperty("child.a.key", "child.a.value");
+ child.setProperty("child.b.key", "child.b.value");
+
+ names = child.propertyNames();
+ assertEquals("parent.a.key", names.nextElement());
+ assertEquals("child.b.key", names.nextElement());
+ assertEquals("current.b.key", names.nextElement());
+ assertEquals("parent.b.key", names.nextElement());
+ assertEquals("child.a.key", names.nextElement());
+ assertEquals("current.a.key", names.nextElement());
+ assertFalse(names.hasMoreElements());
+ }
+
+ public void test_SequentialstringPropertyNames() {
+ Properties parent = new Properties();
+ parent.setProperty("parent.a.key", "parent.a.value");
+ parent.setProperty("parent.b.key", "parent.b.value");
+
+ Iterator<String> nameIterator = parent.stringPropertyNames().iterator();
+ assertEquals("parent.a.key", nameIterator.next());
+ assertEquals("parent.b.key", nameIterator.next());
+ assertFalse(nameIterator.hasNext());
+
+ Properties current = new Properties(parent);
+ current.setProperty("current.a.key", "current.a.value");
+ current.setProperty("current.b.key", "current.b.value");
+
+ nameIterator = current.stringPropertyNames().iterator();
+ assertEquals("parent.a.key", nameIterator.next());
+ assertEquals("current.b.key", nameIterator.next());
+ assertEquals("parent.b.key", nameIterator.next());
+ assertEquals("current.a.key", nameIterator.next());
+ assertFalse(nameIterator.hasNext());
+
+ Properties child = new Properties(current);
+ child.setProperty("child.a.key", "child.a.value");
+ child.setProperty("child.b.key", "child.b.value");
+
+ nameIterator = child.stringPropertyNames().iterator();
+ assertEquals("parent.a.key", nameIterator.next());
+ assertEquals("child.b.key", nameIterator.next());
+ assertEquals("current.b.key", nameIterator.next());
+ assertEquals("parent.b.key", nameIterator.next());
+ assertEquals("child.a.key", nameIterator.next());
+ assertEquals("current.a.key", nameIterator.next());
+ assertFalse(nameIterator.hasNext());
}
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
- protected void setUp() throws Exception {
- super.setUp();
+ protected void setUp() {
+
tProps = new Properties();
tProps.put("test.prop", "this is a test property");
tProps.put("bogus.prop", "bogus");
@@ -594,14 +1031,17 @@ public class PropertiesTest extends junit.framework.TestCase {
* Tears down the fixture, for example, close a network connection. This
* method is called after a test is executed.
*/
- protected void tearDown() throws Exception {
- tProps = null;
- super.tearDown();
+ protected void tearDown() {
}
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
protected byte[] writeProperties() throws IOException {
+ PrintStream ps = null;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(bout);
+ ps = new PrintStream(bout);
ps.println("#commented.entry=Bogus");
ps.println("test.pkg=harmony.tests");
ps.println("test.proj=Automated Tests");
@@ -609,10 +1049,29 @@ public class PropertiesTest extends junit.framework.TestCase {
return bout.toByteArray();
}
- protected byte[] writePropertiesXML(String encoding) throws IOException {
+ protected byte[] writePropertiesXMLUTF_8() throws IOException {
+ PrintStream ps = null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ps = new PrintStream(bout, true, "UTF-8");
+ ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ ps
+ .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
+ ps.println("<properties>");
+ ps.println("<comment>comment</comment>");
+ ps.println("<entry key=\"key4\">value4</entry>");
+ ps.println("<entry key=\"key3\">value3</entry>");
+ ps.println("<entry key=\"key2\">value2</entry>");
+ ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
+ ps.println("</properties>");
+ ps.close();
+ return bout.toByteArray();
+ }
+
+ protected byte[] writePropertiesXMLISO_8859_1() throws IOException {
+ PrintStream ps = null;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(bout, true, encoding);
- ps.println("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>");
+ ps = new PrintStream(bout, true, "ISO-8859-1");
+ ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
ps
.println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
ps.println("<properties>");
diff --git a/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java b/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
index 480c998..52a2409 100644
--- a/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
+++ b/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
@@ -188,7 +188,7 @@ public class ResourceBundleTest extends junit.framework.TestCase {
}
try {
- ResourceBundle.getBundle(name, Locale.getDefault(), null);
+ ResourceBundle.getBundle(name, Locale.getDefault(), (ClassLoader) null);
fail("NullPointerException expected");
} catch (NullPointerException ee) {
//expected