Apply patch FELIX-2887 to add some new functionality to property handling.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1172744 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/utils/src/main/java/org/apache/felix/utils/properties/Properties.java b/utils/src/main/java/org/apache/felix/utils/properties/Properties.java
index 6c6743c..a0cbf36 100644
--- a/utils/src/main/java/org/apache/felix/utils/properties/Properties.java
+++ b/utils/src/main/java/org/apache/felix/utils/properties/Properties.java
@@ -29,7 +29,17 @@
import java.io.Reader;
import java.io.Writer;
import java.net.URL;
-import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
/**
* <p>
@@ -57,7 +67,11 @@
private static final String DEFAULT_ENCODING = "ISO-8859-1";
/** Constant for the platform specific line separator.*/
- private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+ private static final String LINE_SEPARATOR = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("line.separator");
+ }
+ });
/** Constant for the radix of hex numbers.*/
private static final int HEX_RADIX = 16;
@@ -65,8 +79,8 @@
/** Constant for the length of a unicode literal.*/
private static final int UNICODE_LEN = 4;
- private Map<String,String> storage = new LinkedHashMap<String,String>();
- private Map<String,Layout> layout = new LinkedHashMap<String,Layout>();
+ private final Map<String,String> storage = new LinkedHashMap<String,String>();
+ private final Map<String,Layout> layout = new LinkedHashMap<String,Layout>();
private List<String> header;
private List<String> footer;
private File location;
@@ -203,6 +217,50 @@
return old;
}
+ public String put(String key, List<String> commentLines, List<String> valueLines) {
+ commentLines = new ArrayList<String>(commentLines);
+ valueLines = new ArrayList<String>(valueLines);
+ String escapedKey = escapeKey(key);
+ int lastLine = valueLines.size() - 1;
+ if (valueLines.isEmpty()) {
+ valueLines.add(escapedKey + "=");
+ } else if (!valueLines.get(0).trim().startsWith(escapedKey)) {
+ valueLines.set(0, escapedKey + " = " + escapeJava(valueLines.get(0)) + (0 < lastLine? "\\": ""));
+ }
+ for (int i = 1; i < valueLines.size(); i++) {
+ valueLines.set(i, escapeJava(valueLines.get(i)) + (i < lastLine? "\\": ""));
+ }
+ StringBuilder value = new StringBuilder();
+ for (String line: valueLines) {
+ value.append(line);
+ }
+ this.layout.put(key, new Layout(commentLines, valueLines));
+ return storage.put(key, unescapeJava(value.toString()));
+ }
+
+ public String put(String key, List<String> commentLines, String value) {
+ commentLines = new ArrayList<String>(commentLines);
+ this.layout.put(key, new Layout(commentLines, null));
+ return storage.put(key, value);
+ }
+
+ public String put(String key, String comment, String value) {
+ return put(key, Collections.singletonList(comment), value);
+ }
+
+ public List<String> getRaw(String key) {
+ if (layout.containsKey(key)) {
+ if (layout.get(key).getValueLines() != null) {
+ return new ArrayList<String>(layout.get(key).getValueLines());
+ }
+ }
+ List<String> result = new ArrayList<String>();
+ if (storage.containsKey(key)) {
+ result.add(storage.get(key));
+ }
+ return result;
+ }
+
@Override
public String remove(Object key) {
Layout l = layout.get(key);
@@ -589,6 +647,35 @@
}
/**
+ * Escape the separators in the key.
+ *
+ * @param key the key
+ * @return the escaped key
+ */
+ private static String escapeKey(String key)
+ {
+ StringBuffer newkey = new StringBuffer();
+
+ for (int i = 0; i < key.length(); i++)
+ {
+ char c = key.charAt(i);
+
+ if (contains(SEPARATORS, c) || contains(WHITE_SPACE, c))
+ {
+ // escape the separator
+ newkey.append('\\');
+ newkey.append(c);
+ }
+ else
+ {
+ newkey.append(c);
+ }
+ }
+
+ return newkey.toString();
+ }
+
+ /**
* This class is used to read properties lines. These lines do
* not terminate with new-line chars but rather when there is no
* backslash sign a the end of the line. This is used to
@@ -597,10 +684,10 @@
public static class PropertiesReader extends LineNumberReader
{
/** Stores the comment lines for the currently processed property.*/
- private List<String> commentLines;
+ private final List<String> commentLines;
/** Stores the value lines for the currently processed property.*/
- private List<String> valueLines;
+ private final List<String> valueLines;
/** Stores the name of the last read property.*/
private String propertyName;
@@ -894,35 +981,6 @@
}
/**
- * Escape the separators in the key.
- *
- * @param key the key
- * @return the escaped key
- */
- private String escapeKey(String key)
- {
- StringBuffer newkey = new StringBuffer();
-
- for (int i = 0; i < key.length(); i++)
- {
- char c = key.charAt(i);
-
- if (contains(SEPARATORS, c) || contains(WHITE_SPACE, c))
- {
- // escape the separator
- newkey.append('\\');
- newkey.append(c);
- }
- else
- {
- newkey.append(c);
- }
- }
-
- return newkey.toString();
- }
-
- /**
* Helper method for writing a line with the platform specific line
* ending.
*
diff --git a/utils/src/test/java/org/apache/felix/utils/properties/PropertiesTest.java b/utils/src/test/java/org/apache/felix/utils/properties/PropertiesTest.java
index 3f06738..fa8c48d 100644
--- a/utils/src/test/java/org/apache/felix/utils/properties/PropertiesTest.java
+++ b/utils/src/test/java/org/apache/felix/utils/properties/PropertiesTest.java
@@ -20,7 +20,10 @@
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
+import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
import junit.framework.TestCase;
/**
@@ -33,6 +36,13 @@
public class PropertiesTest extends TestCase {
private final static String TEST_PROPERTIES_FILE = "test.properties";
+ private final static String LINE_SEPARATOR = System.getProperty("line.separator");
+ private static final String COMMENT = "# comment";
+ private static final String KEY1 = "mvn:foo/bar";
+ private static final String KEY1A = "mvn\\:foo/bar";
+ private static final String KEY2 = "foo:bar:version:type:classifier";
+ private static final String KEY2A = "foo\\:bar\\:version\\:type\\:classifier";
+ private static final String VALUE1 = "value";
private Properties properties;
@@ -105,4 +115,44 @@
properties.store(System.err, null);
System.err.println("====");
}
+
+ private static final String RESULT1 = COMMENT + LINE_SEPARATOR + KEY1A + " = " + VALUE1 + LINE_SEPARATOR;
+
+ public void testSaveComment1() throws Exception {
+ properties.put(KEY1, COMMENT, VALUE1);
+ StringWriter sw = new StringWriter();
+ properties.save(sw);
+ assertTrue(sw.toString(), sw.toString().endsWith(RESULT1));
+ }
+
+ private static final String RESULT1A = COMMENT + LINE_SEPARATOR + KEY2A + " = " + VALUE1 + LINE_SEPARATOR;
+
+ public void testSaveComment1a() throws Exception {
+ properties.put(KEY2, COMMENT, VALUE1);
+ StringWriter sw = new StringWriter();
+ properties.save(sw);
+ assertTrue(sw.toString(), sw.toString().endsWith(RESULT1A));
+ }
+
+ private static final String RESULT2 = COMMENT + LINE_SEPARATOR + COMMENT + LINE_SEPARATOR + KEY1A + " = " + VALUE1 + LINE_SEPARATOR;
+
+ public void testSaveComment2() throws Exception {
+ properties.put(KEY1, Arrays.asList(new String[] {COMMENT, COMMENT}), VALUE1);
+ StringWriter sw = new StringWriter();
+ properties.save(sw);
+ assertTrue(sw.toString(), sw.toString().endsWith(RESULT2));
+ }
+
+ private static final String RESULT3 = COMMENT + LINE_SEPARATOR + COMMENT + LINE_SEPARATOR + KEY1A + " = " + VALUE1 + "\\" + LINE_SEPARATOR+ VALUE1 + LINE_SEPARATOR;
+
+ public void testSaveComment3() throws Exception {
+ properties.put(KEY1, Arrays.asList(new String[] {COMMENT, COMMENT}), Arrays.asList(new String[] {VALUE1, VALUE1}));
+ StringWriter sw = new StringWriter();
+ properties.save(sw);
+ assertTrue(sw.toString(), sw.toString().endsWith(RESULT3));
+ List<String> rawValue = properties.getRaw(KEY1);
+ assertEquals(2, rawValue.size());
+ assertEquals(KEY1A + " = " + VALUE1 + "\\", rawValue.get(0));
+ assertEquals(VALUE1, rawValue.get(1));
+ }
}