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 }