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 }