View Javadoc
1   package com.opencsv.validators;
2   
3   import com.opencsv.exceptions.CsvValidationException;
4   
5   import java.util.ArrayList;
6   import java.util.List;
7   
8   /**
9    * The aggregator's purpose is to collect multiple {@link RowValidator}s and
10   * run them against a single array of strings.
11   * This way complex validations can be performed.
12   *
13   * @author Scott Conway
14   * @since 5.0
15   */
16  public class RowValidatorAggregator {
17      private static final int CAPACITY = 512;
18      private static final int MULTIPLIER = 3;
19      private List<RowValidator> validators = new ArrayList<>();
20  
21      /**
22       * Default constructor.
23       */
24      public RowValidatorAggregator() {
25      }
26  
27      /**
28       * Add a validator to the aggregator.
29       *
30       * @param validator Validator to be added.
31       */
32      public void addValidator(RowValidator validator) {
33          if (validator != null) {
34              validators.add(validator);
35          }
36      }
37  
38      /**
39       * Runs all {@link RowValidator}s' {@link RowValidator#isValid(String[])}
40       * method against the line.
41       * This is a short circuit: as soon as one validator returns {@code false}
42       * then {@code false} is returned.
43       *
44       * @param row Array of strings to be validated.
45       * @return {@code true} if all validators'
46       *   {@link RowValidator#isValid(String[])} methods return {@code true},
47       *   {@code false} otherwise.
48       */
49      public boolean isValid(final String[] row) {
50          return validators.stream().allMatch(v -> v.isValid(row));
51      }
52  
53      /**
54       * Runs all {@link RowValidator}s' {@link RowValidator#validate(String[])}
55       * methods and if the string array is invalid, then it combines all the
56       * validation error messages in a single CsvValidationException.
57       *
58       * @param row Array of Strings to be validation.
59       * @throws CsvValidationException Thrown if the string is invalid.
60       */
61      public void validate(String[] row) throws CsvValidationException {
62          if (validators.isEmpty()) {
63            return;
64          }
65  
66          StringBuilder combinedExceptionMessage = null;
67  
68          for (RowValidator validator : validators) {
69              try {
70                  validator.validate(row);
71              } catch (CsvValidationException ex) {
72                  if (combinedExceptionMessage == null) {
73                      int length = (ex.getMessage().length() + 2) * MULTIPLIER;
74                      combinedExceptionMessage = new StringBuilder(Math.max(length, CAPACITY));
75                  }
76                  combinedExceptionMessage.append(ex.getMessage()).append("\n");
77              }
78          }
79  
80          if (combinedExceptionMessage != null && combinedExceptionMessage.length() > 0) {
81              throw new CsvValidationException(combinedExceptionMessage.toString());
82          }
83      }
84  
85      /**
86       * Setter created for unit test.
87       *
88       * @param validators - list of validators to use.
89       */
90      void setValidators(List<RowValidator> validators) {
91          this.validators = validators;
92      }
93  }