View Javadoc
1   /*
2    * Copyright 2007 Kasper B. Graversen
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.supercsv.cellprocessor.constraint;
17  
18  import org.supercsv.cellprocessor.CellProcessorAdaptor;
19  import org.supercsv.cellprocessor.ift.LongCellProcessor;
20  import org.supercsv.cellprocessor.ift.StringCellProcessor;
21  import org.supercsv.exception.SuperCsvCellProcessorException;
22  import org.supercsv.exception.SuperCsvConstraintViolationException;
23  import org.supercsv.util.CsvContext;
24  
25  /**
26   * Converts the input data to a Long and and ensures the value is between the supplied min and max values (inclusive).
27   * If the data has no upper or lower bound, you should use either of <code>MIN</code> or <code>MAX</code> constants
28   * provided in the class.
29   * 
30   * @author Kasper B. Graversen
31   * @author James Bassett
32   */
33  public class LMinMax extends CellProcessorAdaptor implements StringCellProcessor {
34  	
35  	/** Maximum value for a Long */
36  	public static final long MAX_LONG = Long.MAX_VALUE;
37  	
38  	/** Minimum value for a Long */
39  	public static final long MIN_LONG = Long.MIN_VALUE;
40  	
41  	/** Maximum value for an Integer */
42  	public static final int MAX_INTEGER = Integer.MAX_VALUE;
43  	
44  	/** Minimum value for an Integer */
45  	public static final int MIN_INTEGER = Integer.MIN_VALUE;
46  	
47  	/** Maximum value for a Short */
48  	public static final short MAX_SHORT = Short.MAX_VALUE;
49  	
50  	/** Minimum value for a Short */
51  	public static final short MIN_SHORT = Short.MIN_VALUE;
52  	
53  	/** Maximum value for a Character */
54  	public static final int MAX_CHAR = Character.MAX_VALUE;
55  	
56  	/** Minimum value for a Character */
57  	public static final int MIN_CHAR = Character.MIN_VALUE;
58  	
59  	/** Maximum value for 8 bits (unsigned) */
60  	public static final int MAX_8_BIT_UNSIGNED = 255;
61  	
62  	/** Minimum value for 8 bits (unsigned) */
63  	public static final int MIN_8_BIT_UNSIGNED = 0;
64  	
65  	/** Maximum value for 8 bits (signed) */
66  	public static final int MAX_8_BIT_SIGNED = Byte.MAX_VALUE;
67  	
68  	/** Minimum value for 8 bits (signed) */
69  	public static final int MIN_8_BIT_SIGNED = Byte.MIN_VALUE;
70  	
71  	private final long min;
72  	
73  	private final long max;
74  	
75  	/**
76  	 * Constructs a new <tt>LMinMax</tt> processor, which converts the input data to a Long and and ensures the value is
77  	 * between the supplied min and max values.
78  	 * 
79  	 * @param min
80  	 *            the minimum value (inclusive)
81  	 * @param max
82  	 *            the maximum value (inclusive)
83  	 * @throws IllegalArgumentException
84  	 *             if {@code max < min}
85  	 */
86  	public LMinMax(final long min, final long max) {
87  		super();
88  		checkPreconditions(min, max);
89  		this.min = min;
90  		this.max = max;
91  	}
92  	
93  	/**
94  	 * Constructs a new <tt>LMinMax</tt> processor, which converts the input data to a Long and and ensures the value is
95  	 * between the supplied min and max values, then calls the next processor in the chain.
96  	 * 
97  	 * @param min
98  	 *            the minimum value (inclusive)
99  	 * @param max
100 	 *            the maximum value (inclusive)
101 	 * @param next
102 	 *            the next processor in the chain
103 	 * @throws NullPointerException
104 	 *             if next is null
105 	 * @throws IllegalArgumentException
106 	 *             if {@code max < min}
107 	 */
108 	public LMinMax(final long min, final long max, final LongCellProcessor next) {
109 		super(next);
110 		checkPreconditions(min, max);
111 		this.min = min;
112 		this.max = max;
113 	}
114 	
115 	/**
116 	 * Checks the preconditions for creating a new LMinMax processor.
117 	 * 
118 	 * @param min
119 	 *            the minimum value (inclusive)
120 	 * @param max
121 	 *            the maximum value (inclusive)
122 	 * @throws IllegalArgumentException
123 	 *             if {@code max < min}
124 	 */
125 	private static void checkPreconditions(final long min, final long max) {
126 		if( max < min ) {
127 			throw new IllegalArgumentException(String.format("max (%d) should not be < min (%d)", max, min));
128 		}
129 	}
130 	
131 	/**
132 	 * {@inheritDoc}
133 	 * 
134 	 * @throws SuperCsvCellProcessorException
135 	 *             if value is null or can't be parsed as a Long
136 	 * @throws SuperCsvConstraintViolationException
137 	 *             if value, or doesn't lie between min and max (inclusive)
138 	 */
139 	public Object execute(final Object value, final CsvContext context) {
140 		validateInputNotNull(value, context);
141 		
142 		final Long result;
143 		if( value instanceof Long ) {
144 			result = (Long) value;
145 		} else {
146 			try {
147 				result = Long.parseLong(value.toString());
148 			}
149 			catch(final NumberFormatException e) {
150 				throw new SuperCsvCellProcessorException(String.format("'%s' could not be parsed as a Long", value),
151 					context, this, e);
152 			}
153 		}
154 		
155 		if( result < min || result > max ) {
156 			throw new SuperCsvConstraintViolationException(String.format(
157 				"%d does not lie between the min (%d) and max (%d) values (inclusive)", result, min, max), context,
158 				this);
159 		}
160 		
161 		return next.execute(result, context);
162 	}
163 	
164 }