View Javadoc
1   package org.supercsv.cellprocessor.time;
2   
3   import java.time.DateTimeException;
4   import java.time.format.DateTimeFormatter;
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.exception.SuperCsvCellProcessorException;
11  import org.supercsv.util.CsvContext;
12  
13  /**
14   * Abstract base class for cell processors converting {@link TemporalAccessor} types to Strings.
15   *
16   * @author Ludovico Fischer
17   * @since 2.4.0
18   */
19  public abstract class AbstractTemporalAccessorFormattingProcessor<T extends TemporalAccessor>
20  	extends CellProcessorAdaptor {
21  
22  	private final DateTimeFormatter formatter;
23  
24  	/**
25  	 * Constructs a new <tt>AbstractTemporalAccessorFormattingProcessor</tt> processor,
26  	 * which formats the type as a String.
27  	 */
28  	public AbstractTemporalAccessorFormattingProcessor() {
29  		this.formatter = null;
30  
31  	}
32  
33  	/**
34  	 * Constructs a new <tt>AbstractTemporalAccessorFormattingProcessor</tt> processor,
35  	 * which formats the type as a String, then calls the next processor in
36  	 * the chain.
37  	 *
38  	 * @param next next processor in the chain
39  	 * @throws NullPointerException if temporalAccessor or next is null
40  	 */
41  	public AbstractTemporalAccessorFormattingProcessor(final CellProcessor next) {
42  		super(next);
43  		this.formatter = null;
44  
45  	}
46  
47  	/**
48  	 * Constructs a new <tt>AbstractTemporalAccessorFormattingProcessor</tt> processor,
49  	 * which formats the type as a String using the supplied formatter.
50  	 *
51  	 * @param formatter the formatter to use
52  	 * @throws NullPointerException if temporalAccessor or formatter is null
53  	 */
54  	public AbstractTemporalAccessorFormattingProcessor(final DateTimeFormatter formatter) {
55  		checkPreconditions(formatter);
56  		this.formatter = formatter;
57  	}
58  
59  	/**
60  	 * Constructs a new <tt>AbstractTemporalAccessorFormattingProcessor</tt> processor,
61  	 * which formats the type as a String using the supplied formatter,
62  	 * then calls the next processor in the chain.
63  	 *
64  	 * @param formatter the formatter to use
65  	 * @param next      the next processor in the chain
66  	 * @throws NullPointerException if temporalAccessor, formatter or next is null
67  	 */
68  	public AbstractTemporalAccessorFormattingProcessor(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
76  	 * AbstractTemporalAccessorFormattingProcessor processor.
77  	 *
78  	 * @param formatter the formatter
79  	 * @throws NullPointerException if temporalAccessor or 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, not the correct type, or can't be formatted
89  	 */
90  	public Object execute(final Object value, final CsvContext context) {
91  		validateInputNotNull(value, context);
92  		final Class<T> ourType = getType();
93  		if( !(value.getClass().equals(ourType)) ) {
94  			throw new SuperCsvCellProcessorException(ourType, value, context, this);
95  		}
96  		final TemporalAccessor timeType = ourType.cast(value);
97  		try {
98  			if( formatter != null ) {
99  				return formatter.format(timeType);
100 			} else {
101 				return timeType.toString();
102 			}
103 		}
104 		catch(DateTimeException | IllegalArgumentException e) {
105 			throw new SuperCsvCellProcessorException(
106 				String.format("Failed to format value as a %s", ourType.getSimpleName()), context, this, e);
107 		}
108 	}
109 
110 	/**
111 	 * @return the type formatted by this subclass
112 	 */
113 	protected abstract Class<T> getType();
114 
115 }