harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zhouke...@apache.org
Subject svn commit: r958912 - in /harmony/enhanced/java/trunk/classlib/modules/luni/src: main/java/java/util/Properties.java test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java
Date Tue, 29 Jun 2010 10:14:01 GMT
Author: zhoukevin
Date: Tue Jun 29 10:14:01 2010
New Revision: 958912

URL: http://svn.apache.org/viewvc?rev=958912&view=rev
Log:
As to java.util.Properties.store(os, comments) method, if the comments argument is not null,
then '#' character and a line separator are first written to the output stream. Thus, the
comments can serve as an identifying comment. Any '\n', '\r' or "\r\n" in comments is replaced
by a line separator generated by the Writer and if the next character in comments is not character
# or character ! then an ASCII # is written out after that line separator.
This patch fixes the above issue. In addition, it includes several test cases for coverage.

Modified:
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/util/Properties.java
    harmony/enhanced/java/trunk/classlib/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/util/Properties.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/util/Properties.java?rev=958912&r1=958911&r2=958912&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/util/Properties.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/java/util/Properties.java
Tue Jun 29 10:14:01 2010
@@ -25,6 +25,7 @@ import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringReader;
+import java.io.Writer;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException;
@@ -97,15 +98,15 @@ public class Properties extends Hashtabl
         defaults = properties;
     }
 
-    private void dumpString(StringBuilder buffer, String string, boolean key) {
-        int i = 0;
-        if (!key && i < string.length() && string.charAt(i) == ' ') {
+    private void dumpString(StringBuilder buffer, String string, boolean isKey) {
+        int index = 0, length = string.length();
+        if (!isKey && index < length && string.charAt(index) == ' ') {
             buffer.append("\\ "); //$NON-NLS-1$
-            i++;
+            index++;
         }
 
-        for (; i < string.length(); i++) {
-            char ch = string.charAt(i);
+        for (; index < length; index++) {
+            char ch = string.charAt(index);
             switch (ch) {
             case '\t':
                 buffer.append("\\t"); //$NON-NLS-1$
@@ -120,23 +121,33 @@ public class Properties extends Hashtabl
                 buffer.append("\\r"); //$NON-NLS-1$
                 break;
             default:
-                if ("\\#!=:".indexOf(ch) >= 0 || (key && ch == ' ')) {
+                if ("\\#!=:".indexOf(ch) >= 0 || (isKey && ch == ' ')) {
                     buffer.append('\\');
                 }
                 if (ch >= ' ' && ch <= '~') {
                     buffer.append(ch);
                 } else {
-                    String hex = Integer.toHexString(ch);
-                    buffer.append("\\u"); //$NON-NLS-1$
-                    for (int j = 0; j < 4 - hex.length(); j++) {
-                        buffer.append("0"); //$NON-NLS-1$
-                    }
-                    buffer.append(hex);
+                    buffer.append(toHexaDecimal(ch));
                 }
             }
         }
     }
 
+    private char[] toHexaDecimal(final int ch) {
+        char[] hexChars = { '\\', 'u', '0', '0', '0', '0' };
+        int hexChar, index = hexChars.length, copyOfCh = ch;
+        do {
+            hexChar = copyOfCh & 15;
+            if (hexChar > 9) {
+                hexChar = hexChar - 10 + 'A';
+            } else {
+                hexChar += '0';
+            }
+            hexChars[--index] = (char) hexChar;
+        } while ((copyOfCh >>>= 4) != 0);
+        return hexChars;
+    }
+
     /**
      * Searches for the property with the specified name. If the property is not
      * found, the default {@code Properties} are checked. If the property is not
@@ -412,7 +423,7 @@ public class Properties extends Hashtabl
                     }
                     break;
                 }
-                if (Character.isWhitespace(nextChar)) {
+                if (nextChar < 256 && Character.isWhitespace(nextChar)) {
                     if (mode == CONTINUE) {
                         mode = IGNORE;
                     }
@@ -504,36 +515,36 @@ public class Properties extends Hashtabl
     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
+     * 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}.
+     * @param out
+     *            the {@code OutputStream} to write to.
+     * @param comments
+     *            the comments 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}.
      */
-    public synchronized void store(OutputStream out, String comment)
+    public synchronized void store(OutputStream out, String comments)
             throws IOException {
         if (lineSeparator == null) {
             lineSeparator = AccessController
                     .doPrivileged(new PriviAction<String>("line.separator")); //$NON-NLS-1$
         }
-
-        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(comment);
-            writer.write(lineSeparator);
+        if (comments != null) {
+            writeComments(writer, comments);
         }
-        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);
@@ -546,6 +557,32 @@ public class Properties extends Hashtabl
         writer.flush();
     }
 
+    private void writeComments(Writer writer, String comments)
+            throws IOException {
+        writer.write('#');
+        char[] chars = comments.toCharArray();
+        for (int index = 0; index < chars.length; index++) {
+            if (chars[index] == '\r' || chars[index] == '\n') {
+                int indexPlusOne = index + 1;
+                if (chars[index] == '\r' && indexPlusOne < chars.length
+                        && chars[indexPlusOne] == '\n') {
+                    // "\r\n"
+                    continue;
+                }
+                writer.write(lineSeparator);
+                if (indexPlusOne < chars.length
+                        && (chars[indexPlusOne] == '#' || chars[indexPlusOne] ==
'!')) {
+                    // return char with either '#' or '!' afterward
+                    continue;
+                }
+                writer.write('#');
+            } else {
+                writer.write(chars[index]);
+            }
+        }
+        writer.write(lineSeparator);
+    }
+
     /**
      * Loads the properties from an {@code InputStream} containing the
      * properties in XML form. The XML document must begin with (and conform to)

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java?rev=958912&r1=958911&r2=958912&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/PropertiesTest.java
Tue Jun 29 10:14:01 2010
@@ -17,10 +17,12 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
+import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.util.Enumeration;
@@ -541,6 +543,131 @@ public class PropertiesTest extends juni
         assertEquals(1, props.size());
     }
 
+    private String comment1 = "comment1";
+
+    private String comment2 = "comment2";
+
+    private void validateOutput(String[] expectStrings, byte[] output)
+            throws IOException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(output);
+        BufferedReader br = new BufferedReader(new InputStreamReader(bais,
+                "ISO8859_1"));
+        for (String expectString : expectStrings) {
+            assertEquals(expectString, br.readLine());
+        }
+        br.readLine();
+        assertNull(br.readLine());
+        br.close();
+    }
+
+    public void testStore_scenario0() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario1() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario2() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '\n' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario3() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '\r' + comment2);
+        validateOutput(new String[] { "#comment1", "#", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario4() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario5() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario6() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario7() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario8() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '\n' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario9() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '\r' + '#' + comment2);
+        validateOutput(new String[] { "#comment1", "#", "#comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario10() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\r' + '\n' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
+    public void testStore_scenario11() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        props.store(baos, comment1 + '\n' + '\r' + '!' + comment2);
+        validateOutput(new String[] { "#comment1", "#", "!comment2" },
+                baos.toByteArray());
+        baos.close();
+    }
+
     /**
      * Sets up the fixture, for example, open a network connection. This method
      * is called before a test is executed.



Mime
View raw message