CsvBindingErrors.java

  1. package com.github.mygreen.supercsv.validation;

  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.Collections;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Objects;

  9. import com.github.mygreen.supercsv.util.ArgUtils;
  10. import com.github.mygreen.supercsv.util.Utils;

  11. /**
  12.  * CSVのエラー情報を管理するためのクラス。
  13.  * <p>SpringFrameworkのBindingResultを参考。</p>
  14.  * <p>現状、ネストしたフィールドはサポートしていないため、パスの機能を省略して実装する。</p>
  15.  *
  16.  * @version 2.2
  17.  * @since 2.0
  18.  * @author T.TSUCHIE
  19.  *
  20.  */
  21. public class CsvBindingErrors implements Serializable {
  22.    
  23.     /** serialVersionUID */
  24.     private static final long serialVersionUID = -9014484172903397334L;
  25.    
  26.     /** パスの区切り文字 */
  27.     public static final String PATH_SEPARATOR = ".";
  28.    
  29.     /** オブジェクト名 */
  30.     private final String objectName;
  31.    
  32.     /** エラーオブジェクト */
  33.     private final List<CsvError> errors = new ArrayList<>();
  34.    
  35.     /** エラーコードの候補を生成するクラス */
  36.     private MessageCodeGenerator messageCodeGenerator = new MessageCodeGenerator();
  37.    
  38.     /**
  39.      * オブジェクト名を指定するコンストラクタ。
  40.      * @param objectName メッセージオブジェクトを構成する際に、自動的に付与する名称。
  41.      * @throws NullPointerException {@link objectName is null.}
  42.      */
  43.     public CsvBindingErrors(final String objectName) {
  44.         Objects.requireNonNull(objectName);
  45.         this.objectName = objectName;
  46.     }
  47.    
  48.     /**
  49.      * クラス名を元にオブジェクト名を設定するコンストラクタ。
  50.      * @param clazz 検証対象のBeanのクラスタイプ。
  51.      */
  52.     public CsvBindingErrors(final Class<?> clazz) {
  53.         this(clazz.getSimpleName());
  54.     }
  55.    
  56.     /**
  57.      * オブジェクト名の取得
  58.      * @return コンストラクタで設定したオブジェクト名を取得する。
  59.      */
  60.     public String getObjectName() {
  61.         return objectName;
  62.     }
  63.    
  64.     /**
  65.      * 全てのエラー情報を取得する。
  66.      * @return 現在のエラー情報
  67.      */
  68.     public List<CsvError> getAllErrors() {
  69.         return new ArrayList<>(errors);
  70.     }
  71.    
  72.     /**
  73.      * エラーを追加する
  74.      * @param error
  75.      */
  76.     public void addError(final CsvError error) {
  77.         this.errors.add(error);
  78.     }
  79.    
  80.     /**
  81.      * 全てのエラー情報を追加する。
  82.      * @param errors 追加するエラー情報。
  83.      */
  84.     public void addAllErrors(Collection<CsvError> errors) {
  85.         this.errors.addAll(errors);
  86.     }
  87.    
  88.     /**
  89.      * 全てのエラー情報を削除する。
  90.      */
  91.     public void clearAllErrors() {
  92.         this.errors.clear();
  93.     }
  94.    
  95.     /**
  96.      * エラー情報が存在するかどうか確かめる。
  97.      * @return trueの場合、エラー情報が存在する。
  98.      */
  99.     public boolean hasErrors() {
  100.         return !errors.isEmpty();
  101.     }
  102.    
  103.     /**
  104.      * グローバルエラーを取得する
  105.      * @return エラーがない場合は空のリストを返す
  106.      */
  107.     public List<CsvError> getGlobalErrors() {
  108.         final List<CsvError> list = new ArrayList<CsvError>();
  109.         for(CsvError item : this.errors) {
  110.             if(!(item instanceof CsvFieldError)) {
  111.                 list.add(item);
  112.             }
  113.         }
  114.        
  115.         return list;
  116.     }
  117.    
  118.     /**
  119.      * 先頭のグローバルエラーを取得する。
  120.      * @return 存在しない場合は、nullを返す。
  121.      */
  122.     public CsvError getFirstGlobalError() {
  123.         for(CsvError item : this.errors) {
  124.             if(!(item instanceof CsvFieldError)) {
  125.                 return item;
  126.             }
  127.         }
  128.        
  129.         return null;
  130.     }
  131.    
  132.     /**
  133.      * グローバルエラーがあるか確かめる。
  134.      * @return
  135.      */
  136.     public boolean hasGlobalErrors() {
  137.         return !getGlobalErrors().isEmpty();
  138.     }
  139.    
  140.     /**
  141.      * グローバルエラーの件数を取得する
  142.      * @return
  143.      */
  144.     public int getGlobalErrorCount() {
  145.         return getGlobalErrors().size();
  146.     }
  147.    
  148.     /**
  149.      * フィールドエラーを取得する
  150.      * @return エラーがない場合は空のリストを返す
  151.      */
  152.     public List<CsvFieldError> getFieldErrors() {
  153.         final List<CsvFieldError> list = new ArrayList<CsvFieldError>();
  154.         for(CsvError item : this.errors) {
  155.             if(item instanceof CsvFieldError) {
  156.                 list.add((CsvFieldError) item);
  157.             }
  158.         }
  159.        
  160.         return list;
  161.     }
  162.    
  163.     /**
  164.      * 先頭のフィールドエラーを取得する
  165.      * @return エラーがない場合は空のリストを返す
  166.      */
  167.     public CsvFieldError getFirstFieldError() {
  168.         for(CsvError item : this.errors) {
  169.             if(item instanceof CsvFieldError) {
  170.                 return (CsvFieldError) item;
  171.             }
  172.         }
  173.        
  174.         return null;
  175.     }
  176.    
  177.     /**
  178.      * フィールドエラーが存在するか確かめる。
  179.      * @return true:フィールドエラーを持つ。
  180.      */
  181.     public boolean hasFieldErrors() {
  182.         return !getFieldErrors().isEmpty();
  183.     }
  184.    
  185.     /**
  186.      * フィールドエラーの件数を取得する。
  187.      * @return
  188.      */
  189.     public int getFieldErrorCount() {
  190.         return getFieldErrors().size();
  191.     }
  192.    
  193.     /**
  194.      * パスを指定してフィールドエラーを取得する
  195.      * @param path 最後に'*'を付けるとワイルドカードが指定可能。
  196.      * @return
  197.      * @throws IllegalArgumentException {@literal if path is empty.}
  198.      */
  199.     public List<CsvFieldError> getFieldErrors(final String path) {
  200.         ArgUtils.notEmpty(path, "path");
  201.        
  202.         final List<CsvFieldError> list = new ArrayList<CsvFieldError>();
  203.         for(CsvError item : this.errors) {
  204.             if(item instanceof CsvFieldError && isMatchingFieldError(path, (CsvFieldError) item)) {
  205.                 list.add((CsvFieldError) item);
  206.             }
  207.         }
  208.        
  209.         return list;
  210.     }
  211.    
  212.     /**
  213.      * パスを指定して先頭のフィールドエラーを取得する
  214.      * @param path 最後に'*'を付けるとワイルドカードが指定可能。
  215.      * @return エラーがない場合は空のリストを返す
  216.      */
  217.     public CsvFieldError getFirstFieldError(final String path) {
  218.         ArgUtils.notEmpty(path, "path");
  219.        
  220.         for(CsvError item : this.errors) {
  221.             if(item instanceof CsvFieldError && isMatchingFieldError(path, (CsvFieldError) item)) {
  222.                 return (CsvFieldError) item;
  223.             }
  224.         }
  225.        
  226.         return null;
  227.     }
  228.    
  229.     /**
  230.      * 指定したパスのフィィールドエラーが存在するか確かめる。
  231.      * @param path 最後に'*'を付けるとワイルドカードが指定可能。
  232.      * @return true:エラーがある場合。
  233.      */
  234.     public boolean hasFieldErrors(final String path) {
  235.         return !getFieldErrors(path).isEmpty();
  236.     }
  237.    
  238.     /**
  239.      * 指定したパスのフィィールドエラーの件数を取得する。
  240.      * @param path 最後に'*'を付けるとワイルドカードが指定可能。
  241.      * @return
  242.      */
  243.     public int getFieldErrorCount(final String path) {
  244.         return getFieldErrors(path).size();
  245.     }
  246.    
  247.     /**
  248.      * 指定したパスがフィールドエラーのパスと一致するかチェックするかどうか。
  249.      * @param path
  250.      * @param fieldError
  251.      * @return true: 一致する場合。
  252.      */
  253.     private boolean isMatchingFieldError(final String path, final CsvFieldError fieldError) {
  254.        
  255.         if (fieldError.getField().equals(path)) {
  256.             return true;
  257.         }
  258.        
  259.         if(path.endsWith("*")) {
  260.             String subPath = path.substring(0, path.length()-1);
  261.             return fieldError.getField().startsWith(subPath);
  262.         }
  263.        
  264.         return false;
  265.     }
  266.    
  267.     /**
  268.      * グローバルエラーを登録する。
  269.      * @param errorCode エラーコード
  270.      */
  271.     public void reject(final String errorCode) {
  272.         reject(errorCode, Collections.emptyMap(), null);
  273.     }
  274.    
  275.     /**
  276.      * グローバルエラーを登録する。
  277.      * @param errorCode エラーコード
  278.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  279.      */
  280.     public void reject(final String errorCode, final String defaultMessage) {
  281.         reject(errorCode, Collections.emptyMap(), defaultMessage);
  282.     }
  283.    
  284.     /**
  285.      * グローバルエラーを登録する。
  286.      * @param errorCode エラーコード
  287.      * @param messageVariables メッセージ中の変数。
  288.      */
  289.     public void reject(final String errorCode, final Map<String, Object> messageVariables) {
  290.         reject(errorCode, messageVariables, null);
  291.     }
  292.    
  293.     /**
  294.      * グローバルエラーを登録する。
  295.      * @param errorCode エラーコード
  296.      * @param messageVariables メッセージ中の変数。
  297.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  298.      */
  299.     public void reject(final String errorCode, final Map<String, Object> messageVariables, final String defaultMessage) {
  300.         reject(new String[]{errorCode}, messageVariables, defaultMessage);
  301.     }
  302.    
  303.     /**
  304.      * グローバルエラーを登録する。
  305.      * @since 2.2
  306.      * @param errorCodes エラーコード
  307.      * @param messageVariables メッセージ中の変数。
  308.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  309.      */
  310.     public void reject(final String[] errorCodes, final Map<String, Object> messageVariables, final String defaultMessage) {
  311.        
  312.         String[] codes = new String[0];
  313.         for(String errorCode : errorCodes) {
  314.             codes = Utils.concat(codes, messageCodeGenerator.generateCodes(errorCode, getObjectName()));
  315.         }
  316.         addError(new CsvError(getObjectName(), codes, messageVariables, defaultMessage));
  317.     }
  318.    
  319.     /**
  320.      * フィールドエラーを登録します。
  321.      * @param field フィールドパス。
  322.      * @param errorCode エラーコード。
  323.      */
  324.     public void rejectValue(final String field, final String errorCode) {
  325.         rejectValue(field, null, errorCode, Collections.emptyMap(), null);
  326.        
  327.     }
  328.    
  329.     /**
  330.      * フィールドエラーを登録します。
  331.      * @param field フィールドパス。
  332.      * @param errorCode エラーコード。
  333.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  334.      */
  335.     public void rejectValue(final String field, final String errorCode, final String defaultMessage) {
  336.         rejectValue(field, null, errorCode, Collections.emptyMap(), defaultMessage);
  337.        
  338.     }
  339.    
  340.     /**
  341.      * フィールドエラーを登録します。
  342.      * @param field フィールドパス。
  343.      * @param errorCode エラーコード。
  344.      * @param messageVariables メッセージ中の変数。
  345.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  346.      */
  347.     public void rejectValue(final String field, final String errorCode,
  348.             final Map<String, Object> messageVariables, final String defaultMessage) {
  349.        
  350.         rejectValue(field, null, errorCode, Collections.emptyMap(), defaultMessage);
  351.        
  352.     }
  353.    
  354.     /**
  355.      * フィールドエラーを登録します。
  356.      * @param field フィールドパス。
  357.      * @param fieldType フィールドのタイプ
  358.      * @param errorCode エラーコード。
  359.      * @param messageVariables メッセージ中の変数。
  360.      */
  361.     public void rejectValue(final String field, final Class<?> fieldType, final String errorCode,
  362.             final Map<String, Object> messageVariables) {
  363.        
  364.         rejectValue(field, fieldType, errorCode, messageVariables, null);
  365.        
  366.     }
  367.    
  368.     /**
  369.      * フィールドエラーを登録します。
  370.      * @param field フィールドパス。
  371.      * @param fieldType フィールドのタイプ
  372.      * @param errorCode エラーコード。
  373.      * @param messageVariables メッセージ中の変数。
  374.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  375.      */
  376.     public void rejectValue(final String field, final Class<?> fieldType, final String errorCode,
  377.             final Map<String, Object> messageVariables, final String defaultMessage) {
  378.        
  379.         rejectValue(field, fieldType, new String[]{errorCode}, messageVariables, defaultMessage);
  380.     }
  381.    
  382.     /**
  383.      * フィールドエラーを登録します。
  384.      * @since 2.2
  385.      * @param field フィールドパス。
  386.      * @param fieldType フィールドのタイプ
  387.      * @param errorCodes エラーコード。
  388.      * @param messageVariables メッセージ中の変数。
  389.      * @param defaultMessage 指定したエラーコードに対するメッセージが見つからないときに使用するメッセージです。指定しない場合はnullを設定します。
  390.      */
  391.     public void rejectValue(final String field, final Class<?> fieldType, final String[] errorCodes,
  392.             final Map<String, Object> messageVariables, final String defaultMessage) {
  393.        
  394.         String[] codes = new String[0];
  395.         for(String errorCode : errorCodes) {
  396.             codes = Utils.concat(codes, messageCodeGenerator.generateCodes(errorCode, getObjectName(), field, fieldType));
  397.         }
  398.        
  399.         addError(new CsvFieldError(getObjectName(), field, false, codes, messageVariables, defaultMessage));
  400.        
  401.     }
  402.    
  403.     public MessageCodeGenerator getMessageCodeGenerator() {
  404.         return messageCodeGenerator;
  405.     }
  406.    
  407.     public void setMessageCodeGenerator(MessageCodeGenerator messageCodeGenerator) {
  408.         this.messageCodeGenerator = messageCodeGenerator;
  409.     }
  410.    
  411.    
  412. }