1 package com.opencsv.validators;
2
3 import com.opencsv.exceptions.CsvValidationException;
4
5 import java.util.function.Function;
6
7 /**
8 * This validator is best used to validate a specific property of the row - either about a specific
9 * element or information about the array itself.
10 * <p>An empty or null first row is considered invalid.</p>
11 * <p>As with all row validators the assumption is you have control of the data and have skipped any initial
12 * empty lines AND that your validator checks the size or handles the IndexOutOfBoundsException.</p>
13 * <p>There are several examples coded in the RowFunctionValidatorTest but here are a couple to give you the
14 * idea of the flexibility this validator offers.</p>
15 *
16 * <pre>{@code
17 * private static final String[] GOOD_ROW = {"8675309", "Firstname", "M", "Lastname", "Dec 06, 1951"};
18 * private static final String[] BAD_ROW = {"not a number", "not capitialized", "not an initial", "Not Single word", "12/06/51"};
19 * private static final String[] LONG_ROW = {"8675309", "Firstname", "M", "Lastname", "Dec 06, 1951", "More data"};
20 * private static final String[] SHORT_ROW = {"8675309", "Firstname", "Lastname", "Dec 06, 1951"};
21 *
22 * private static final Function<String[], Boolean> THIRD_ELEMENT_IS_MIDDLE_INITIAL = (x) -> {
23 * return x.length > 2 && x[2].matches("^[A-Z]$");
24 * };
25 *
26 * private static final Function<String[], Boolean> ROW_MUST_HAVE_FIVE_ELEMENTS = (x) -> {
27 * return (x.length == 5);
28 * };
29 * }
30 * {@code @Test}
31 * {@code @DisplayName("Simple test to show checking an middle initial")}
32 * {@code public void thirdElementIsMiddleInitial() {
33 * validator = new RowFunctionValidator(THIRD_ELEMENT_IS_MIDDLE_INITIAL, "The third element must be the middle initial.");
34 *
35 * assertTrue(validator.isValid(GOOD_ROW));
36 * assertFalse(validator.isValid(BAD_ROW));
37 * }
38 * }
39 * {@code @Test}
40 * {@code @DisplayName("The row must have a specific number of elements in order to be valid.")}
41 * {@code public void numberOfElementsInARow() {
42 * validator = new RowFunctionValidator(ROW_MUST_HAVE_FIVE_ELEMENTS, "A Row can have only five elements.");
43 *
44 * assertTrue(validator.isValid(GOOD_ROW));
45 * assertFalse(validator.isValid(LONG_ROW));
46 * assertFalse(validator.isValid(SHORT_ROW));
47 * }
48 * }</pre>
49 *
50 * @author Scott Conway
51 * @since 5.0
52 */
53
54 public class RowFunctionValidator implements RowValidator {
55 private Function<String[], Boolean> testFunction;
56 private String failureMessage;
57
58 /**
59 * Default Constructor.
60 *
61 * @param testFunction - function to run against the Array of Strings.
62 * @param failureMessage - message to be included in the CsvValidationException error message.
63 */
64 public RowFunctionValidator(Function<String[], Boolean> testFunction, String failureMessage) {
65 this.testFunction = testFunction;
66 this.failureMessage = failureMessage;
67 }
68
69 @Override
70 public boolean isValid(String[] row) {
71 if (row == null || row.length == 0) {
72 return false;
73 }
74 return testFunction.apply(row);
75 }
76
77 @Override
78 public void validate(String[] row) throws CsvValidationException {
79 if (!isValid(row)) {
80 throw new CsvValidationException(failureMessage);
81 }
82 }
83 }