1 package com.github.mygreen.supercsv.cellprocessor.constraint;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.supercsv.cellprocessor.ift.CellProcessor;
7 import org.supercsv.util.CsvContext;
8
9 import com.github.mygreen.supercsv.cellprocessor.ValidationCellProcessor;
10 import com.github.mygreen.supercsv.cellprocessor.format.TextPrinter;
11
12
13
14
15
16
17
18
19 public class UniqueHashCode<T> extends ValidationCellProcessor {
20
21 private final Map<Integer, ValueObject> encounteredElements = new HashMap<>();
22
23 private final TextPrinter<T> printer;
24
25 public UniqueHashCode(final TextPrinter<T> printer) {
26 super();
27 checkPreconditions(printer);
28 this.printer = printer;
29 }
30
31 public UniqueHashCode(final TextPrinter<T> printer, final CellProcessor next) {
32 super(next);
33 checkPreconditions(printer);
34 this.printer = printer;
35 }
36
37 private static <T> void checkPreconditions(final TextPrinter<T> printer) {
38 if(printer == null) {
39 throw new NullPointerException("printer should not be null.");
40 }
41 }
42
43 @SuppressWarnings("unchecked")
44 @Override
45 public Object execute(final Object value, final CsvContext context) {
46
47 if(value == null) {
48 return next.execute(value, context);
49 }
50
51 final T result = (T)value;
52 final int hashCode = value.hashCode();
53
54 if(encounteredElements.containsKey(hashCode)) {
55
56 final ValueObject duplicatedObject = encounteredElements.get(result);
57 throw createValidationException(context)
58 .messageFormat("duplicate hashCode '%s' encountered.", hashCode)
59 .rejectedValue(result)
60 .messageVariables("hashCode", hashCode)
61 .messageVariables("duplicatedRowNumber", duplicatedObject.rowNumber)
62 .messageVariables("duplicatedLineNumber", duplicatedObject.lineNumber)
63 .messageVariables("printer", getPrinter())
64 .build();
65
66 } else {
67 final ValueObject object = new ValueObject(hashCode, context.getRowNumber(), context.getLineNumber());
68 encounteredElements.put(object.hashCode, object);
69 }
70
71 return next.execute(value, context);
72 }
73
74 private static class ValueObject {
75
76 final int hashCode;
77
78 final int rowNumber;
79
80 final int lineNumber;
81
82 ValueObject(final int hashCode, final int rowNumber, final int lineNumber) {
83 this.hashCode = hashCode;
84 this.rowNumber = rowNumber;
85 this.lineNumber = lineNumber;
86 }
87
88 }
89
90
91
92
93
94 public TextPrinter<T> getPrinter() {
95 return printer;
96 }
97
98 }