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