AbstractDateCellConverterFactory.java
package com.gh.mygreen.xlsmapper.cellconverter.impl;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.TimeZone;
import com.gh.mygreen.xlsmapper.Configuration;
import com.gh.mygreen.xlsmapper.annotation.XlsDateTimeConverter;
import com.gh.mygreen.xlsmapper.cellconverter.BaseCellConverter;
import com.gh.mygreen.xlsmapper.cellconverter.CellConverterFactorySupport;
import com.gh.mygreen.xlsmapper.cellconverter.CellConverterFactory;
import com.gh.mygreen.xlsmapper.fieldaccessor.FieldAccessor;
import com.gh.mygreen.xlsmapper.textformatter.TextFormatter;
import com.gh.mygreen.xlsmapper.textformatter.TextParseException;
import com.gh.mygreen.xlsmapper.util.ArgUtils;
import com.gh.mygreen.xlsmapper.util.Utils;
/**
* {@link Date}または、その子クラスに対する{@link CellConverterFactory}のベースクラス。
*
* @since 2.0
* @author T.TSUCHIE
*
*/
public abstract class AbstractDateCellConverterFactory<T extends Date> extends CellConverterFactorySupport<T>
implements CellConverterFactory<T> {
@Override
protected void setupCustom(final BaseCellConverter<T> cellConverter, final FieldAccessor field, final Configuration config) {
ArgUtils.instanceOf(cellConverter, AbstractDateCellConverter.class, "cellConverter");
if(cellConverter instanceof AbstractDateCellConverter) {
final AbstractDateCellConverter<T> dateCellConverter = (AbstractDateCellConverter<T>)cellConverter;
// 書き込み時のセルの書式を設定する
Optional<XlsDateTimeConverter> converterAnno = field.getAnnotation(XlsDateTimeConverter.class);
dateCellConverter.setDefaultExcelPattern(getDefaultExcelPattern());
converterAnno.ifPresent(ca -> dateCellConverter.setSettingExcelPattern(ca.excelPattern()));
}
}
@Override
protected TextFormatter<T> createTextFormatter(final FieldAccessor field, final Configuration config) {
final Optional<XlsDateTimeConverter> converterAnno = field.getAnnotation(XlsDateTimeConverter.class);
DateFormat formatter = createFormatter(converterAnno);
return new TextFormatter<T>() {
@Override
public T parse(final String text) {
try {
return parseString(formatter, text);
} catch(ParseException e) {
final Map<String, Object> vars = new HashMap<>();
vars.put("javaPattern", getJavaPattern(converterAnno));
vars.put("excelPattern", getExcelPattern(converterAnno));
throw new TextParseException(text, field.getType(), e, vars);
}
}
@Override
public String format(final T value) {
return formatter.format(value);
}
};
}
/**
* 文字列をパースして対応するオブジェクトに変換する
* @param formatter フォーマッタ
* @param text パース対象の文字列
* @return パースした結果
* @throws ParseException
*/
protected T parseString(final DateFormat formatter, final String text) throws ParseException {
Date date = formatter.parse(text);
return convertTypeValue(date);
}
/**
* アノテーションを元に日時のフォーマッタを作成する。
* @param converterAnno アノテーション
* @return 日時のフォーマッタ
*/
protected DateFormat createFormatter(final Optional<XlsDateTimeConverter> converterAnno) {
final boolean lenient = converterAnno.map(a -> a.lenient()).orElse(false);
if(!converterAnno.isPresent()) {
SimpleDateFormat formatter = new SimpleDateFormat(getDefaultJavaPattern());
formatter.setLenient(lenient);
return formatter;
}
final String pattern = getJavaPattern(converterAnno);
final Locale locale = Utils.getLocale(converterAnno.get().locale());
final TimeZone timeZone = converterAnno.get().timezone().isEmpty() ? TimeZone.getDefault()
: TimeZone.getTimeZone(converterAnno.get().timezone());
final SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale);
formatter.setLenient(lenient);
formatter.setTimeZone(timeZone);
return formatter;
}
private String getJavaPattern(final Optional<XlsDateTimeConverter> converterAnno) {
if(!converterAnno.isPresent()) {
return getDefaultJavaPattern();
}
String pattern = converterAnno.get().javaPattern();
if(pattern.isEmpty()) {
pattern = getDefaultJavaPattern();
}
return pattern;
}
private String getExcelPattern(final Optional<XlsDateTimeConverter> converterAnno) {
if(!converterAnno.isPresent()) {
return getDefaultExcelPattern();
}
String pattern = converterAnno.get().excelPattern();
if(pattern.isEmpty()) {
pattern = getDefaultExcelPattern();
}
return pattern;
}
/**
* その型における型に変換する
* @param date 変換対象の値
* @return 変換後の値
*/
protected abstract T convertTypeValue(Date date);
/**
* その型における標準のJavaの書式を返す。
* @since 0.5
* @return {@link SimpleDateFormat}で処理可能な形式。
*/
protected abstract String getDefaultJavaPattern();
/**
* その型における標準のExcelの書式を返す。
* @since 1.1
* @return Excelの書式
*/
protected abstract String getDefaultExcelPattern();
}