View Javadoc
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   * 値がユニークかチェックするCellProcessor.
14   * 
15   * @since 2.0
16   * @author T.TSUCHIE
17   *
18   */
19  public class Unique<T> extends ValidationCellProcessor {
20      
21      private final Map<T, ValueObject> encounteredElements = new HashMap<>();
22      
23      private final TextPrinter<T> printer;
24      
25      public Unique(final TextPrinter<T> printer) {
26          super();
27          checkPreconditions(printer);
28          this.printer = printer;
29      }
30      
31      public Unique(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          
53          if(encounteredElements.containsKey(result)) {
54              
55              final String formattedValue = printer.print(result);
56              final ValueObject duplicatedObject = encounteredElements.get(result);
57              throw createValidationException(context)
58                  .messageFormat("duplicate value '%s' encountered.", formattedValue)
59                  .rejectedValue(result)
60                  .messageVariables("duplicatedLineNumber", duplicatedObject.lineNumber)
61                  .messageVariables("duplicatedRowNumber", duplicatedObject.rowNumber)
62                  .messageVariables("printer", getPrinter())
63                  .build();
64              
65          } else {
66              final ValueObject object = new ValueObject(result, context.getLineNumber(), context.getRowNumber());
67              encounteredElements.put(object.value, object);
68          }
69          
70          return next.execute(value, context);
71      }
72      
73      private class ValueObject {
74          
75          final T value;
76          
77          final int lineNumber;
78          
79          final int rowNumber;
80          
81          
82          ValueObject(final T value, final int lineNumber, final int rowNumber) {
83              this.value = value;
84              this.lineNumber = lineNumber;
85              this.rowNumber = rowNumber;
86          }
87      }
88      
89      /**
90       * 
91       * @return 値のフォーマッタを取得する。
92       */
93      public TextPrinter<T> getPrinter() {
94          return printer;
95      }
96      
97  }