View Javadoc
1   package com.github.mygreen.supercsv.cellprocessor.conversion;
2   
3   import java.io.Serializable;
4   import java.util.Collection;
5   
6   import com.github.mygreen.supercsv.annotation.conversion.CsvWordReplace;
7   import com.github.mygreen.supercsv.builder.FieldAccessor;
8   import com.github.mygreen.supercsv.util.ArgUtils;
9   
10  /**
11   * {@link CsvWordReplace}による語彙による置換処理をを個ナウ際の語彙を提供するためのインタフェースです。
12   * <p>語彙を別ファイルやDBから取得する時などサービスクラスとして実装します。</p>
13   * 
14   * <p>基本的な使い方は、 {@link CsvWordReplace}のJavaDocを参照してください。</p>
15   * 
16   * <h3 class="description">フィールドごとにリソースを切り替えたい場合</h3>
17   * <p>フィールドごとにリソースを切り替えたい場合は、メソッドの引数{@link FieldAccessor}で判定を行います。</p>
18   * <p>また、独自のパラメータを渡したい時は、独自のアノテーションを作成し、それをフィールドに付与して、
19   *    引数{@link FieldAccessor}から取得して判定します。
20   * </p>
21   * 
22   * <pre class="highlight"><code class="java">
23   * // 読み込むリソースを定義されているフィールドやクラスで分ける場合
24   * public class FileReplacedWordProvider implements ReplacedWordProvider {
25   *     
26   *     {@literal @Override}
27   *     public {@literal Collection<Word>} getReplacedWords(final FieldAccessor field) {
28   *         
29   *         final String path;
30   *         if(field.getDeclaredClass().equals(AdminCsv.class)) {
31   *             path = "replaced_word_admin.txt";
32   *         } else {
33   *             path = "replaced_word.txt";
34   *         }
35   *         
36   *         // ファイルから語彙の定義を読み込む
37   *         {@literal List<String>} lines;
38   *         try {
39   *              
40   *              lines = Files.readAllLines(new File(path).toPath(), Charset.forName("UTF-8"));
41   *              
42   *         } catch (IOException e) {
43   *             throw new RuntimeException("fail reading the replaced words file.", e);
44   *         }
45   *         
46   *         // 読み込んだ各行の値を分割して、ReplacedWordProvider.Word クラスに変換する。
47   *         return lines.stream()
48   *             .map(l {@literal ->} l.split(","))
49   *             .map(s {@literal ->} new Word(s[0], s[1]))
50   *             .collect(Collectors.toLit());
51   *         
52   *     }
53   * }
54   * </code></pre>
55   * 
56   * <h3 class="description">Spring Frameworkと連携する場合</h3>
57   * <p>Springと連携している場合は、プロバイダクラスをSpringBeanとして登録しておくことでインジェクションできます。</p>
58   * <p>また、メソッド{@link ReplacedWordProvider#getReplacedWords(FieldAccessor)}は、定義したフィールド単位に呼ばれるため、多数のフィールドで定義していると何度も呼ばれ、効率が悪くなる場合があります。
59   *   <br>このようなときは、Spring Framework3.1から追加された Cache Abstraction(キャッシュの抽象化)機能を使うと改善できます。
60   * </p>
61   * 
62   * <pre class="highlight"><code class="java">
63   * // SpringBeanとして登録する場合。
64   * {@literal @Service}
65   * {@literal @Transactional}
66   * public class ReplacedWordProviderImpl implements ReplacedWordProvider {
67   *     
68   *     // リポジトリのインジェクション
69   *     {@literal @Autowired}
70   *     private ReplacedWordRepository replacedWordRepository;
71   *     
72   *     {@literal @Override}
73   *     public {@literal Collection<Word>} getReplacedWords(final FieldAccessor field) {
74   *         
75   *         final Role role;
76   *         if(field.getDeclaredClass().equals(AdminCsv.class)) {
77   *             role = Role.admin;
78   *         } else {
79   *             role = Role.normal;
80   *         }
81   *         
82   *         return loadWords(role).stream()
83   *             .map(dto {@literal ->} new Word(dto.getWord(), dto.getReplacement()))
84   *             .collect(Collectors.toList());
85   *         
86   *     }
87   *     
88   *     // リポジトリから取得した内容をキャッシュする。
89   *     // 引数 role をキーにして、区別する。
90   *     {@literal @Transactional(readOnly = true)}
91   *     {@literal @Cacheable(cacheNames="replacedWords", key="#role")}
92   *     public {@literal List<WordDto>} loadWords(Role role) {
93   *          
94   *          if(role.euals(Role.admin)) {
95   *              return replacedWordRepository.findByRole(role);
96   *          } else {
97   *              return replacedWordRepository.findAll();
98   *          }
99   *          
100  *     }
101  * }
102  * </code></pre>
103  * 
104  * @since 2.0
105  * @author T.TSUCHIE
106  *
107  */
108 @FunctionalInterface
109 public interface ReplacedWordProvider {
110     
111     /**
112      * 語彙の一覧を取得する。
113      * @param field フィールド情報
114      * @return 語彙を返します。チェック対象の文字がない場合は、空のリストを返します。
115      */
116     Collection<Word> getReplacedWords(FieldAccessor field);
117     
118     /**
119      * 置換語彙を表現するクラス。
120      *
121      * @since 2.0.1
122      * @author T.TSUCHIE
123      *
124      */
125     public static class Word implements Serializable {
126         
127         /** serialVersionUID */
128         private static final long serialVersionUID = 1L;
129         
130         private final String word;
131         
132         private final String replacement;
133         
134         /**
135          * 置換語彙のコンストラクタ。
136          * @param word 置換対象の文字。
137          * @param replacement 置換後の文字。
138          * @throws NullPointerException word or replacement is null.
139          * @throws IllegalArgumentException word is empty.
140          */
141         public Word(final String word, final String replacement) {
142             ArgUtils.notEmpty(word, "word");
143             ArgUtils.notNull(replacement, "replacement");
144             
145             this.word = word;
146             this.replacement = replacement;
147         }
148         
149         /**
150          * 置換対象の語彙を取得する。
151          * @return 置換対象の語彙。
152          */
153         public String getWord() {
154             return word;
155         }
156         
157         /**
158          * 置換後の文字列を返します。
159          * @return 置換語彙の文字列
160          */
161         public String getReplacement() {
162             return replacement;
163         }
164         
165     }
166     
167 }