blob: 2f26e921d03b37bf28377388fe13ce66723ffb85 [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
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -080019import android.annotation.IntRange;
20import android.annotation.NonNull;
21import android.text.TextUtils;
22
Ruben Brunk91838de2014-07-16 17:24:17 -070023import java.util.Collection;
24
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070025/**
26 * Simple static methods to be called at the start of your own methods to verify
27 * correct arguments and state.
28 */
29public class Preconditions {
30
Jeff Sharkey620b32b2015-04-23 19:36:02 -070031 public static void checkArgument(boolean expression) {
32 if (!expression) {
33 throw new IllegalArgumentException();
34 }
35 }
36
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070037 /**
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -080038 * Ensures that an string reference passed as a parameter to the calling
39 * method is not empty.
40 *
41 * @param string an string reference
42 * @return the string reference that was validated
43 * @throws IllegalArgumentException if {@code string} is empty
44 */
Philip P. Moltmann76d7e3e2016-01-15 13:22:13 -080045 public static @NonNull String checkStringNotEmpty(final String string) {
46 if (TextUtils.isEmpty(string)) {
47 throw new IllegalArgumentException();
48 }
49 return string;
50 }
51
52 /**
53 * Ensures that an string reference passed as a parameter to the calling
54 * method is not empty.
55 *
56 * @param string an string reference
57 * @param errorMessage the exception message to use if the check fails; will
58 * be converted to a string using {@link String#valueOf(Object)}
59 * @return the string reference that was validated
60 * @throws IllegalArgumentException if {@code string} is empty
61 */
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -080062 public static @NonNull String checkStringNotEmpty(final String string,
63 final Object errorMessage) {
64 if (TextUtils.isEmpty(string)) {
65 throw new IllegalArgumentException(String.valueOf(errorMessage));
66 }
67 return string;
68 }
69
70 /**
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070071 * Ensures that an object reference passed as a parameter to the calling
72 * method is not null.
73 *
74 * @param reference an object reference
75 * @return the non-null reference that was validated
76 * @throws NullPointerException if {@code reference} is null
77 */
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -080078 public static @NonNull <T> T checkNotNull(final T reference) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070079 if (reference == null) {
80 throw new NullPointerException();
81 }
82 return reference;
83 }
84
85 /**
86 * Ensures that an object reference passed as a parameter to the calling
87 * method is not null.
88 *
89 * @param reference an object reference
90 * @param errorMessage the exception message to use if the check fails; will
91 * be converted to a string using {@link String#valueOf(Object)}
92 * @return the non-null reference that was validated
93 * @throws NullPointerException if {@code reference} is null
94 */
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -080095 public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070096 if (reference == null) {
97 throw new NullPointerException(String.valueOf(errorMessage));
98 }
99 return reference;
100 }
101
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700102 /**
103 * Ensures the truth of an expression involving the state of the calling
104 * instance, but not involving any parameters to the calling method.
105 *
106 * @param expression a boolean expression
107 * @throws IllegalStateException if {@code expression} is false
108 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700109 public static void checkState(final boolean expression) {
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -0700110 if (!expression) {
111 throw new IllegalStateException();
112 }
113 }
Jeff Sharkeyee2f7df2013-09-26 11:32:30 -0700114
115 /**
116 * Check the requested flags, throwing if any requested flags are outside
117 * the allowed set.
118 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700119 public static void checkFlagsArgument(final int requestedFlags, final int allowedFlags) {
Jeff Sharkeyee2f7df2013-09-26 11:32:30 -0700120 if ((requestedFlags & allowedFlags) != requestedFlags) {
121 throw new IllegalArgumentException("Requested flags 0x"
122 + Integer.toHexString(requestedFlags) + ", but only 0x"
123 + Integer.toHexString(allowedFlags) + " are allowed");
124 }
125 }
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700126
127 /**
128 * Ensures that that the argument numeric value is non-negative.
129 *
130 * @param value a numeric int value
131 * @param errorMessage the exception message to use if the check fails
132 * @return the validated numeric value
133 * @throws IllegalArgumentException if {@code value} was negative
134 */
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -0800135 public static @IntRange(from = 0) int checkArgumentNonnegative(final int value,
136 final String errorMessage) {
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700137 if (value < 0) {
138 throw new IllegalArgumentException(errorMessage);
139 }
140
141 return value;
142 }
143
144 /**
145 * Ensures that that the argument numeric value is non-negative.
146 *
147 * @param value a numeric long value
148 * @param errorMessage the exception message to use if the check fails
149 * @return the validated numeric value
150 * @throws IllegalArgumentException if {@code value} was negative
151 */
152 public static long checkArgumentNonnegative(final long value, final String errorMessage) {
153 if (value < 0) {
154 throw new IllegalArgumentException(errorMessage);
155 }
156
157 return value;
158 }
159
160 /**
161 * Ensures that that the argument numeric value is positive.
162 *
163 * @param value a numeric int value
164 * @param errorMessage the exception message to use if the check fails
165 * @return the validated numeric value
166 * @throws IllegalArgumentException if {@code value} was not positive
167 */
168 public static int checkArgumentPositive(final int value, final String errorMessage) {
169 if (value <= 0) {
170 throw new IllegalArgumentException(errorMessage);
171 }
172
173 return value;
174 }
175
176 /**
177 * Ensures that the argument floating point value is a finite number.
178 *
179 * <p>A finite number is defined to be both representable (that is, not NaN) and
180 * not infinite (that is neither positive or negative infinity).</p>
181 *
182 * @param value a floating point value
183 * @param valueName the name of the argument to use if the check fails
184 *
185 * @return the validated floating point value
186 *
187 * @throws IllegalArgumentException if {@code value} was not finite
188 */
189 public static float checkArgumentFinite(final float value, final String valueName) {
190 if (Float.isNaN(value)) {
191 throw new IllegalArgumentException(valueName + " must not be NaN");
192 } else if (Float.isInfinite(value)) {
193 throw new IllegalArgumentException(valueName + " must not be infinite");
194 }
195
196 return value;
197 }
198
199 /**
200 * Ensures that the argument floating point value is within the inclusive range.
201 *
202 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers
203 * will always be out of range.</p>
204 *
205 * @param value a floating point value
206 * @param lower the lower endpoint of the inclusive range
207 * @param upper the upper endpoint of the inclusive range
208 * @param valueName the name of the argument to use if the check fails
209 *
210 * @return the validated floating point value
211 *
212 * @throws IllegalArgumentException if {@code value} was not within the range
213 */
214 public static float checkArgumentInRange(float value, float lower, float upper,
215 String valueName) {
216 if (Float.isNaN(value)) {
217 throw new IllegalArgumentException(valueName + " must not be NaN");
218 } else if (value < lower) {
219 throw new IllegalArgumentException(
220 String.format(
221 "%s is out of range of [%f, %f] (too low)", valueName, lower, upper));
222 } else if (value > upper) {
223 throw new IllegalArgumentException(
224 String.format(
225 "%s is out of range of [%f, %f] (too high)", valueName, lower, upper));
226 }
227
228 return value;
229 }
230
231 /**
Yin-Chia Yeh97f1c852014-05-28 16:36:05 -0700232 * Ensures that the argument int value is within the inclusive range.
233 *
234 * @param value a int value
235 * @param lower the lower endpoint of the inclusive range
236 * @param upper the upper endpoint of the inclusive range
237 * @param valueName the name of the argument to use if the check fails
238 *
239 * @return the validated int value
240 *
241 * @throws IllegalArgumentException if {@code value} was not within the range
242 */
243 public static int checkArgumentInRange(int value, int lower, int upper,
244 String valueName) {
245 if (value < lower) {
246 throw new IllegalArgumentException(
247 String.format(
248 "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
249 } else if (value > upper) {
250 throw new IllegalArgumentException(
251 String.format(
252 "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
253 }
254
255 return value;
256 }
257
258 /**
Daichi Hirono2dd48252016-01-12 15:46:41 +0900259 * Ensures that the argument long value is within the inclusive range.
260 *
261 * @param value a long value
262 * @param lower the lower endpoint of the inclusive range
263 * @param upper the upper endpoint of the inclusive range
264 * @param valueName the name of the argument to use if the check fails
265 *
266 * @return the validated long value
267 *
268 * @throws IllegalArgumentException if {@code value} was not within the range
269 */
270 public static long checkArgumentInRange(long value, long lower, long upper,
271 String valueName) {
272 if (value < lower) {
273 throw new IllegalArgumentException(
274 String.format(
275 "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
276 } else if (value > upper) {
277 throw new IllegalArgumentException(
278 String.format(
279 "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
280 }
281
282 return value;
283 }
284
285 /**
Ruben Brunk91838de2014-07-16 17:24:17 -0700286 * Ensures that the array is not {@code null}, and none of its elements are {@code null}.
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700287 *
288 * @param value an array of boxed objects
289 * @param valueName the name of the argument to use if the check fails
290 *
291 * @return the validated array
292 *
293 * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
294 */
295 public static <T> T[] checkArrayElementsNotNull(final T[] value, final String valueName) {
296 if (value == null) {
297 throw new NullPointerException(valueName + " must not be null");
298 }
299
300 for (int i = 0; i < value.length; ++i) {
301 if (value[i] == null) {
302 throw new NullPointerException(
303 String.format("%s[%d] must not be null", valueName, i));
304 }
305 }
306
307 return value;
308 }
309
310 /**
Ruben Brunk91838de2014-07-16 17:24:17 -0700311 * Ensures that the {@link Collection} is not {@code null}, and none of its elements are
312 * {@code null}.
313 *
314 * @param value a {@link Collection} of boxed objects
315 * @param valueName the name of the argument to use if the check fails
316 *
317 * @return the validated {@link Collection}
318 *
319 * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
320 */
Philip P. Moltmann76d7e3e2016-01-15 13:22:13 -0800321 public static @NonNull <C extends Collection<T>, T> C checkCollectionElementsNotNull(
322 final C value, final String valueName) {
Ruben Brunk91838de2014-07-16 17:24:17 -0700323 if (value == null) {
324 throw new NullPointerException(valueName + " must not be null");
325 }
326
327 long ctr = 0;
328 for (T elem : value) {
329 if (elem == null) {
330 throw new NullPointerException(
331 String.format("%s[%d] must not be null", valueName, ctr));
332 }
333 ++ctr;
334 }
335
336 return value;
337 }
338
339 /**
340 * Ensures that the {@link Collection} is not {@code null}, and contains at least one element.
341 *
342 * @param value a {@link Collection} of boxed elements.
343 * @param valueName the name of the argument to use if the check fails.
344
345 * @return the validated {@link Collection}
346 *
347 * @throws NullPointerException if the {@code value} was {@code null}
348 * @throws IllegalArgumentException if the {@code value} was empty
349 */
350 public static <T> Collection<T> checkCollectionNotEmpty(final Collection<T> value,
351 final String valueName) {
352 if (value == null) {
353 throw new NullPointerException(valueName + " must not be null");
354 }
355 if (value.isEmpty()) {
356 throw new IllegalArgumentException(valueName + " is empty");
357 }
358 return value;
359 }
360
361 /**
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700362 * Ensures that all elements in the argument floating point array are within the inclusive range
363 *
364 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers
365 * will always be out of range.</p>
366 *
367 * @param value a floating point array of values
368 * @param lower the lower endpoint of the inclusive range
369 * @param upper the upper endpoint of the inclusive range
370 * @param valueName the name of the argument to use if the check fails
371 *
372 * @return the validated floating point value
373 *
374 * @throws IllegalArgumentException if any of the elements in {@code value} were out of range
375 * @throws NullPointerException if the {@code value} was {@code null}
376 */
377 public static float[] checkArrayElementsInRange(float[] value, float lower, float upper,
378 String valueName) {
379 checkNotNull(value, valueName + " must not be null");
380
381 for (int i = 0; i < value.length; ++i) {
382 float v = value[i];
383
384 if (Float.isNaN(v)) {
385 throw new IllegalArgumentException(valueName + "[" + i + "] must not be NaN");
386 } else if (v < lower) {
387 throw new IllegalArgumentException(
388 String.format("%s[%d] is out of range of [%f, %f] (too low)",
389 valueName, i, lower, upper));
390 } else if (v > upper) {
391 throw new IllegalArgumentException(
392 String.format("%s[%d] is out of range of [%f, %f] (too high)",
393 valueName, i, lower, upper));
394 }
395 }
396
397 return value;
398 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700399}