blob: 414b7bc0c4079fdd234e6af716a4f68859a0a008 [file] [log] [blame]
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
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
17package com.android.internal.util;
18
Ruben Brunk91838de2014-07-16 17:24:17 -070019import java.util.Collection;
20
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070021/**
22 * Simple static methods to be called at the start of your own methods to verify
23 * correct arguments and state.
24 */
25public class Preconditions {
26
27 /**
28 * Ensures that an object reference passed as a parameter to the calling
29 * method is not null.
30 *
31 * @param reference an object reference
32 * @return the non-null reference that was validated
33 * @throws NullPointerException if {@code reference} is null
34 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -070035 public static <T> T checkNotNull(final T reference) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070036 if (reference == null) {
37 throw new NullPointerException();
38 }
39 return reference;
40 }
41
42 /**
43 * Ensures that an object reference passed as a parameter to the calling
44 * method is not null.
45 *
46 * @param reference an object reference
47 * @param errorMessage the exception message to use if the check fails; will
48 * be converted to a string using {@link String#valueOf(Object)}
49 * @return the non-null reference that was validated
50 * @throws NullPointerException if {@code reference} is null
51 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -070052 public static <T> T checkNotNull(final T reference, final Object errorMessage) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070053 if (reference == null) {
54 throw new NullPointerException(String.valueOf(errorMessage));
55 }
56 return reference;
57 }
58
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070059 /**
60 * Ensures the truth of an expression involving the state of the calling
61 * instance, but not involving any parameters to the calling method.
62 *
63 * @param expression a boolean expression
64 * @throws IllegalStateException if {@code expression} is false
65 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -070066 public static void checkState(final boolean expression) {
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070067 if (!expression) {
68 throw new IllegalStateException();
69 }
70 }
Jeff Sharkeyee2f7df2013-09-26 11:32:30 -070071
72 /**
73 * Check the requested flags, throwing if any requested flags are outside
74 * the allowed set.
75 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -070076 public static void checkFlagsArgument(final int requestedFlags, final int allowedFlags) {
Jeff Sharkeyee2f7df2013-09-26 11:32:30 -070077 if ((requestedFlags & allowedFlags) != requestedFlags) {
78 throw new IllegalArgumentException("Requested flags 0x"
79 + Integer.toHexString(requestedFlags) + ", but only 0x"
80 + Integer.toHexString(allowedFlags) + " are allowed");
81 }
82 }
Igor Murashkinb3a78b22014-04-17 14:01:13 -070083
84 /**
85 * Ensures that that the argument numeric value is non-negative.
86 *
87 * @param value a numeric int value
88 * @param errorMessage the exception message to use if the check fails
89 * @return the validated numeric value
90 * @throws IllegalArgumentException if {@code value} was negative
91 */
92 public static int checkArgumentNonnegative(final int value, final String errorMessage) {
93 if (value < 0) {
94 throw new IllegalArgumentException(errorMessage);
95 }
96
97 return value;
98 }
99
100 /**
101 * Ensures that that the argument numeric value is non-negative.
102 *
103 * @param value a numeric long value
104 * @param errorMessage the exception message to use if the check fails
105 * @return the validated numeric value
106 * @throws IllegalArgumentException if {@code value} was negative
107 */
108 public static long checkArgumentNonnegative(final long value, final String errorMessage) {
109 if (value < 0) {
110 throw new IllegalArgumentException(errorMessage);
111 }
112
113 return value;
114 }
115
116 /**
117 * Ensures that that the argument numeric value is positive.
118 *
119 * @param value a numeric int value
120 * @param errorMessage the exception message to use if the check fails
121 * @return the validated numeric value
122 * @throws IllegalArgumentException if {@code value} was not positive
123 */
124 public static int checkArgumentPositive(final int value, final String errorMessage) {
125 if (value <= 0) {
126 throw new IllegalArgumentException(errorMessage);
127 }
128
129 return value;
130 }
131
132 /**
133 * Ensures that the argument floating point value is a finite number.
134 *
135 * <p>A finite number is defined to be both representable (that is, not NaN) and
136 * not infinite (that is neither positive or negative infinity).</p>
137 *
138 * @param value a floating point value
139 * @param valueName the name of the argument to use if the check fails
140 *
141 * @return the validated floating point value
142 *
143 * @throws IllegalArgumentException if {@code value} was not finite
144 */
145 public static float checkArgumentFinite(final float value, final String valueName) {
146 if (Float.isNaN(value)) {
147 throw new IllegalArgumentException(valueName + " must not be NaN");
148 } else if (Float.isInfinite(value)) {
149 throw new IllegalArgumentException(valueName + " must not be infinite");
150 }
151
152 return value;
153 }
154
155 /**
156 * Ensures that the argument floating point value is within the inclusive range.
157 *
158 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers
159 * will always be out of range.</p>
160 *
161 * @param value a floating point value
162 * @param lower the lower endpoint of the inclusive range
163 * @param upper the upper endpoint of the inclusive range
164 * @param valueName the name of the argument to use if the check fails
165 *
166 * @return the validated floating point value
167 *
168 * @throws IllegalArgumentException if {@code value} was not within the range
169 */
170 public static float checkArgumentInRange(float value, float lower, float upper,
171 String valueName) {
172 if (Float.isNaN(value)) {
173 throw new IllegalArgumentException(valueName + " must not be NaN");
174 } else if (value < lower) {
175 throw new IllegalArgumentException(
176 String.format(
177 "%s is out of range of [%f, %f] (too low)", valueName, lower, upper));
178 } else if (value > upper) {
179 throw new IllegalArgumentException(
180 String.format(
181 "%s is out of range of [%f, %f] (too high)", valueName, lower, upper));
182 }
183
184 return value;
185 }
186
187 /**
Yin-Chia Yeh97f1c852014-05-28 16:36:05 -0700188 * Ensures that the argument int value is within the inclusive range.
189 *
190 * @param value a int value
191 * @param lower the lower endpoint of the inclusive range
192 * @param upper the upper endpoint of the inclusive range
193 * @param valueName the name of the argument to use if the check fails
194 *
195 * @return the validated int value
196 *
197 * @throws IllegalArgumentException if {@code value} was not within the range
198 */
199 public static int checkArgumentInRange(int value, int lower, int upper,
200 String valueName) {
201 if (value < lower) {
202 throw new IllegalArgumentException(
203 String.format(
204 "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
205 } else if (value > upper) {
206 throw new IllegalArgumentException(
207 String.format(
208 "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
209 }
210
211 return value;
212 }
213
214 /**
Ruben Brunk91838de2014-07-16 17:24:17 -0700215 * Ensures that the array is not {@code null}, and none of its elements are {@code null}.
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700216 *
217 * @param value an array of boxed objects
218 * @param valueName the name of the argument to use if the check fails
219 *
220 * @return the validated array
221 *
222 * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
223 */
224 public static <T> T[] checkArrayElementsNotNull(final T[] value, final String valueName) {
225 if (value == null) {
226 throw new NullPointerException(valueName + " must not be null");
227 }
228
229 for (int i = 0; i < value.length; ++i) {
230 if (value[i] == null) {
231 throw new NullPointerException(
232 String.format("%s[%d] must not be null", valueName, i));
233 }
234 }
235
236 return value;
237 }
238
239 /**
Ruben Brunk91838de2014-07-16 17:24:17 -0700240 * Ensures that the {@link Collection} is not {@code null}, and none of its elements are
241 * {@code null}.
242 *
243 * @param value a {@link Collection} of boxed objects
244 * @param valueName the name of the argument to use if the check fails
245 *
246 * @return the validated {@link Collection}
247 *
248 * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
249 */
250 public static <T> Collection<T> checkCollectionElementsNotNull(final Collection<T> value,
251 final String valueName) {
252 if (value == null) {
253 throw new NullPointerException(valueName + " must not be null");
254 }
255
256 long ctr = 0;
257 for (T elem : value) {
258 if (elem == null) {
259 throw new NullPointerException(
260 String.format("%s[%d] must not be null", valueName, ctr));
261 }
262 ++ctr;
263 }
264
265 return value;
266 }
267
268 /**
269 * Ensures that the {@link Collection} is not {@code null}, and contains at least one element.
270 *
271 * @param value a {@link Collection} of boxed elements.
272 * @param valueName the name of the argument to use if the check fails.
273
274 * @return the validated {@link Collection}
275 *
276 * @throws NullPointerException if the {@code value} was {@code null}
277 * @throws IllegalArgumentException if the {@code value} was empty
278 */
279 public static <T> Collection<T> checkCollectionNotEmpty(final Collection<T> value,
280 final String valueName) {
281 if (value == null) {
282 throw new NullPointerException(valueName + " must not be null");
283 }
284 if (value.isEmpty()) {
285 throw new IllegalArgumentException(valueName + " is empty");
286 }
287 return value;
288 }
289
290 /**
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700291 * Ensures that all elements in the argument floating point array are within the inclusive range
292 *
293 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers
294 * will always be out of range.</p>
295 *
296 * @param value a floating point array of values
297 * @param lower the lower endpoint of the inclusive range
298 * @param upper the upper endpoint of the inclusive range
299 * @param valueName the name of the argument to use if the check fails
300 *
301 * @return the validated floating point value
302 *
303 * @throws IllegalArgumentException if any of the elements in {@code value} were out of range
304 * @throws NullPointerException if the {@code value} was {@code null}
305 */
306 public static float[] checkArrayElementsInRange(float[] value, float lower, float upper,
307 String valueName) {
308 checkNotNull(value, valueName + " must not be null");
309
310 for (int i = 0; i < value.length; ++i) {
311 float v = value[i];
312
313 if (Float.isNaN(v)) {
314 throw new IllegalArgumentException(valueName + "[" + i + "] must not be NaN");
315 } else if (v < lower) {
316 throw new IllegalArgumentException(
317 String.format("%s[%d] is out of range of [%f, %f] (too low)",
318 valueName, i, lower, upper));
319 } else if (v > upper) {
320 throw new IllegalArgumentException(
321 String.format("%s[%d] is out of range of [%f, %f] (too high)",
322 valueName, i, lower, upper));
323 }
324 }
325
326 return value;
327 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700328}