AbstractDateCellConverterFactory.java

  1. package com.gh.mygreen.xlsmapper.cellconverter.impl;

  2. import java.text.DateFormat;
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.HashMap;
  7. import java.util.Locale;
  8. import java.util.Map;
  9. import java.util.Optional;
  10. import java.util.TimeZone;

  11. import com.gh.mygreen.xlsmapper.Configuration;
  12. import com.gh.mygreen.xlsmapper.annotation.XlsDateTimeConverter;
  13. import com.gh.mygreen.xlsmapper.cellconverter.BaseCellConverter;
  14. import com.gh.mygreen.xlsmapper.cellconverter.CellConverterFactorySupport;
  15. import com.gh.mygreen.xlsmapper.cellconverter.CellConverterFactory;
  16. import com.gh.mygreen.xlsmapper.fieldaccessor.FieldAccessor;
  17. import com.gh.mygreen.xlsmapper.textformatter.TextFormatter;
  18. import com.gh.mygreen.xlsmapper.textformatter.TextParseException;
  19. import com.gh.mygreen.xlsmapper.util.ArgUtils;
  20. import com.gh.mygreen.xlsmapper.util.Utils;

  21. /**
  22.  * {@link Date}または、その子クラスに対する{@link CellConverterFactory}のベースクラス。
  23.  *
  24.  * @since 2.0
  25.  * @author T.TSUCHIE
  26.  *
  27.  */
  28. public abstract class AbstractDateCellConverterFactory<T extends Date> extends CellConverterFactorySupport<T>
  29.         implements CellConverterFactory<T> {

  30.     @Override
  31.     protected void setupCustom(final BaseCellConverter<T> cellConverter, final FieldAccessor field, final Configuration config) {

  32.         ArgUtils.instanceOf(cellConverter, AbstractDateCellConverter.class, "cellConverter");

  33.         if(cellConverter instanceof AbstractDateCellConverter) {

  34.             final AbstractDateCellConverter<T> dateCellConverter = (AbstractDateCellConverter<T>)cellConverter;

  35.             // 書き込み時のセルの書式を設定する
  36.             Optional<XlsDateTimeConverter> converterAnno = field.getAnnotation(XlsDateTimeConverter.class);

  37.             dateCellConverter.setDefaultExcelPattern(getDefaultExcelPattern());
  38.             converterAnno.ifPresent(ca -> dateCellConverter.setSettingExcelPattern(ca.excelPattern()));

  39.         }

  40.     }

  41.     @Override
  42.     protected TextFormatter<T> createTextFormatter(final FieldAccessor field, final Configuration config) {

  43.         final Optional<XlsDateTimeConverter> converterAnno = field.getAnnotation(XlsDateTimeConverter.class);
  44.         DateFormat formatter = createFormatter(converterAnno);

  45.         return new TextFormatter<T>() {

  46.             @Override
  47.             public T parse(final String text) {
  48.                 try {
  49.                     return parseString(formatter, text);

  50.                 } catch(ParseException e) {
  51.                     final Map<String, Object> vars = new HashMap<>();
  52.                     vars.put("javaPattern", getJavaPattern(converterAnno));
  53.                     vars.put("excelPattern", getExcelPattern(converterAnno));

  54.                     throw new TextParseException(text, field.getType(), e, vars);
  55.                 }
  56.             }

  57.             @Override
  58.             public String format(final T value) {
  59.                 return formatter.format(value);
  60.             }
  61.         };

  62.     }

  63.     /**
  64.      * 文字列をパースして対応するオブジェクトに変換する
  65.      * @param formatter フォーマッタ
  66.      * @param text パース対象の文字列
  67.      * @return パースした結果
  68.      * @throws ParseException
  69.      */
  70.     protected T parseString(final DateFormat formatter, final String text) throws ParseException {
  71.         Date date = formatter.parse(text);
  72.         return convertTypeValue(date);
  73.     }

  74.     /**
  75.      * アノテーションを元に日時のフォーマッタを作成する。
  76.      * @param converterAnno アノテーション
  77.      * @return 日時のフォーマッタ
  78.      */
  79.     protected DateFormat createFormatter(final Optional<XlsDateTimeConverter> converterAnno) {

  80.         final boolean lenient = converterAnno.map(a -> a.lenient()).orElse(false);
  81.         if(!converterAnno.isPresent()) {
  82.             SimpleDateFormat formatter = new SimpleDateFormat(getDefaultJavaPattern());
  83.             formatter.setLenient(lenient);
  84.             return formatter;
  85.         }

  86.         final String pattern = getJavaPattern(converterAnno);

  87.         final Locale locale = Utils.getLocale(converterAnno.get().locale());
  88.         final TimeZone timeZone = converterAnno.get().timezone().isEmpty() ? TimeZone.getDefault()
  89.                 : TimeZone.getTimeZone(converterAnno.get().timezone());

  90.         final SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale);
  91.         formatter.setLenient(lenient);
  92.         formatter.setTimeZone(timeZone);

  93.         return formatter;
  94.     }

  95.     private String getJavaPattern(final Optional<XlsDateTimeConverter> converterAnno) {
  96.         if(!converterAnno.isPresent()) {
  97.             return getDefaultJavaPattern();
  98.         }

  99.         String pattern = converterAnno.get().javaPattern();
  100.         if(pattern.isEmpty()) {
  101.             pattern = getDefaultJavaPattern();
  102.         }

  103.         return pattern;
  104.     }

  105.     private String getExcelPattern(final Optional<XlsDateTimeConverter> converterAnno) {
  106.         if(!converterAnno.isPresent()) {
  107.             return getDefaultExcelPattern();
  108.         }

  109.         String pattern = converterAnno.get().excelPattern();
  110.         if(pattern.isEmpty()) {
  111.             pattern = getDefaultExcelPattern();
  112.         }

  113.         return pattern;
  114.     }

  115.     /**
  116.      * その型における型に変換する
  117.      * @param date 変換対象の値
  118.      * @return 変換後の値
  119.      */
  120.     protected abstract T convertTypeValue(Date date);


  121.     /**
  122.      * その型における標準のJavaの書式を返す。
  123.      * @since 0.5
  124.      * @return {@link SimpleDateFormat}で処理可能な形式。
  125.      */
  126.     protected abstract String getDefaultJavaPattern();

  127.     /**
  128.      * その型における標準のExcelの書式を返す。
  129.      * @since 1.1
  130.      * @return Excelの書式
  131.      */
  132.     protected abstract String getDefaultExcelPattern();


  133. }