Browse Source

style

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@687617 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 17 years ago
parent
commit
0fccd329c1
2 changed files with 253 additions and 209 deletions
  1. +136
    -115
      src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
  2. +117
    -94
      src/tests/junit/org/apache/tools/ant/util/LayoutPreservingPropertiesTest.java

+ 136
- 115
src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java View File

@@ -79,31 +79,32 @@ import java.util.Properties;
*/
public class LayoutPreservingProperties extends Properties {
private static final String LS = System.getProperty("line.separator");
/**
* Logical lines have escaping and line continuation taken care of. Comments
* and blank lines are logical lines; they are not removed.
* Logical lines have escaping and line continuation taken care
* of. Comments and blank lines are logical lines; they are not
* removed.
*/
private ArrayList logicalLines = new ArrayList();
/**
* Position in the <code>logicalLines</code> list, keyed by property name.
*/
private HashMap keyedPairLines = new HashMap();
/**
* Flag to indicate that, when we remove a property from the file, we
* also want to remove the comments that precede it.
*/
private boolean removeComments;
/**
* Create a new, empty, Properties collection, with no defaults.
*/
public LayoutPreservingProperties() {
super();
}
/**
* Create a new, empty, Properties collection, with the specified defaults.
* @param defaults the default property values
@@ -113,58 +114,63 @@ public class LayoutPreservingProperties extends Properties {
}

/**
* Returns <code>true</code> if comments are removed along with properties, or
* <code>false</code> otherwise. If <code>true</code>, then when a property is
* removed, the comment preceding it in the original file is removed also.
* @return <code>true</code> if leading comments are removed when a property is
* removed; <code>false</code> otherwise
* Returns <code>true</code> if comments are removed along with
* properties, or <code>false</code> otherwise. If
* <code>true</code>, then when a property is removed, the comment
* preceding it in the original file is removed also.
* @return <code>true</code> if leading comments are removed when
* a property is removed; <code>false</code> otherwise
*/
public boolean isRemoveComments() {
return removeComments;
}
/**
* Sets the behaviour for comments accompanying properties that are being
* removed. If <code>true</code>, then when a property is removed, the comment
* preceding it in the original file is removed also.
* @param val <code>true</code> if leading comments are to be removed when a property is
* removed; <code>false</code> otherwise
* Sets the behaviour for comments accompanying properties that
* are being removed. If <code>true</code>, then when a property
* is removed, the comment preceding it in the original file is
* removed also.
* @param val <code>true</code> if leading comments are to be
* removed when a property is removed; <code>false</code>
* otherwise
*/
public void setRemoveComments(boolean val) {
removeComments = val;
}
public void load(InputStream inStream) throws IOException {
String s = readLines(inStream);
byte[] ba = s.getBytes("ISO-8859-1");
ByteArrayInputStream bais = new ByteArrayInputStream(ba);
super.load(bais);
}
public Object put(Object key, Object value) throws NullPointerException {
Object obj = super.put(key, value);
// the above call will have failed if key or value are null
innerSetProperty(key.toString(), value.toString());
return obj;
}
public Object setProperty(String key, String value) throws NullPointerException {

public Object setProperty(String key, String value)
throws NullPointerException {
Object obj = super.setProperty(key, value);
// the above call will have failed if key or value are null
innerSetProperty(key, value);
return obj;
}
/**
* Store a new key-value pair, or add a new one. The normal functionality is
* taken care of by the superclass in the call to {@link #setProperty}; this
* method takes care of this classes extensions.
* Store a new key-value pair, or add a new one. The normal
* functionality is taken care of by the superclass in the call to
* {@link #setProperty}; this method takes care of this classes
* extensions.
* @param key the key of the property to be stored
* @param value the value to be stored
*/
private void innerSetProperty(String key, String value) {
value = escapeValue(value);
if (keyedPairLines.containsKey(key)) {
Integer i = (Integer) keyedPairLines.get(key);
Pair p = (Pair) logicalLines.get(i.intValue());
@@ -177,13 +183,13 @@ public class LayoutPreservingProperties extends Properties {
logicalLines.add(p);
}
}
public void clear() {
super.clear();
keyedPairLines.clear();
logicalLines.clear();
}
public Object remove(Object key) {
Object obj = super.remove(key);
Integer i = (Integer) keyedPairLines.remove(key);
@@ -195,9 +201,10 @@ public class LayoutPreservingProperties extends Properties {
}
return obj;
}
public Object clone() {
LayoutPreservingProperties dolly = (LayoutPreservingProperties) super.clone();
LayoutPreservingProperties dolly =
(LayoutPreservingProperties) super.clone();
dolly.keyedPairLines = (HashMap) this.keyedPairLines.clone();
dolly.logicalLines = (ArrayList) this.logicalLines.clone();
for (int j = 0; j < dolly.logicalLines.size(); j++) {
@@ -210,7 +217,7 @@ public class LayoutPreservingProperties extends Properties {
}
return dolly;
}
/**
* Echo the lines of the properties (including blanks and comments) to the
* stream.
@@ -232,7 +239,7 @@ public class LayoutPreservingProperties extends Properties {
}
}
}
/**
* Save the properties to a file.
* @param dest the file to write to
@@ -242,15 +249,15 @@ public class LayoutPreservingProperties extends Properties {
store(fos, null);
fos.close();
}
public void store(OutputStream out, String header) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(out, "ISO-8859-1");
if (header != null) {
osw.write("#" + header + LS);
}
osw.write("#" + (new Date()).toString() + LS);
boolean writtenSep = false;
for (Iterator i = logicalLines.iterator();i.hasNext();) {
LogicalLine line = (LogicalLine) i.next();
@@ -268,46 +275,48 @@ public class LayoutPreservingProperties extends Properties {
}
osw.close();
}
/**
* Reads a properties file into an internally maintained collection of logical
* lines (possibly spanning physcial lines), which make up the comments, blank
* lines and properties of the file.
* Reads a properties file into an internally maintained
* collection of logical lines (possibly spanning physcial lines),
* which make up the comments, blank lines and properties of the
* file.
* @param is the stream from which to read the data
*/
private String readLines(InputStream is) throws IOException {
InputStreamReader isr = new InputStreamReader(is, "ISO-8859-1");
BufferedReader br = new BufferedReader(isr);
if (logicalLines.size() > 0) {
// we add a blank line for spacing
logicalLines.add(new Blank());
}
String s = br.readLine();
boolean continuation = false;
boolean comment = false;
StringBuffer fileBuffer = new StringBuffer();
StringBuffer logicalLineBuffer = new StringBuffer();
while (s != null) {
fileBuffer.append(s).append(LS);
if (continuation) {
// put in the line feed that was removed
s = "\n" + s;
} else {
// could be a comment, if first non-whitespace is a # or !
// could be a comment, if first non-whitespace is a # or !
comment = s.matches("^( |\t|\f)*(#|!).*");
}
// continuation if not a comment and the line ends is an odd number of backslashes

// continuation if not a comment and the line ends is an
// odd number of backslashes
if (!comment) {
continuation = requiresContinuation(s);
}
logicalLineBuffer.append(s);
if (!continuation) {
LogicalLine line = null;
if (comment) {
@@ -331,12 +340,14 @@ public class LayoutPreservingProperties extends Properties {
}
return fileBuffer.toString();
}
/**
* Returns <code>true</code> if the line represented by <code>s</code> is to be continued
* on the next line of the file, or <code>false</code> otherwise.
* Returns <code>true</code> if the line represented by
* <code>s</code> is to be continued on the next line of the file,
* or <code>false</code> otherwise.
* @param s the contents of the line to examine
* @return <code>true</code> if the line is to be continued, <code>false</code> otherwise
* @return <code>true</code> if the line is to be continued,
* <code>false</code> otherwise
*/
private boolean requiresContinuation(String s) {
char[] ca = s.toCharArray();
@@ -348,10 +359,11 @@ public class LayoutPreservingProperties extends Properties {
int tb = ca.length - i - 1;
return tb % 2 == 1;
}
/**
* Unescape the string according to the rules for a Properites file, as laid out in
* the docs for <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* Unescape the string according to the rules for a Properites
* file, as laid out in the docs for <a
* href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* @param s the string to unescape (coming from the source file)
* @return the unescaped string
*/
@@ -367,7 +379,7 @@ public class LayoutPreservingProperties extends Properties {
* Any other slash is ignored, so
* \b becomes 'b'.
*/
char[] ch = new char[s.length() + 1];
s.getChars(0, s.length(), ch, 0);
ch[s.length()] = '\n';
@@ -404,10 +416,10 @@ public class LayoutPreservingProperties extends Properties {
}
return buffy.toString();
}
/**
* Retrieve the unicode character whose code is listed at position <code>i</code>
* in the character array <code>ch</code>.
* Retrieve the unicode character whose code is listed at position
* <code>i</code> in the character array <code>ch</code>.
* @param ch the character array containing the unicode character code
* @return the character extracted
*/
@@ -415,41 +427,46 @@ public class LayoutPreservingProperties extends Properties {
String s = new String(ch, i, 4);
return (char) Integer.parseInt(s, 16);
}
/**
* Escape the string <code>s</code> according to the rules in the docs for
* <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* Escape the string <code>s</code> according to the rules in the
* docs for <a
* href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* @param s the string to escape
* @return the escaped string
*/
private String escapeValue(String s) {
return escape(s, false);
}
/**
* Escape the string <code>s</code> according to the rules in the docs for
* <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* This method escapes all the whitespace, not just the stuff at the beginning.
* Escape the string <code>s</code> according to the rules in the
* docs for <a
* href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* This method escapes all the whitespace, not just the stuff at
* the beginning.
* @param s the string to escape
* @return the escaped string
*/
private String escapeName(String s) {
return escape(s, true);
}
/**
* Escape the string <code>s</code> according to the rules in the docs for
* <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* Escape the string <code>s</code> according to the rules in the
* docs for <a
* href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
* @param s the string to escape
* @param escapeAllSpaces if <code>true</code> the method escapes all the spaces,
* if <code>false</code>, it escapes only the leading whitespace
* @param escapeAllSpaces if <code>true</code> the method escapes
* all the spaces, if <code>false</code>, it escapes only the
* leading whitespace
* @return the escaped string
*/
private String escape(String s, boolean escapeAllSpaces) {
if (s == null) {
return null;
}
char[] ch = new char[s.length()];
s.getChars(0, s.length(), ch, 0);
String forEscaping = "\t\f\r\n\\:=#!";
@@ -476,9 +493,10 @@ public class LayoutPreservingProperties extends Properties {
}
return buffy.toString();
}
/**
* Return the unicode escape sequence for a character, in the form \u005CuNNNN.
* Return the unicode escape sequence for a character, in the form
* \u005CuNNNN.
* @param ch the character to encode
* @return the unicode escape sequence
*/
@@ -489,66 +507,68 @@ public class LayoutPreservingProperties extends Properties {
buffy.append(hex);
return buffy.toString();
}
/**
* Remove the comments in the leading up the {@link logicalLines} list leading
* up to line <code>pos</code>.
* Remove the comments in the leading up the {@link logicalLines}
* list leading up to line <code>pos</code>.
* @param pos the line number to which the comments lead
*/
private void removeCommentsEndingAt(int pos) {
/* We want to remove comments preceding this position. Step back counting
* blank lines (call this range B1) until we hit something non-blank. If
* what we hit is not a comment, then exit. If what we hit is a comment,
* then step back counting comment lines (call this range C1). Nullify
* lines in C1 and B1.
/* We want to remove comments preceding this position. Step
* back counting blank lines (call this range B1) until we hit
* something non-blank. If what we hit is not a comment, then
* exit. If what we hit is a comment, then step back counting
* comment lines (call this range C1). Nullify lines in C1 and
* B1.
*/
int end = pos - 1;
// step pos back until it hits something non-blank
for (pos = end; pos > 0; pos--) {
if (!(logicalLines.get(pos) instanceof Blank)) {
break;
}
}
// if the thing it hits is not a comment, then we have nothing to remove

// if the thing it hits is not a comment, then we have nothing
// to remove
if (!(logicalLines.get(pos) instanceof Comment)) {
return;
}
// step back until we hit the start of the comment
for (; pos >= 0; pos--) {
if (!(logicalLines.get(pos) instanceof Comment)) {
break;
}
}
// now we want to delete from pos+1 to end
for (pos++ ;pos <= end; pos++) {
logicalLines.set(pos, null);
}
}
/**
* A logical line of the properties input stream.
*/
private static abstract class LogicalLine {
private String text;
public LogicalLine(String text) {
this.text = text;
}
public void setText(String text) {
this.text = text;
}
public String toString() {
return text;
}
}
/**
* A blank line of the input stream.
*/
@@ -557,7 +577,7 @@ public class LayoutPreservingProperties extends Properties {
super("");
}
}
/**
* A comment line of the input stream.
*/
@@ -566,48 +586,49 @@ public class LayoutPreservingProperties extends Properties {
super(text);
}
}
/**
* A key-value pair from the input stream. This may span more than one physical
* line, but it is constitutes as a single logical line.
* A key-value pair from the input stream. This may span more than
* one physical line, but it is constitutes as a single logical
* line.
*/
private static class Pair extends LogicalLine implements Cloneable {
private String name;
private String value;
private boolean added;
public Pair(String text) {
super(text);
parsePair(text);
}
public Pair(String name, String value) {
this(name + "=" + value);
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
setText(name + "=" + value);
}
public boolean isNew() {
return added;
}
public void setNew(boolean val) {
added = val;
}
public Object clone() {
Object dolly = null;
Object dolly = null;
try {
dolly = super.clone();
}
@@ -617,7 +638,7 @@ public class LayoutPreservingProperties extends Properties {
}
return dolly;
}
private void parsePair(String text) {
// need to find first non-escaped '=', ':', '\t' or ' '.
int pos = findFirstSeparator(text);
@@ -633,12 +654,12 @@ public class LayoutPreservingProperties extends Properties {
// trim leading whitespace only
name = stripStart(name, " \t\f");
}
private String stripStart(String s, String chars) {
if (s == null) {
return null;
}
int i = 0;
for (;i < s.length(); i++) {
if (chars.indexOf(s.charAt(i)) == -1) {
@@ -650,29 +671,29 @@ public class LayoutPreservingProperties extends Properties {
}
return s.substring(i);
}
private int findFirstSeparator(String s) {
// Replace double backslashes with underscores so that they don't
// confuse us looking for '\t' or '\=', for example, but they also
// don't change the position of other characters
s = s.replaceAll("\\\\\\\\", "__");
// Replace single backslashes followed by separators, so we don't
// pick them up
s = s.replaceAll("\\\\=", "__");
s = s.replaceAll("\\\\:", "__");
s = s.replaceAll("\\\\ ", "__");
s = s.replaceAll("\\\\t", "__");
// Now only the unescaped separators are left
return indexOfAny(s, " :=\t");
}
private int indexOfAny(String s, String chars) {
if (s == null || chars == null) {
return -1;
}
int p = s.length() + 1;
for (int i = 0; i < chars.length(); i++) {
int x = s.indexOf(chars.charAt(i));


+ 117
- 94
src/tests/junit/org/apache/tools/ant/util/LayoutPreservingPropertiesTest.java View File

@@ -30,43 +30,45 @@ public class LayoutPreservingPropertiesTest extends TestCase {
public LayoutPreservingPropertiesTest(String s) {
super(s);
}
/**
* Tests that a properties file read by the LayoutPreservingPropertiesFile
* and then saves the properties in it.

/**
* Tests that a properties file read by the
* LayoutPreservingPropertiesFile and then saves the properties in
* it.
*/
public void testPreserve() throws Exception {
File simple = new File(System.getProperty("root"), "src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
File simple = new File(System.getProperty("root"),
"src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.load(fis);
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// now compare original and tmp for property equivalence
Properties originalProps = new Properties();
originalProps.load(new FileInputStream(simple));
Properties tmpProps = new Properties();
tmpProps.load(new FileInputStream(tmp));
assertEquals("properties corrupted", originalProps, tmpProps);
// and now make sure that the comments made it into the new file
String s = readFile(tmp);
assertTrue("missing comment", s.indexOf("# a comment") > -1);
assertTrue("missing comment", s.indexOf("! more comment") > -1);
}
/**
/**
* Tests that names and value are properly escaped when being
* written out.
*/
public void testEscaping() throws Exception {
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.setProperty(" prop one ", " leading and trailing spaces ");
lpf.setProperty("prop\ttwo", "contains\ttab");
lpf.setProperty("prop\nthree", "contains\nnewline");
@@ -77,15 +79,16 @@ public class LayoutPreservingPropertiesTest extends TestCase {
lpf.setProperty("prop=eight", "contains=equals");
lpf.setProperty("prop#nine", "contains#hash");
lpf.setProperty("prop!ten", "contains!exclamation");
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue(s.indexOf("\\ prop\\ one\\ =\\ \\ leading and trailing spaces ") > -1);

assertTrue(s.indexOf("\\ prop\\ one\\ =\\ \\ leading and trailing"
+ " spaces ") > -1);
assertTrue(s.indexOf("prop\\ttwo=contains\\ttab") > -1);
assertTrue(s.indexOf("prop\\nthree=contains\\nnewline") > -1);
assertTrue(s.indexOf("prop\\rfour=contains\\rcarraige return") > -1);
@@ -95,190 +98,210 @@ public class LayoutPreservingPropertiesTest extends TestCase {
assertTrue(s.indexOf("prop\\#nine=contains\\#hash") > -1);
assertTrue(s.indexOf("prop\\!ten=contains\\!exclamation") > -1);
}
/**
/**
* Tests that properties are correctly indexed, so that when we set
* an existing property, it updates the logical line, and it doesn't
* append a new one.
*/
public void testOverwrite() throws Exception {
File unusual = new File(System.getProperty("root"), "src/etc/testcases/util/unusual.properties");
FileInputStream fis = new FileInputStream(unusual);
File unusual = new File(System.getProperty("root"),
"src/etc/testcases/util/unusual.properties");
FileInputStream fis = new FileInputStream(unusual);
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.load(fis);
lpf.setProperty(" prop one ", "new one");
lpf.setProperty("prop\ttwo", "new two");
lpf.setProperty("prop\nthree", "new three");
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue(s.indexOf("\\ prop\\ one\\ =\\ \\ leading and trailing spaces ") == -1);

assertTrue(s.indexOf("\\ prop\\ one\\ =\\ \\ leading and"
+ " trailing spaces ") == -1);
assertTrue(s.indexOf("\\ prop\\ one\\ =new one") > -1);
assertTrue(s.indexOf("prop\\ttwo=contains\\ttab") == -1);
assertTrue(s.indexOf("prop\\ttwo=new two") > -1);
assertTrue(s.indexOf("prop\\nthree=contains\\nnewline") == -1);
assertTrue(s.indexOf("prop\\nthree=new three") > -1);
}
public void testStoreWithHeader() throws Exception {
File simple = new File(System.getProperty("root"), "src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
File simple = new File(System.getProperty("root"),
"src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.load(fis);
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tmp);
lpf.store(fos, "file-header");
fos.close();
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue("should have had header ", s.startsWith("#file-header"));
}
public void testClear() throws Exception {
File simple = new File(System.getProperty("root"), "src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
File simple = new File(System.getProperty("root"),
"src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.load(fis);
lpf.clear();
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue("should have had no properties ", s.indexOf("prop.alpha") == -1);
assertTrue("should have had no properties ", s.indexOf("prop.beta") == -1);
assertTrue("should have had no properties ", s.indexOf("prop.gamma") == -1);
assertTrue("should have had no comments", s.indexOf("# a comment") == -1);
assertTrue("should have had no comments", s.indexOf("! more comment") == -1);
assertTrue("should have had no comments", s.indexOf("# now a line wrapping one") == -1);

assertTrue("should have had no properties ",
s.indexOf("prop.alpha") == -1);
assertTrue("should have had no properties ",
s.indexOf("prop.beta") == -1);
assertTrue("should have had no properties ",
s.indexOf("prop.gamma") == -1);

assertTrue("should have had no comments",
s.indexOf("# a comment") == -1);
assertTrue("should have had no comments",
s.indexOf("! more comment") == -1);
assertTrue("should have had no comments",
s.indexOf("# now a line wrapping one") == -1);
}
public void testRemove() throws Exception {
File simple = new File(System.getProperty("root"), "src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
File simple = new File(System.getProperty("root"),
"src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.load(fis);
lpf.remove("prop.beta");
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue("should not have had prop.beta", s.indexOf("prop.beta") == -1);
assertTrue("should have had prop.beta's comment", s.indexOf("! more comment") > -1);

assertTrue("should not have had prop.beta",
s.indexOf("prop.beta") == -1);
assertTrue("should have had prop.beta's comment",
s.indexOf("! more comment") > -1);
}
public void testRemoveWithComment() throws Exception {
File simple = new File(System.getProperty("root"), "src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
File simple = new File(System.getProperty("root"),
"src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
lpf.load(fis);
lpf.setRemoveComments(true);
lpf.remove("prop.beta");
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue("should not have had prop.beta", s.indexOf("prop.beta") == -1);
assertTrue("should not have had prop.beta's comment", s.indexOf("! more comment") == -1);

assertTrue("should not have had prop.beta",
s.indexOf("prop.beta") == -1);
assertTrue("should not have had prop.beta's comment",
s.indexOf("! more comment") == -1);
}
public void testClone() throws Exception {
File simple = new File(System.getProperty("root"), "src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
File simple = new File(System.getProperty("root"),
"src/etc/testcases/util/simple.properties");
FileInputStream fis = new FileInputStream(simple);
LayoutPreservingProperties lpf1 = new LayoutPreservingProperties();
lpf1.load(fis);
LayoutPreservingProperties lpf2 = (LayoutPreservingProperties) lpf1.clone();

LayoutPreservingProperties lpf2 =
(LayoutPreservingProperties) lpf1.clone();

lpf2.setProperty("prop.new", "a new property");
lpf2.setProperty("prop.beta", "a new value for beta");
assertEquals("size of original is wrong", 3, lpf1.size());
assertEquals("size of clone is wrong", 4, lpf2.size());
File tmp1 = File.createTempFile("tmp", "props");
tmp1.deleteOnExit();
lpf1.saveAs(tmp1);
String s1 = readFile(tmp1);
File tmp2 = File.createTempFile("tmp", "props");
tmp2.deleteOnExit();
lpf2.saveAs(tmp2);
String s2 = readFile(tmp2);
// check original is untouched
assertTrue("should have had 'simple'", s1.indexOf("simple") > -1);
assertTrue("should not have had prop.new", s1.indexOf("prop.new") == -1);
// check clone has the changes
assertTrue("should have had 'a new value for beta'", s2.indexOf("a new value for beta") > -1);
assertTrue("should have had 'a new value for beta'",
s2.indexOf("a new value for beta") > -1);
assertTrue("should have had prop.new", s2.indexOf("prop.new") > -1);
}
public void testPreserveEsacpeName() throws Exception {
LayoutPreservingProperties lpf = new LayoutPreservingProperties();
File unusual = new File(System.getProperty("root"), "src/etc/testcases/util/unusual.properties");
FileInputStream fis = new FileInputStream(unusual);
File unusual = new File(System.getProperty("root"),
"src/etc/testcases/util/unusual.properties");
FileInputStream fis = new FileInputStream(unusual);
lpf.load(fis);
lpf.setProperty("prop:seven", "new value for seven");
lpf.setProperty("prop=eight", "new value for eight");
lpf.setProperty("prop eleven", "new value for eleven");
lpf.setProperty("alpha", "new value for alpha");
lpf.setProperty("beta", "new value for beta");
File tmp = File.createTempFile("tmp", "props");
tmp.deleteOnExit();
lpf.saveAs(tmp);
// and check that the resulting file looks okay
String s = readFile(tmp);
assertTrue(s.indexOf("prop\\:seven=new value for seven") > -1);
assertTrue(s.indexOf("prop\\=eight=new value for eight") > -1);
assertTrue(s.indexOf("prop\\ eleven=new value for eleven") > -1);
assertTrue(s.indexOf("alpha=new value for alpha") > -1);
assertTrue(s.indexOf("beta=new value for beta") > -1);
assertTrue(s.indexOf("prop\\:seven=contains\\:colon") == -1);
assertTrue(s.indexOf("prop\\=eight=contains\\=equals") == -1);
assertTrue(s.indexOf("alpha:set with a colon") == -1);
assertTrue(s.indexOf("beta set with a space") == -1);
}
private String readFile(File f) throws IOException {
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
String s = FileUtils.readFully(isr);
isr.close();
fis.close();
return s;
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
String s = FileUtils.readFully(isr);
isr.close();
fis.close();
return s;
}
}

Loading…
Cancel
Save