View Javadoc
1   package com.github.mygreen.cellformatter;
2   
3   import java.util.Calendar;
4   import java.util.Date;
5   import java.util.List;
6   import java.util.Locale;
7   import java.util.TimeZone;
8   import java.util.concurrent.CopyOnWriteArrayList;
9   
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  import com.github.mygreen.cellformatter.callback.Callback;
14  import com.github.mygreen.cellformatter.lang.ArgUtils;
15  import com.github.mygreen.cellformatter.lang.ExcelDateUtils;
16  import com.github.mygreen.cellformatter.term.DateTerm;
17  import com.github.mygreen.cellformatter.term.Term;
18  
19  
20  /**
21   * ユーザ定義型の日時を解釈するフォーマッタ
22   *
23   * @version 0.10
24   * @author T.TSUCHIE
25   *
26   */
27  public class ConditionDateFormatter extends ConditionFormatter {
28  
29      private static final Logger logger = LoggerFactory.getLogger(ConditionDateFormatter.class);
30  
31      /**
32       * 日時の各項
33       */
34      private List<Term<Calendar>> terms = new CopyOnWriteArrayList<>();
35  
36      public ConditionDateFormatter(final String pattern) {
37          super(pattern);
38      }
39  
40      @Override
41      public FormatterType getType() {
42          return FormatterType.Date;
43      }
44  
45      /**
46       * 値が条件に一致するかどうか。
47       * <p>Excelの1900年1月1日を基準に、ミリ秒に直して判定する。
48       * @param cell
49       * @return
50       */
51      @Override
52      public boolean isMatch(final CommonCell cell) {
53          if(!cell.isNumber()) {
54              return false;
55          }
56  
57          final long zeroTime = ExcelDateUtils.getExcelZeroDateTime(cell.isDateStart1904());
58          final Date date = cell.getDateCellValue();
59          final long value = date.getTime() - zeroTime;
60  
61          if(logger.isDebugEnabled()) {
62              logger.debug("isMatch::date={}, zeroTime={}, diff={}",
63                      ExcelDateUtils.formatDate(date), ExcelDateUtils.formatDate(new Date(zeroTime)), value);
64          }
65  
66          return getOperator().isMatch(value);
67      }
68  
69      @Override
70      public CellFormatResult format(final CommonCell cell, final Locale runtimeLocale) {
71          ArgUtils.notNull(cell, "date");
72  
73          final Date date = cell.getDateCellValue();
74          final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-00:00"));
75          cal.setTime(date);
76  
77          // 各項の処理
78          StringBuilder sb = new StringBuilder();
79          for(Term<Calendar> term : terms) {
80              final String formatValue;
81              if(term instanceof DateTerm) {
82                  formatValue = ((DateTerm) term).format(cal, getLocale(), runtimeLocale, cell.isDateStart1904());
83              } else {
84                  formatValue = term.format(cal, getLocale(), runtimeLocale);
85              }
86              sb.append(applyFormatCallback(cal, formatValue, runtimeLocale, term));
87          }
88  
89          String value = sb.toString();
90  
91          final CellFormatResultormatResult.html#CellFormatResult">CellFormatResult result = new CellFormatResult();
92          result.setValue(date);
93          result.setText(value);
94          result.setTextColor(getColor());
95          result.setSectionPattern(getPattern());
96          result.setCellType(FormatCellType.Date);
97  
98          return result;
99      }
100 
101     @SuppressWarnings({"rawtypes", "unchecked"})
102     private String applyFormatCallback(final Calendar cal, final String str, final Locale runtimeLocale, Term<Calendar> term) {
103 
104         String value = str;
105 
106         for(Callback callback : getCallbacks()) {
107 
108             final Locale locale;
109             if(getLocale() != null) {
110                 locale = getLocale().getLocale();
111             } else {
112                 locale = runtimeLocale;
113             }
114 
115             if(!callback.isApplicable(locale)) {
116                 continue;
117             }
118 
119             value = callback.call(cal, value, locale, term);
120         }
121 
122         return value;
123 
124     }
125 
126     /**
127      * フォーマットの項を追加する。
128      * @param term
129      */
130     public void addTerm(final Term<Calendar> term) {
131         this.terms.add(term);
132     }
133 
134     /**
135      * フォーマットの複数の項を追加する。
136      * @param terms
137      */
138     public void addAllTerms(final List<Term<Calendar>> terms) {
139         this.terms.addAll(terms);
140     }
141 
142     /**
143      * フォーマットの項を全て取得する。
144      * @return
145      */
146     public List<Term<Calendar>> getTerms() {
147         return terms;
148     }
149 }