[CSV-68] Use the Builder pattern for CSVFormat.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1410759 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gary D. Gregory 2012-11-17 18:00:38 +00:00
parent e4889167d2
commit db11c04d29
3 changed files with 296 additions and 43 deletions

View File

@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Arrays;
/**
* The format specification of a CSV file.
@ -176,8 +177,10 @@ public class CSVFormat implements Serializable {
*/
private CSVFormat(final char delimiter, final Character quoteChar, final Quote quotePolicy, final Character commentStart, final Character escape, final
boolean ignoreSurroundingSpaces, final boolean ignoreEmptyLines, final String lineSeparator,
final String[] header) {
if (isLineBreak(delimiter)) {
final String[] header)
{
if (isLineBreak(delimiter))
{
throw new IllegalArgumentException("The delimiter cannot be a line break");
}
this.delimiter = delimiter;
@ -188,7 +191,7 @@ public class CSVFormat implements Serializable {
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
this.ignoreEmptyLines = ignoreEmptyLines;
this.recordSeparator = lineSeparator;
this.header = header;
this.header = header == null ? null : header.clone();
}
/**
@ -374,6 +377,108 @@ public class CSVFormat implements Serializable {
return quotePolicy;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + delimiter;
result = prime * result + ((quotePolicy == null) ? 0 : quotePolicy.hashCode());
result = prime * result + ((quoteChar == null) ? 0 : quoteChar.hashCode());
result = prime * result + ((commentStart == null) ? 0 : commentStart.hashCode());
result = prime * result + ((escape == null) ? 0 : escape.hashCode());
result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237);
result = prime * result + (ignoreEmptyLines ? 1231 : 1237);
result = prime * result + ((recordSeparator == null) ? 0 : recordSeparator.hashCode());
result = prime * result + Arrays.hashCode(header);
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
CSVFormat other = (CSVFormat) obj;
if (delimiter != other.delimiter)
{
return false;
}
if (quotePolicy != other.quotePolicy)
{
return false;
}
if (quoteChar == null)
{
if (other.quoteChar != null)
{
return false;
}
}
else if (!quoteChar.equals(other.quoteChar))
{
return false;
}
if (commentStart == null)
{
if (other.commentStart != null)
{
return false;
}
}
else if (!commentStart.equals(other.commentStart))
{
return false;
}
if (escape == null)
{
if (other.escape != null)
{
return false;
}
}
else if (!escape.equals(other.escape))
{
return false;
}
if (!Arrays.equals(header, other.header))
{
return false;
}
if (ignoreSurroundingSpaces != other.ignoreSurroundingSpaces)
{
return false;
}
if (ignoreEmptyLines != other.ignoreEmptyLines)
{
return false;
}
if (recordSeparator == null)
{
if (other.recordSeparator != null)
{
return false;
}
}
else if (!recordSeparator.equals(other.recordSeparator))
{
return false;
}
return true;
}
public static class CSVFormatBuilder {
private char delimiter;

View File

@ -21,9 +21,9 @@ import static org.apache.commons.csv.CSVFormat.RFC4180;
import static org.apache.commons.csv.Constants.CR;
import static org.apache.commons.csv.Constants.CRLF;
import static org.apache.commons.csv.Constants.LF;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import org.apache.commons.csv.CSVFormat.CSVFormatBuilder;
@ -159,7 +159,7 @@ public class CSVFormatBuilderTest {
@Test
public void testCopiedFormatIsEqualToOriginal() {
CSVFormat copyOfRCF4180 = CSVFormat.newBuilder(RFC4180).build();
assertEqualFormats(RFC4180, copyOfRCF4180);
assertEquals(RFC4180, copyOfRCF4180);
}
@Test
@ -168,16 +168,14 @@ public class CSVFormatBuilderTest {
assertTrue(newFormat.getDelimiter() != RFC4180.getDelimiter());
}
// FIXME implement equals on CSVFormat to allow use of Assert.assertEquals()
private static void assertEqualFormats(CSVFormat expected, CSVFormat acutal) {
assertEquals(expected.getCommentStart(), acutal.getCommentStart());
assertEquals(expected.getDelimiter(), acutal.getDelimiter());
assertEquals(expected.getEscape(), acutal.getEscape());
assertArrayEquals(expected.getHeader(), acutal.getHeader());
assertEquals(expected.getIgnoreEmptyLines(), acutal.getIgnoreEmptyLines());
assertEquals(expected.getIgnoreSurroundingSpaces(), acutal.getIgnoreSurroundingSpaces());
assertEquals(expected.getQuoteChar(), acutal.getQuoteChar());
assertEquals(expected.getQuotePolicy(), acutal.getQuotePolicy());
assertEquals(expected.getRecordSeparator(), acutal.getRecordSeparator());
@Test
public void testHeaderReferenceCannotEscape() {
String[] header = new String[]{"one", "tow", "three"};
builder.withHeader(header);
CSVFormat firstFormat = builder.build();
CSVFormat secondFormat = builder.build();
assertNotSame(header, firstFormat.getHeader());
assertNotSame(firstFormat, secondFormat.getHeader());
}
}

View File

@ -18,6 +18,7 @@
package org.apache.commons.csv;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import java.io.ByteArrayInputStream;
@ -65,4 +66,153 @@ public class CSVFormatTest {
assertEquals("trim", CSVFormat.DEFAULT.getIgnoreSurroundingSpaces(), format.getIgnoreSurroundingSpaces());
assertEquals("empty lines", CSVFormat.DEFAULT.getIgnoreEmptyLines(), format.getIgnoreEmptyLines());
}
@Test
public void testEquals() {
CSVFormat right = CSVFormat.DEFAULT;
CSVFormat left = CSVFormat.newBuilder().build();
assertFalse(right.equals(null));
assertFalse(right.equals("A String Instance"));
assertEquals(right, right);
assertEquals(right, left);
assertEquals(left, right);
assertEquals(right.hashCode(), right.hashCode());
assertEquals(right.hashCode(), left.hashCode());
}
@Test
public void testEqualsDelimiter() {
CSVFormat right = CSVFormat.newBuilder('!').build();
CSVFormat left = CSVFormat.newBuilder('?').build();
assertNotEquals(right, left);
}
@Test
public void testEqualsQuoteChar() {
CSVFormat right = CSVFormat.newBuilder('\'').withQuoteChar('"').build();
CSVFormat left = CSVFormat.newBuilder(right).withQuoteChar('!').build();
assertNotEquals(right, left);
}
@Test
public void testEqualsQuotePolicy() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withQuotePolicy(Quote.MINIMAL)
.build();
assertNotEquals(right, left);
}
@Test
public void testEqualsCommentStart() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.withCommentStart('#')
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withCommentStart('!')
.build();
assertNotEquals(right, left);
}
@Test
public void testEqualsEscape() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.withCommentStart('#')
.withEscape('+')
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withEscape('!')
.build();
assertNotEquals(right, left);
}
@Test
public void testEqualsIgnoreSurroundingSpaces() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.withCommentStart('#')
.withEscape('+')
.withIgnoreSurroundingSpaces(true)
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withIgnoreSurroundingSpaces(false)
.build();
assertNotEquals(right, left);
}
@Test
public void testEqualsIgnoreEmptyLines() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.withCommentStart('#')
.withEscape('+')
.withIgnoreSurroundingSpaces(true)
.withIgnoreEmptyLines(true)
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withIgnoreEmptyLines(false)
.build();
assertNotEquals(right, left);
}
@Test
public void testEqualsRecordSeparator() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.withCommentStart('#')
.withEscape('+')
.withIgnoreSurroundingSpaces(true)
.withIgnoreEmptyLines(true)
.withRecordSeparator('*')
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withRecordSeparator('!')
.build();
assertNotEquals(right, left);
}
@Test
public void testEqualsHeader() {
CSVFormat right = CSVFormat.newBuilder('\'')
.withQuoteChar('"')
.withQuotePolicy(Quote.ALL)
.withCommentStart('#')
.withEscape('+')
.withIgnoreSurroundingSpaces(true)
.withIgnoreEmptyLines(true)
.withRecordSeparator('*')
.withHeader("One", "Two", "Three")
.build();
CSVFormat left = CSVFormat.newBuilder(right)
.withHeader("Three", "Two", "One")
.build();
assertNotEquals(right, left);
}
private static void assertNotEquals(Object right, Object left) {
assertFalse(right.equals(left));
assertFalse(left.equals(right));
}
}