spring-batch DefaultFieldSet 源码
spring-batch DefaultFieldSet 代码
文件路径:/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DefaultFieldSet.java
/*
* Copyright 2006-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.file.transform;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Default implementation of {@link FieldSet} using Java using Java primitive and standard
* types and utilities. Strings are trimmed before parsing by default, and so are plain
* String values.
*
* @author Rob Harrop
* @author Dave Syer
*/
public class DefaultFieldSet implements FieldSet {
private final static String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
private DateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
{
dateFormat.setLenient(false);
}
private NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
private String grouping = ",";
private String decimal = ".";
/**
* The fields wrapped by this '<code>FieldSet</code>' instance.
*/
private String[] tokens;
private List<String> names;
/**
* The {@link NumberFormat} to use for parsing numbers. If unset the US locale will be
* used ('.' as decimal place).
* @param numberFormat the {@link NumberFormat} to use for number parsing
*/
public final void setNumberFormat(NumberFormat numberFormat) {
this.numberFormat = numberFormat;
if (numberFormat instanceof DecimalFormat) {
grouping = "" + ((DecimalFormat) numberFormat).getDecimalFormatSymbols().getGroupingSeparator();
decimal = "" + ((DecimalFormat) numberFormat).getDecimalFormatSymbols().getDecimalSeparator();
}
}
/**
* The {@link DateFormat} to use for parsing numbers. If unset the default pattern is
* ISO standard <code>yyyy/MM/dd</code>.
* @param dateFormat the {@link DateFormat} to use for date parsing
*/
public void setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
/**
* Create a FieldSet with anonymous tokens. They can only be retrieved by column
* number.
* @param tokens the token values
* @see FieldSet#readString(int)
*/
public DefaultFieldSet(String[] tokens) {
this.tokens = tokens == null ? null : tokens.clone();
setNumberFormat(NumberFormat.getInstance(Locale.US));
}
/**
* Create a FieldSet with named tokens. The token values can then be retrieved either
* by name or by column number.
* @param tokens the token values
* @param names the names of the tokens
* @see FieldSet#readString(String)
*/
public DefaultFieldSet(String[] tokens, String[] names) {
Assert.notNull(tokens, "Tokens must not be null");
Assert.notNull(names, "Names must not be null");
if (tokens.length != names.length) {
throw new IllegalArgumentException("Field names must be same length as values: names="
+ Arrays.asList(names) + ", values=" + Arrays.asList(tokens));
}
this.tokens = tokens.clone();
this.names = Arrays.asList(names);
setNumberFormat(NumberFormat.getInstance(Locale.US));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#getNames()
*/
@Override
public String[] getNames() {
if (names == null) {
throw new IllegalStateException("Field names are not known");
}
return names.toArray(new String[0]);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.FieldSet#hasNames()
*/
@Override
public boolean hasNames() {
return names != null;
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#getValues()
*/
@Override
public String[] getValues() {
return tokens.clone();
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readString(int)
*/
@Override
public String readString(int index) {
return readAndTrim(index);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readString(java
* .lang.String)
*/
@Override
public String readString(String name) {
return readString(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readRawString(int)
*/
@Override
public String readRawString(int index) {
return tokens[index];
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readRawString(java
* .lang.String)
*/
@Override
public String readRawString(String name) {
return readRawString(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBoolean(int)
*/
@Override
public boolean readBoolean(int index) {
return readBoolean(index, "true");
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBoolean(java
* .lang.String)
*/
@Override
public boolean readBoolean(String name) {
return readBoolean(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBoolean(int,
* java.lang.String)
*/
@Override
public boolean readBoolean(int index, String trueValue) {
Assert.notNull(trueValue, "'trueValue' cannot be null.");
String value = readAndTrim(index);
return trueValue.equals(value);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBoolean(java
* .lang.String, java.lang.String)
*/
@Override
public boolean readBoolean(String name, String trueValue) {
return readBoolean(indexOf(name), trueValue);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readChar(int)
*/
@Override
public char readChar(int index) {
String value = readAndTrim(index);
Assert.isTrue(value.length() == 1, "Cannot convert field value '" + value + "' to char.");
return value.charAt(0);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readChar(java.lang
* .String)
*/
@Override
public char readChar(String name) {
return readChar(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readByte(int)
*/
@Override
public byte readByte(int index) {
return Byte.parseByte(readAndTrim(index));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readByte(java.lang
* .String)
*/
@Override
public byte readByte(String name) {
return readByte(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readShort(int)
*/
@Override
public short readShort(int index) {
return Short.parseShort(readAndTrim(index));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readShort(java.
* lang.String)
*/
@Override
public short readShort(String name) {
return readShort(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readInt(int)
*/
@Override
public int readInt(int index) {
return parseNumber(readAndTrim(index)).intValue();
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readInt(java.lang
* .String)
*/
@Override
public int readInt(String name) {
return readInt(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readInt(int, int)
*/
@Override
public int readInt(int index, int defaultValue) {
String value = readAndTrim(index);
return StringUtils.hasLength(value) ? Integer.parseInt(value) : defaultValue;
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readInt(java.lang
* .String, int)
*/
@Override
public int readInt(String name, int defaultValue) {
return readInt(indexOf(name), defaultValue);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readLong(int)
*/
@Override
public long readLong(int index) {
return parseNumber(readAndTrim(index)).longValue();
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readLong(java.lang
* .String)
*/
@Override
public long readLong(String name) {
return readLong(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readLong(int, long)
*/
@Override
public long readLong(int index, long defaultValue) {
String value = readAndTrim(index);
return StringUtils.hasLength(value) ? Long.parseLong(value) : defaultValue;
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readLong(java.lang
* .String, long)
*/
@Override
public long readLong(String name, long defaultValue) {
return readLong(indexOf(name), defaultValue);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readFloat(int)
*/
@Override
public float readFloat(int index) {
return parseNumber(readAndTrim(index)).floatValue();
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readFloat(java.
* lang.String)
*/
@Override
public float readFloat(String name) {
return readFloat(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDouble(int)
*/
@Override
public double readDouble(int index) {
return parseNumber(readAndTrim(index)).doubleValue();
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDouble(java
* .lang.String)
*/
@Override
public double readDouble(String name) {
return readDouble(indexOf(name));
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBigDecimal(int)
*/
@Override
public BigDecimal readBigDecimal(int index) {
return readBigDecimal(index, null);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBigDecimal(
* java.lang.String)
*/
@Override
public BigDecimal readBigDecimal(String name) {
return readBigDecimal(name, null);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBigDecimal(int,
* java.math.BigDecimal)
*/
@Override
public BigDecimal readBigDecimal(int index, BigDecimal defaultValue) {
String candidate = readAndTrim(index);
if (!StringUtils.hasText(candidate)) {
return defaultValue;
}
try {
String result = removeSeparators(candidate);
return new BigDecimal(result);
}
catch (NumberFormatException e) {
throw new NumberFormatException("Unparseable number: " + candidate);
}
}
private String removeSeparators(String candidate) {
return candidate.replace(grouping, "").replace(decimal, ".");
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readBigDecimal(
* java.lang.String, java.math.BigDecimal)
*/
@Override
public BigDecimal readBigDecimal(String name, BigDecimal defaultValue) {
try {
return readBigDecimal(indexOf(name), defaultValue);
}
catch (NumberFormatException e) {
throw new NumberFormatException(e.getMessage() + ", name: [" + name + "]");
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + ", name: [" + name + "]");
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDate(int)
*/
@Override
public Date readDate(int index) {
return parseDate(readAndTrim(index), dateFormat);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.transform.FieldSet#readDate(int,
* java.util.Date)
*/
@Override
public Date readDate(int index, Date defaultValue) {
String candidate = readAndTrim(index);
return StringUtils.hasText(candidate) ? parseDate(candidate, dateFormat) : defaultValue;
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDate(java.lang
* .String)
*/
@Override
public Date readDate(String name) {
try {
return readDate(indexOf(name));
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + ", name: [" + name + "]");
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.transform.FieldSet#readDate(int,
* java.util.Date)
*/
@Override
public Date readDate(String name, Date defaultValue) {
try {
return readDate(indexOf(name), defaultValue);
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + ", name: [" + name + "]");
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDate(int,
* java.lang.String)
*/
@Override
public Date readDate(int index, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
sdf.setLenient(false);
return parseDate(readAndTrim(index), sdf);
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDate(int,
* java.lang.String)
*/
@Override
public Date readDate(int index, String pattern, Date defaultValue) {
String candidate = readAndTrim(index);
return StringUtils.hasText(candidate) ? readDate(index, pattern) : defaultValue;
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDate(java.lang
* .String, java.lang.String)
*/
@Override
public Date readDate(String name, String pattern) {
try {
return readDate(indexOf(name), pattern);
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + ", name: [" + name + "]");
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#readDate(int,
* java.lang.String)
*/
@Override
public Date readDate(String name, String pattern, Date defaultValue) {
try {
return readDate(indexOf(name), pattern, defaultValue);
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + ", name: [" + name + "]");
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#getFieldCount()
*/
@Override
public int getFieldCount() {
return tokens.length;
}
/**
* Read and trim the {@link String} value at '<code>index</code>'.
* @param index the offset in the token array to obtain the value to be trimmed.
* @return null if the field value is <code>null</code>.
*/
protected String readAndTrim(int index) {
String value = tokens[index];
if (value != null) {
return value.trim();
}
else {
return null;
}
}
/**
* Retrieve the index of where a specified column is located based on the {@code name}
* parameter.
* @param name the value to search in the {@link List} of names.
* @return the index in the {@link List} of names where the name was found.
* @throws IllegalArgumentException if a column with given name is not defined.
*/
protected int indexOf(String name) {
if (names == null) {
throw new IllegalArgumentException("Cannot access columns by name without meta data");
}
int index = names.indexOf(name);
if (index >= 0) {
return index;
}
throw new IllegalArgumentException("Cannot access column [" + name + "] from " + names);
}
@Override
public String toString() {
if (names != null) {
return getProperties().toString();
}
return tokens == null ? "" : Arrays.asList(tokens).toString();
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object object) {
if (object instanceof DefaultFieldSet) {
DefaultFieldSet fs = (DefaultFieldSet) object;
if (this.tokens == null) {
return fs.tokens == null;
}
else {
return Arrays.equals(this.tokens, fs.tokens);
}
}
return false;
}
@Override
public int hashCode() {
// this algorithm was taken from java 1.5 jdk Arrays.hashCode(Object[])
if (tokens == null) {
return 0;
}
int result = 1;
for (String token : tokens) {
result = 31 * result + (token == null ? 0 : token.hashCode());
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.file.mapping.IFieldSet#getProperties()
*/
@Override
public Properties getProperties() {
if (names == null) {
throw new IllegalStateException("Cannot create properties without meta data");
}
Properties props = new Properties();
for (int i = 0; i < tokens.length; i++) {
String value = readAndTrim(i);
if (value != null) {
props.setProperty(names.get(i), value);
}
}
return props;
}
private Number parseNumber(String candidate) {
try {
return numberFormat.parse(candidate);
}
catch (ParseException e) {
throw new NumberFormatException("Unparseable number: " + candidate);
}
}
private Date parseDate(String readAndTrim, DateFormat dateFormat) {
try {
return dateFormat.parse(readAndTrim);
}
catch (ParseException e) {
String pattern;
if (dateFormat instanceof SimpleDateFormat) {
pattern = ((SimpleDateFormat) dateFormat).toPattern();
}
else {
pattern = dateFormat.toString();
}
throw new IllegalArgumentException(e.getMessage() + ", format: [" + pattern + "]");
}
}
}
相关信息
相关文章
spring-batch AbstractLineTokenizer 源码
spring-batch BeanWrapperFieldExtractor 源码
spring-batch ConversionException 源码
spring-batch DefaultFieldSetFactory 源码
spring-batch DelimitedLineAggregator 源码
spring-batch DelimitedLineTokenizer 源码
spring-batch ExtractorLineAggregator 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦