View Javadoc
1   package com.github.mygreen.supercsv.exception;
2   
3   import java.util.HashMap;
4   import java.util.Map;
5   import java.util.Optional;
6   
7   import org.supercsv.cellprocessor.ift.CellProcessor;
8   import org.supercsv.exception.SuperCsvCellProcessorException;
9   import org.supercsv.util.CsvContext;
10  
11  import com.github.mygreen.supercsv.util.Utils;
12  
13  /**
14   * {@link CellProcessor}の実行に失敗(入力値が不正)などの時にスローされる例外。
15   * <p>フォーマット用のメッセージや、変数が設定可能。</p>
16   *
17   * @since 2.0
18   * @author T.TSUCHIE
19   *
20   */
21  public class SuperCsvValidationException extends SuperCsvCellProcessorException implements Cloneable {
22      
23      /** serialVersionUID */
24      private static final long serialVersionUID = 3448638872019192862L;
25      
26      private boolean parsedError;
27      
28      private Object rejectedValue;
29      
30      private String validationMessage;
31      
32      private Map<String, Object> messageVariables = new HashMap<>();
33      
34      public SuperCsvValidationException(final String msg, final CsvContext context, final CellProcessor processor) {
35          super(msg, context, processor);
36      }
37      
38      public SuperCsvValidationException(final String msg, final CsvContext context, final CellProcessor processor, final Throwable t) {
39          super(msg, context, processor, t);
40      }
41      
42      /**
43       * 検証に失敗した値を取得する。
44       * @return
45       */
46      public Object getRejectedValue() {
47          return rejectedValue;
48      }
49      
50      /**
51       * 検証用のメッセージを取得する。
52       * @return 検証用のメッセージ。
53       */
54      public String getValidationMessage() {
55          return validationMessage;
56      }
57      
58      /**
59       * 検証用のメッセージ変数を取得する。
60       * @return 検証用のメッセージ変数
61       */
62      public Map<String, Object> getMessageVariables() {
63          return messageVariables;
64      }
65      
66      /**
67       * パース時などの型変換エラーかどうか。
68       * @return trueの場合、型変換エラー。
69       */
70      public boolean isParedError() {
71          return parsedError;
72      }
73      
74      @Override
75      public SuperCsvValidationException clone() {
76          return new Builder(new CsvContext(getCsvContext()), getProcessor())
77                  .message(getMessage())
78                  .exception(getCause())
79                  .rejectedValue(rejectedValue)
80                  .validationMessage(validationMessage)
81                  .messageVariables(messageVariables)
82                  .parsedError(parsedError)
83                  .build();
84      }
85      
86      /**
87       * {@link SuperCsvValidationException}のインスタンスを作成するビルダクラス。
88       *
89       */
90      public final static class Builder {
91          
92          private final CsvContext context;
93          
94          private final CellProcessor processor;
95          
96          private String message;
97          
98          private Throwable exception;
99          
100         private Object rejectedValue;
101         
102         private String validationMessage;
103         
104         private Map<String, Object> messageVariables = new HashMap<>();
105         
106         private boolean parsedError;
107         
108         public Builder(CsvContext context, CellProcessor processor) {
109             this.context = context;
110             this.processor = processor;
111         }
112         
113         /**
114          * 例外用のメッセージを設定する。
115          * @param message 例外用のメッセージ。
116          * @return
117          */
118         public Builder message(String message) {
119             this.message = message;
120             return this;
121         }
122         
123         /**
124          * 例外用のメッセージをフォーマットして設定する。
125          * 
126          * @see String#format(String, Object...)
127          * @param format フォーマット。
128          * @param args 書式の引数。
129          * @return
130          */
131         public Builder messageFormat(final String format, final Object... args) {
132             return message(String.format(format, args));
133         }
134         
135         /**
136          * 例外を設定する。
137          * @param exception 例外。
138          * @return
139          */
140         public Builder exception(Throwable exception) {
141             this.exception = exception;
142             return this;
143             
144         }
145         
146         /**
147          * 検証に失敗した値
148          * @param rejectedValue
149          * @return
150          */
151         public Builder rejectedValue(Object rejectedValue) {
152             this.rejectedValue = rejectedValue;
153             return this;
154         }
155         
156         /**
157          * 検証エラー用メッセージを設定する
158          * @param validationMessage 検証エラー時のメッセージ
159          * @return
160          */
161         public Builder validationMessage(String validationMessage) {
162             this.validationMessage = validationMessage;
163             return this;
164         }
165         
166         /**
167          * 値が存在する場合に検証エラー用メッセージを設定する
168          * @param validationMessage 検証エラー時のメッセージ
169          * @return
170          */
171         public Builder validationMessageIfPresent(Optional<String> validationMessage) {
172             validationMessage.ifPresent(m -> validationMessage(m));
173             return this;
174         }
175         
176         /**
177          * 検証エラー用メッセージの引数を追加する。
178          * @param key キー.
179          * @param value 値
180          * @return
181          */
182         public Builder messageVariables(String key, Object value) {
183             this.messageVariables.put(key, value);
184             return this;
185         }
186         
187         /**
188          * 値が存在する場合に検証エラー用メッセージの引数を追加する。
189          * @param key キー.
190          * @param value 値。
191          * @return
192          */
193         public Builder messageVariablesIfPresent(String key, Optional<?> value) {
194             value.ifPresent(v -> messageVariables.put(key, v));
195             return this;
196         }
197         
198         /**
199          * 値が存在する場合に検証エラー用メッセージの引数を追加する。
200          * @param arguments メッセージ変数のマップ。
201          * @return
202          */
203         public Builder messageVariables(Map<String, Object> arguments) {
204             this.messageVariables.putAll(arguments);
205             return this;
206         }
207         
208         /**
209          * パース時のエラーかどうか設定する。
210          * @param parsedError
211          * @return
212          */
213         public Builder parsedError(boolean parsedError) {
214             this.parsedError = parsedError;
215             return this;
216         }
217         
218         /**
219          * {@link SuperCsvValidationException}のインスタンスを作成する。
220          * @return
221          */
222         public SuperCsvValidationException build() {
223             
224             final String msg = Optional.ofNullable(message)
225                     .orElseGet(() -> processor.getClass().getName() + " error.");
226             
227             final SuperCsvValidationException error;
228             if(exception == null) {
229                 error = new SuperCsvValidationException(msg, context, processor);
230             } else {
231                 error = new SuperCsvValidationException(msg, context, processor, exception);
232             }
233             
234             error.rejectedValue = rejectedValue;
235             
236             if(Utils.isNotEmpty(validationMessage)) {
237                 error.validationMessage = validationMessage;
238             }
239             
240             if(messageVariables.size() > 0) {
241                 error.messageVariables = messageVariables;
242             }
243             
244             error.parsedError = parsedError;
245             
246             return error;
247             
248         }
249         
250     }
251     
252 
253 }