CsvBindingErrors.java
package com.github.mygreen.supercsv.validation;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.github.mygreen.supercsv.util.ArgUtils;
import com.github.mygreen.supercsv.util.Utils;
/**
* CSVのエラー情報を管理するためのクラス。
* <p>SpringFrameworkのBindingResultを参考。</p>
* <p>現状、ネストしたフィールドはサポートしていないため、パスの機能を省略して実装する。</p>
*
* @version 2.2
* @since 2.0
* @author T.TSUCHIE
*
*/
public class CsvBindingErrors implements Serializable {
/** serialVersionUID */
private static final long serialVersionUID = -9014484172903397334L;
/** パスの区切り文字 */
public static final String PATH_SEPARATOR = ".";
/** オブジェクト名 */
private final String objectName;
/** エラーオブジェクト */
private final List<CsvError> errors = new ArrayList<>();
/** エラーコードの候補を生成するクラス */
private MessageCodeGenerator messageCodeGenerator = new MessageCodeGenerator();
/**
* オブジェクト名を指定するコンストラクタ。
* @param objectName メッセージオブジェクトを構成する際に、自動的に付与する名称。
* @throws NullPointerException {@link objectName is null.}
*/
public CsvBindingErrors(final String objectName) {
Objects.requireNonNull(objectName);
this.objectName = objectName;
}
/**
* クラス名を元にオブジェクト名を設定するコンストラクタ。
* @param clazz 検証対象のBeanのクラスタイプ。
*/
public CsvBindingErrors(final Class<?> clazz) {
this(clazz.getSimpleName());
}
/**
* オブジェクト名の取得
* @return コンストラクタで設定したオブジェクト名を取得する。
*/
public String getObjectName() {
return objectName;
}
/**
* 全てのエラー情報を取得する。
* @return 現在のエラー情報
*/
public List<CsvError> getAllErrors() {
return new ArrayList<>(errors);
}
/**
* エラーを追加する
* @param error
*/
public void addError(final CsvError error) {
this.errors.add(error);
}
/**
* 全てのエラー情報を追加する。
* @param errors 追加するエラー情報。
*/
public void addAllErrors(Collection<CsvError> errors) {
this.errors.addAll(errors);
}
/**
* 全てのエラー情報を削除する。
*/
public void clearAllErrors() {
this.errors.clear();
}
/**
* エラー情報が存在するかどうか確かめる。
* @return trueの場合、エラー情報が存在する。
*/
public boolean hasErrors() {
return !errors.isEmpty();
}
/**
* グローバルエラーを取得する
* @return エラーがない場合は空のリストを返す
*/
public List<CsvError> getGlobalErrors() {
final List<CsvError> list = new ArrayList<CsvError>();
for(CsvError item : this.errors) {
if(!(item instanceof CsvFieldError)) {
list.add(item);
}
}
return list;
}
/**
* 先頭のグローバルエラーを取得する。
* @return 存在しない場合は、nullを返す。
*/
public CsvError getFirstGlobalError() {
for(CsvError item : this.errors) {
if(!(item instanceof CsvFieldError)) {
return item;
}
}
return null;
}
/**
* グローバルエラーがあるか確かめる。
* @return
*/
public boolean hasGlobalErrors() {
return !getGlobalErrors().isEmpty();
}
/**
* グローバルエラーの件数を取得する
* @return
*/
public int getGlobalErrorCount() {
return getGlobalErrors().size();
}
/**
* フィールドエラーを取得する
* @return エラーがない場合は空のリストを返す
*/
public List<CsvFieldError> getFieldErrors() {
final List<CsvFieldError> list = new ArrayList<CsvFieldError>();
for(CsvError item : this.errors) {
if(item instanceof CsvFieldError) {
list.add((CsvFieldError) item);
}
}
return list;
}
/**
* 先頭のフィールドエラーを取得する
* @return エラーがない場合は空のリストを返す
*/
public CsvFieldError getFirstFieldError() {
for(CsvError item : this.errors) {
if(item instanceof CsvFieldError) {
return (CsvFieldError) item;
}
}
return null;
}
/**
* フィールドエラーが存在するか確かめる。
* @return true:フィールドエラーを持つ。
*/
public boolean hasFieldErrors() {
return !getFieldErrors().isEmpty();
}
/**
* フィールドエラーの件数を取得する。
* @return
*/
public int getFieldErrorCount() {
return getFieldErrors().size();
}
/**
* パスを指定してフィールドエラーを取得する
* @param path 最後に'*'を付けるとワイルドカードが指定可能。
* @return
* @throws IllegalArgumentException {@literal if path is empty.}
*/
public List<CsvFieldError> getFieldErrors(final String path) {
ArgUtils.notEmpty(path, "path");
final List<CsvFieldError> list = new ArrayList<CsvFieldError>();
for(CsvError item : this.errors) {
if(item instanceof CsvFieldError && isMatchingFieldError(path, (CsvFieldError) item)) {
list.add((CsvFieldError) item);
}
}
return list;
}
/**
* パスを指定して先頭のフィールドエラーを取得する
* @param path 最後に'*'を付けるとワイルドカードが指定可能。
* @return エラーがない場合は空のリストを返す
*/
public CsvFieldError getFirstFieldError(final String path) {
ArgUtils.notEmpty(path, "path");
for(CsvError item : this.errors) {
if(item instanceof CsvFieldError && isMatchingFieldError(path, (CsvFieldError) item)) {
return (CsvFieldError) item;
}
}
return null;
}
/**
* 指定したパスのフィィールドエラーが存在するか確かめる。
* @param path 最後に'*'を付けるとワイルドカードが指定可能。
* @return true:エラーがある場合。
*/
public boolean hasFieldErrors(final String path) {
return !getFieldErrors(path).isEmpty();
}
/**
* 指定したパスのフィィールドエラーの件数を取得する。
* @param path 最後に'*'を付けるとワイルドカードが指定可能。
* @return
*/
public int getFieldErrorCount(final String path) {
return getFieldErrors(path).size();
}
/**
* 指定したパスがフィールドエラーのパスと一致するかチェックするかどうか。
* @param path
* @param fieldError
* @return true: 一致する場合。
*/
private boolean isMatchingFieldError(final String path, final CsvFieldError fieldError) {
if (fieldError.getField().equals(path)) {
return true;
}
if(path.endsWith("*")) {
String subPath = path.substring(0, path.length()-1);
return fieldError.getField().startsWith(subPath);
}
return false;
}
/**
* グローバルエラーを登録する。
* @param errorCode エラーコード
*/
public void reject(final String errorCode) {
reject(errorCode, Collections.emptyMap(), null);
}
/**
* グローバルエラーを登録する。
* @param errorCode エラーコード
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void reject(final String errorCode, final String defaultMessage) {
reject(errorCode, Collections.emptyMap(), defaultMessage);
}
/**
* グローバルエラーを登録する。
* @param errorCode エラーコード
* @param messageVariables メッセージ中の変数。
*/
public void reject(final String errorCode, final Map<String, Object> messageVariables) {
reject(errorCode, messageVariables, null);
}
/**
* グローバルエラーを登録する。
* @param errorCode エラーコード
* @param messageVariables メッセージ中の変数。
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void reject(final String errorCode, final Map<String, Object> messageVariables, final String defaultMessage) {
reject(new String[]{errorCode}, messageVariables, defaultMessage);
}
/**
* グローバルエラーを登録する。
* @since 2.2
* @param errorCodes エラーコード
* @param messageVariables メッセージ中の変数。
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void reject(final String[] errorCodes, final Map<String, Object> messageVariables, final String defaultMessage) {
String[] codes = new String[0];
for(String errorCode : errorCodes) {
codes = Utils.concat(codes, messageCodeGenerator.generateCodes(errorCode, getObjectName()));
}
addError(new CsvError(getObjectName(), codes, messageVariables, defaultMessage));
}
/**
* フィールドエラーを登録します。
* @param field フィールドパス。
* @param errorCode エラーコード。
*/
public void rejectValue(final String field, final String errorCode) {
rejectValue(field, null, errorCode, Collections.emptyMap(), null);
}
/**
* フィールドエラーを登録します。
* @param field フィールドパス。
* @param errorCode エラーコード。
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void rejectValue(final String field, final String errorCode, final String defaultMessage) {
rejectValue(field, null, errorCode, Collections.emptyMap(), defaultMessage);
}
/**
* フィールドエラーを登録します。
* @param field フィールドパス。
* @param errorCode エラーコード。
* @param messageVariables メッセージ中の変数。
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void rejectValue(final String field, final String errorCode,
final Map<String, Object> messageVariables, final String defaultMessage) {
rejectValue(field, null, errorCode, Collections.emptyMap(), defaultMessage);
}
/**
* フィールドエラーを登録します。
* @param field フィールドパス。
* @param fieldType フィールドのタイプ
* @param errorCode エラーコード。
* @param messageVariables メッセージ中の変数。
*/
public void rejectValue(final String field, final Class<?> fieldType, final String errorCode,
final Map<String, Object> messageVariables) {
rejectValue(field, fieldType, errorCode, messageVariables, null);
}
/**
* フィールドエラーを登録します。
* @param field フィールドパス。
* @param fieldType フィールドのタイプ
* @param errorCode エラーコード。
* @param messageVariables メッセージ中の変数。
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void rejectValue(final String field, final Class<?> fieldType, final String errorCode,
final Map<String, Object> messageVariables, final String defaultMessage) {
rejectValue(field, fieldType, new String[]{errorCode}, messageVariables, defaultMessage);
}
/**
* フィールドエラーを登録します。
* @since 2.2
* @param field フィールドパス。
* @param fieldType フィールドのタイプ
* @param errorCodes エラーコード。
* @param messageVariables メッセージ中の変数。
* @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
*/
public void rejectValue(final String field, final Class<?> fieldType, final String[] errorCodes,
final Map<String, Object> messageVariables, final String defaultMessage) {
String[] codes = new String[0];
for(String errorCode : errorCodes) {
codes = Utils.concat(codes, messageCodeGenerator.generateCodes(errorCode, getObjectName(), field, fieldType));
}
addError(new CsvFieldError(getObjectName(), field, false, codes, messageVariables, defaultMessage));
}
public MessageCodeGenerator getMessageCodeGenerator() {
return messageCodeGenerator;
}
public void setMessageCodeGenerator(MessageCodeGenerator messageCodeGenerator) {
this.messageCodeGenerator = messageCodeGenerator;
}
}