package batch.internal;
import java.math.BigDecimal;
import java.util.Arrays;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
*/
public final class FieldSet {
/**
* The fields wrapped by this '<code>FieldSet</code>' instance.
*/
private final String[] fields;
/**
* Create a new instance of the <code>FieldSet</code> class wrapping the supplied <code>fields</code>.
*
* @param fields the fields to be wrapped.
* @throws IllegalArgumentException if the supplied <code>fields</code> array is <code>null</code>.
*/
public FieldSet(String[] fields) {
Assert.notNull(fields, "'fields' cannot be null.");
this.fields = (String[]) fields.clone();
}
/**
* Read the {@link String} value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public String readString(int index) {
if (index < 0 || index > fields.length - 1) {
throw new IndexOutOfBoundsException("No field at index '" + index + "'");
}
return this.fields[index];
}
/**
* Read the {@link String} value at index '<code>index</code>' and remove leading white space. <p/>
* <p>
* This will never return <code>null</code>; if the field is <code>null</code> an empty string will be
* returned.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public String readStringAndTrim(int index) {
String value = readString(index);
return value == null ? "" : value.trim();
}
/**
* Read the '<code>boolean</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public boolean readBoolean(int index) {
return Boolean.parseBoolean(readAndTrim(index));
}
/**
* Read the '<code>boolean</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @param trueValue the value that signifies {@link Boolean#TRUE true}; case-sensitive.
* @throws IndexOutOfBoundsException if the index is out of bounds, or if the supplied <code>trueValue</code> is
* <code>null</code>.
*/
public boolean readBoolean(int index, String trueValue) {
Assert.notNull(trueValue, "'trueValue' cannot be null.");
String value = readAndTrim(index);
return (trueValue.equals(value) ? Boolean.TRUE : Boolean.FALSE).booleanValue();
}
/**
* Read the '<code>char</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public char readChar(int index) {
String value = readAndTrim(index);
if (value.length() != 1) {
throw new IllegalArgumentException("Cannot convert field value '" + value + "' to char.");
}
return value.charAt(index);
}
/**
* Read the '<code>byte</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public byte readByte(int index) {
return Byte.parseByte(readAndTrim(index));
}
/**
* Read the '<code>short</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public short readShort(int index) {
return Short.parseShort(readAndTrim(index));
}
/**
* Read the '<code>int</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public int readInt(int index) {
return Integer.parseInt(readAndTrim(index));
}
/**
* Read the '<code>int</code>' value at index '<code>index</code>', using the supplied
* <code>defaultValue</code> if the field value is blank.
*
* @param index the field index..
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public int readInt(int index, int defaultValue) {
String value = readAndTrim(index);
return StringUtils.hasLength(value) ? Integer.parseInt(value) : defaultValue;
}
/**
* Read the '<code>long</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public long readLong(int index) {
return Long.parseLong(readAndTrim(index));
}
/**
* Read the '<code>long</code>' value at index '<code>index</code>', using the supplied
* <code>defaultValue</code> if the field value is blank.
*
* @param index the field index..
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public long readLong(int index, long defaultValue) {
String value = readAndTrim(index);
return StringUtils.hasLength(value) ? Long.parseLong(value) : defaultValue;
}
/**
* Read the '<code>float</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public float readFloat(int index) {
return Float.parseFloat(readAndTrim(index));
}
/**
* Read the '<code>double</code>' value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public double readDouble(int index) {
return Double.parseDouble(readAndTrim(index));
}
/**
* Read the {@link java.math.BigDecimal} value at index '<code>index</code>'.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public BigDecimal readBigDecimal(int index) {
return readBigDecimal(index, null);
}
/**
* Read the {@link BigDecimal} value at index '<code>index</code>', returning the supplied
* <code>defaultValue</code> if the trimmed string value at index '<code>index</code>' is blank.
*
* @param index the field index.
* @throws IndexOutOfBoundsException if the index is out of bounds.
*/
public BigDecimal readBigDecimal(int index, BigDecimal defaultValue) {
String candidate = readAndTrim(index);
try {
return candidate.length() != 0 ? new BigDecimal(candidate) : defaultValue;
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("'" + candidate + "' | '" + candidate.length() + "', '" + defaultValue
+ "'", ex);
}
}
/**
* Return the number of fields in this '<code>FieldSet</code>'.
*/
public int getFieldCount() {
return this.fields.length;
}
/**
* Read and trim the {@link String} value at '<code>index</code>'.
*
* @throws NullPointerException if the field value is <code>null</code>.
*/
private String readAndTrim(int index) {
String value = readString(index);
if (value == null) {
throw new NullPointerException("Unable to convert field at index '" + index + "' - value is null.");
}
return value.trim();
}
public String toString() {
return Arrays.asList(this.fields).toString();
}
}