View Javadoc
1   package com.github.mygreen.cellformatter;
2   
3   import java.util.List;
4   import java.util.Locale;
5   import java.util.concurrent.CopyOnWriteArrayList;
6   
7   import com.github.mygreen.cellformatter.lang.ArgUtils;
8   import com.github.mygreen.cellformatter.number.NumberFactory;
9   import com.github.mygreen.cellformatter.term.NumberTerm;
10  import com.github.mygreen.cellformatter.term.TextTerm;
11  import com.github.mygreen.cellformatter.tokenizer.Token;
12  
13  
14  
15  /**
16   * ユーザ定義の書式を表現するフォーマッタ。
17   * <p>{@link CustomFormatterFactory}からインスタンスを作成する。
18   *
19   * @version 0.10
20   * @author T.TSUCHIE
21   *
22   */
23  public class CustomFormatter extends CellFormatter {
24  
25      /**
26       * 書式がない、標準フォーマッター
27       */
28      public static final CustomFormatter DEFAULT_FORMATTER;
29      static {
30          // 数値の場合
31          final ConditionNumberFormatterer.html#ConditionNumberFormatter">ConditionNumberFormatter numberFormatter = new ConditionNumberFormatter("General");
32          numberFormatter.addTerm(NumberTerm.general());
33          numberFormatter.setOperator(ConditionOperator.ALL);
34          numberFormatter.setNumberFactory(NumberFactory.decimalNumber(0, false, 0));
35  
36          // 文字列の場合
37          final ConditionTextFormattertter.html#ConditionTextFormatter">ConditionTextFormatter textFormatter = new ConditionTextFormatter("General");
38          textFormatter.addTerm(TextTerm.atMark(Token.SYMBOL_AT_MARK));
39          textFormatter.setOperator(ConditionOperator.ALL);
40  
41          final CustomFormatterormatter.html#CustomFormatter">CustomFormatter formatter = new CustomFormatter("");
42          formatter.addConditionFormatter(numberFormatter);
43          formatter.addConditionFormatter(textFormatter);
44  
45          DEFAULT_FORMATTER = formatter;
46      }
47  
48      /**
49       * 書式のパターン
50       */
51      private final String pattern;
52  
53      /**
54       * 条件付きのフォーマッタ
55       */
56      private List<ConditionFormatter> conditionFormatters = new CopyOnWriteArrayList<>();
57  
58      /**
59       * 書式を指定してインスタンスを作成する。
60       * @param pattern ユーザ定義の書式。
61       */
62      public CustomFormatter(final String pattern) {
63          this.pattern = pattern;
64      }
65  
66      @Override
67      public CellFormatResult format(final CommonCell cell, final Locale runtimeLocale) {
68  
69          ArgUtils.notNull(cell, "cell");
70  
71          for(ConditionFormatter formatter : conditionFormatters) {
72              if(formatter.isMatch(cell)) {
73                  return formatter.format(cell, runtimeLocale);
74              }
75          }
76  
77          /*
78           * 一致するものがない場合は、デフォルトのフォーマッタで処理する。
79           * ・セクションとセルの属性が一致していない場合に発生する。
80           * ・数値が設定されているのに、文字列用のセクションしかない場合。
81           */
82          if(cell.isText()) {
83              return DEFAULT_FORMATTER.format(cell, runtimeLocale);
84  
85          } else if(cell.isNumber()) {
86              return DEFAULT_FORMATTER.format(cell, runtimeLocale);
87          }
88  
89          throw new NoMatchConditionFormatterException(cell, String.format(
90                  "not match format for cell : '%s'", cell.getCellAddress()));
91  
92      }
93  
94      @Override
95      public String getPattern(Locale locale) {
96          return pattern;
97      }
98  
99      /**
100      * 文字列の書式を持つかどうか。
101      * @return
102      */
103     public boolean hasTextFormatter() {
104         for(ConditionFormatter formatter : conditionFormatters) {
105             if(formatter.isTextFormatter()) {
106                 return true;
107             }
108         }
109 
110         return false;
111     }
112 
113     /**
114      * 日時のフォーマッタを持つかどうか。
115      * <p>ただし、';'で区切り数値と日時の書式を同時に持つ可能性がある。
116      * @return
117      */
118     public boolean hasDateFormatter() {
119         for(ConditionFormatter formatter : conditionFormatters) {
120             if(formatter.isDateFormatter()) {
121                 return true;
122             }
123         }
124 
125         return false;
126     }
127 
128     /**
129      * 数値のフォーマッタを持つかどうか。
130      * <p>ただし、';'で区切り数値と日時の書式を同時に持つ可能性がある。
131      * @return
132      */
133     public boolean hasNumberFormatter() {
134         for(ConditionFormatter formatter : conditionFormatters) {
135             if(formatter.isNumberFormatter()) {
136                 return true;
137             }
138         }
139 
140         return false;
141     }
142 
143     /**
144      * 条件付きのフォーマッタを追加する。
145      * @param formatter
146      */
147     public void addConditionFormatter(ConditionFormatter formatter) {
148         this.conditionFormatters.add(formatter);
149     }
150 
151     /**
152      * 条件付きのフォーマッタを取得する。
153      * @return
154      */
155     public List<ConditionFormatter> getConditionFormatters() {
156         return conditionFormatters;
157     }
158 
159 }