View Javadoc
1   package org.supercsv.cellprocessor.time;
2   
3   import java.time.format.DateTimeFormatter;
4   import java.time.format.DateTimeParseException;
5   import java.time.temporal.TemporalAccessor;
6   import java.util.Objects;
7   
8   import org.supercsv.cellprocessor.CellProcessorAdaptor;
9   import org.supercsv.cellprocessor.ift.CellProcessor;
10  import org.supercsv.cellprocessor.ift.StringCellProcessor;
11  import org.supercsv.exception.SuperCsvCellProcessorException;
12  import org.supercsv.util.CsvContext;
13  
14  /**
15   * Abstract base class for cell processors converting Strings to {@link TemporalAccessor} types.
16   *
17   * @param <T> the {@link TemporalAccessor} type that the processor returns
18   * @author James Bassett
19   * @since 2.4.0
20   */
21  public abstract class AbstractTemporalAccessorParsingProcessor<T extends TemporalAccessor> extends CellProcessorAdaptor
22  	implements StringCellProcessor {
23  
24  	private final DateTimeFormatter formatter;
25  
26  	/**
27  	 * Constructs a new <tt>AbstractTemporalAccessorParsingProcessor</tt> processor, which
28  	 * parses a String as a {@link TemporalAccessor} type.
29  	 */
30  	public AbstractTemporalAccessorParsingProcessor() {
31  		this.formatter = null;
32  	}
33  
34  	/**
35  	 * Constructs a new <tt>AbstractTemporalAccessorParsingProcessor</tt> processor, which
36  	 * parses a String as a {@link TemporalAccessor} type, then calls the next processor in the
37  	 * chain.
38  	 *
39  	 * @param next the next processor in the chain
40  	 * @throws NullPointerException if next is null
41  	 */
42  	public AbstractTemporalAccessorParsingProcessor(final CellProcessor next) {
43  		super(next);
44  		this.formatter = null;
45  	}
46  
47  	/**
48  	 * Constructs a new <tt>AbstractTemporalAccessorParsingProcessor</tt> processor, which
49  	 * parses a String as a {@link TemporalAccessor} type using the supplied formatter.
50  	 *
51  	 * @param formatter the formatter used for parsing
52  	 * @throws NullPointerException if formatter is null
53  	 */
54  	public AbstractTemporalAccessorParsingProcessor(final DateTimeFormatter formatter) {
55  		checkPreconditions(formatter);
56  		this.formatter = formatter;
57  	}
58  
59  	/**
60  	 * Constructs a new <tt>AbstractTemporalAccessorParsingProcessor</tt> processor, which
61  	 * parses a String as a {@link TemporalAccessor} type using the supplied formatter, then calls
62  	 * the next processor in the chain.
63  	 *
64  	 * @param formatter the formatter used for parsing
65  	 * @param next      the next processor in the chain
66  	 * @throws NullPointerException if formatter or next is null
67  	 */
68  	public AbstractTemporalAccessorParsingProcessor(final DateTimeFormatter formatter, final CellProcessor next) {
69  		super(next);
70  		checkPreconditions(formatter);
71  		this.formatter = formatter;
72  	}
73  
74  	/**
75  	 * Checks the preconditions for creating a new AbstractTemporalAccessorParsingProcessor
76  	 * processor.
77  	 *
78  	 * @param formatter the formatter
79  	 * @throws NullPointerException if formatter is null
80  	 */
81  	private static void checkPreconditions(final DateTimeFormatter formatter) {
82  		Objects.requireNonNull(formatter, "formatter should not be null");
83  	}
84  
85  	/**
86  	 * {@inheritDoc}
87  	 *
88  	 * @throws SuperCsvCellProcessorException if value is null or is not a String
89  	 */
90  	public Object execute(final Object value, final CsvContext context) {
91  		validateInputNotNull(value, context);
92  		if( !(value instanceof String) ) {
93  			throw new SuperCsvCellProcessorException(String.class, value, context, this);
94  		}
95  
96  		final String string = (String) value;
97  		final T result;
98  		try {
99  			if( formatter != null ) {
100 				result = parse(string, formatter);
101 			} else {
102 				result = parse(string);
103 			}
104 		}
105 		catch(DateTimeParseException e) {
106 			throw new SuperCsvCellProcessorException("Failed to parse value", context, this, e);
107 		}
108 
109 		return next.execute(result, context);
110 	}
111 
112 	/**
113 	 * Parses the String into the appropriate {@link TemporalAccessor} type.
114 	 *
115 	 * @param string the string to parse
116 	 * @return the {@link TemporalAccessor} type
117 	 * @throws IllegalArgumentException if the string can't be parsed
118 	 */
119 	protected abstract T parse(final String string);
120 
121 	/**
122 	 * Parses the String into the appropriate {@link TemporalAccessor} type, using the supplied
123 	 * formatter.
124 	 *
125 	 * @param string    the string to parse
126 	 * @param formatter the formatter to use
127 	 * @return the {@link TemporalAccessor} type
128 	 * @throws IllegalArgumentException if the string can't be parsed
129 	 */
130 	protected abstract T parse(final String string, final DateTimeFormatter formatter);
131 
132 }