blob: cf2fdf13abc154af46e6671d4be593403b2c0e3c [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 */
45 public static @NonNull String checkStringNotEmpty(final String string,
46 final Object errorMessage) {
47 if (TextUtils.isEmpty(string)) {
48 throw new IllegalArgumentException(String.valueOf(errorMessage));
49 }
50 return string;
51 }
52
53 /**
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070054 * Ensures that an object reference passed as a parameter to the calling
55 * method is not null.
56 *
57 * @param reference an object reference
58 * @return the non-null reference that was validated
59 * @throws NullPointerException if {@code reference} is null
60 */
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -080061 public static @NonNull <T> T checkNotNull(final T reference) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070062 if (reference == null) {
63 throw new NullPointerException();
64 }
65 return reference;
66 }
67
68 /**
69 * Ensures that an object reference passed as a parameter to the calling
70 * method is not null.
71 *
72 * @param reference an object reference
73 * @param errorMessage the exception message to use if the check fails; will
74 * be converted to a string using {@link String#valueOf(Object)}
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, final Object errorMessage) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070079 if (reference == null) {
80 throw new NullPointerException(String.valueOf(errorMessage));
81 }
82 return reference;
83 }
84
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070085 /**
86 * Ensures the truth of an expression involving the state of the calling
87 * instance, but not involving any parameters to the calling method.
88 *
89 * @param expression a boolean expression
90 * @throws IllegalStateException if {@code expression} is false
91 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -070092 public static void checkState(final boolean expression) {
Jeff Sharkeyc268f0b2012-08-24 10:25:31 -070093 if (!expression) {
94 throw new IllegalStateException();
95 }
96 }
Jeff Sharkeyee2f7df2013-09-26 11:32:30 -070097
98 /**
99 * Check the requested flags, throwing if any requested flags are outside
100 * the allowed set.
101 */
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700102 public static void checkFlagsArgument(final int requestedFlags, final int allowedFlags) {
Jeff Sharkeyee2f7df2013-09-26 11:32:30 -0700103 if ((requestedFlags & allowedFlags) != requestedFlags) {
104 throw new IllegalArgumentException("Requested flags 0x"
105 + Integer.toHexString(requestedFlags) + ", but only 0x"
106 + Integer.toHexString(allowedFlags) + " are allowed");
107 }
108 }
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700109
110 /**
111 * Ensures that that the argument numeric value is non-negative.
112 *
113 * @param value a numeric int value
114 * @param errorMessage the exception message to use if the check fails
115 * @return the validated numeric value
116 * @throws IllegalArgumentException if {@code value} was negative
117 */
Philip P. Moltmannc2ad2262016-01-13 09:17:15 -0800118 public static @IntRange(from = 0) int checkArgumentNonnegative(final int value,
119 final String errorMessage) {
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700120 if (value < 0) {
121 throw new IllegalArgumentException(errorMessage);
122 }
123
124 return value;
125 }
126
127 /**
128 * Ensures that that the argument numeric value is non-negative.
129 *
130 * @param value a numeric long 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 */
135 public static long checkArgumentNonnegative(final long value, final String errorMessage) {
136 if (value < 0) {
137 throw new IllegalArgumentException(errorMessage);
138 }
139
140 return value;
141 }
142
143 /**
144 * Ensures that that the argument numeric value is positive.
145 *
146 * @param value a numeric int value
147 * @param errorMessage the exception message to use if the check fails
148 * @return the validated numeric value
149 * @throws IllegalArgumentException if {@code value} was not positive
150 */
151 public static int checkArgumentPositive(final int value, final String errorMessage) {
152 if (value <= 0) {
153 throw new IllegalArgumentException(errorMessage);
154 }
155
156 return value;
157 }
158
159 /**
160 * Ensures that the argument floating point value is a finite number.
161 *
162 * <p>A finite number is defined to be both representable (that is, not NaN) and
163 * not infinite (that is neither positive or negative infinity).</p>
164 *
165 * @param value a floating point value
166 * @param valueName the name of the argument to use if the check fails
167 *
168 * @return the validated floating point value
169 *
170 * @throws IllegalArgumentException if {@code value} was not finite
171 */
172 public static float checkArgumentFinite(final float value, final String valueName) {
173 if (Float.isNaN(value)) {
174 throw new IllegalArgumentException(valueName + " must not be NaN");
175 } else if (Float.isInfinite(value)) {
176 throw new IllegalArgumentException(valueName + " must not be infinite");
177 }
178
179 return value;
180 }
181
182 /**
183 * Ensures that the argument floating point value is within the inclusive range.
184 *
185 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers
186 * will always be out of range.</p>
187 *
188 * @param value a floating point value
189 * @param lower the lower endpoint of the inclusive range
190 * @param upper the upper endpoint of the inclusive range
191 * @param valueName the name of the argument to use if the check fails
192 *
193 * @return the validated floating point value
194 *
195 * @throws IllegalArgumentException if {@code value} was not within the range
196 */
197 public static float checkArgumentInRange(float value, float lower, float upper,
198 String valueName) {
199 if (Float.isNaN(value)) {
200 throw new IllegalArgumentException(valueName + " must not be NaN");
201 } else if (value < lower) {
202 throw new IllegalArgumentException(
203 String.format(
204 "%s is out of range of [%f, %f] (too low)", valueName, lower, upper));
205 } else if (value > upper) {
206 throw new IllegalArgumentException(
207 String.format(
208 "%s is out of range of [%f, %f] (too high)", valueName, lower, upper));
209 }
210
211 return value;
212 }
213
214 /**
Yin-Chia Yeh97f1c852014-05-28 16:36:05 -0700215 * Ensures that the argument int value is within the inclusive range.
216 *
217 * @param value a int value
218 * @param lower the lower endpoint of the inclusive range
219 * @param upper the upper endpoint of the inclusive range
220 * @param valueName the name of the argument to use if the check fails
221 *
222 * @return the validated int value
223 *
224 * @throws IllegalArgumentException if {@code value} was not within the range
225 */
226 public static int checkArgumentInRange(int value, int lower, int upper,
227 String valueName) {
228 if (value < lower) {
229 throw new IllegalArgumentException(
230 String.format(
231 "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
232 } else if (value > upper) {
233 throw new IllegalArgumentException(
234 String.format(
235 "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
236 }
237
238 return value;
239 }
240
241 /**
Ruben Brunk91838de2014-07-16 17:24:17 -0700242 * Ensures that the array is not {@code null}, and none of its elements are {@code null}.
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700243 *
244 * @param value an array of boxed objects
245 * @param valueName the name of the argument to use if the check fails
246 *
247 * @return the validated array
248 *
249 * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
250 */
251 public static <T> T[] checkArrayElementsNotNull(final T[] value, final String valueName) {
252 if (value == null) {
253 throw new NullPointerException(valueName + " must not be null");
254 }
255
256 for (int i = 0; i < value.length; ++i) {
257 if (value[i] == null) {
258 throw new NullPointerException(
259 String.format("%s[%d] must not be null", valueName, i));
260 }
261 }
262
263 return value;
264 }
265
266 /**
Ruben Brunk91838de2014-07-16 17:24:17 -0700267 * Ensures that the {@link Collection} is not {@code null}, and none of its elements are
268 * {@code null}.
269 *
270 * @param value a {@link Collection} of boxed objects
271 * @param valueName the name of the argument to use if the check fails
272 *
273 * @return the validated {@link Collection}
274 *
275 * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
276 */
277 public static <T> Collection<T> checkCollectionElementsNotNull(final Collection<T> value,
278 final String valueName) {
279 if (value == null) {
280 throw new NullPointerException(valueName + " must not be null");
281 }
282
283 long ctr = 0;
284 for (T elem : value) {
285 if (elem == null) {
286 throw new NullPointerException(
287 String.format("%s[%d] must not be null", valueName, ctr));
288 }
289 ++ctr;
290 }
291
292 return value;
293 }
294
295 /**
296 * Ensures that the {@link Collection} is not {@code null}, and contains at least one element.
297 *
298 * @param value a {@link Collection} of boxed elements.
299 * @param valueName the name of the argument to use if the check fails.
300
301 * @return the validated {@link Collection}
302 *
303 * @throws NullPointerException if the {@code value} was {@code null}
304 * @throws IllegalArgumentException if the {@code value} was empty
305 */
306 public static <T> Collection<T> checkCollectionNotEmpty(final Collection<T> value,
307 final String valueName) {
308 if (value == null) {
309 throw new NullPointerException(valueName + " must not be null");
310 }
311 if (value.isEmpty()) {
312 throw new IllegalArgumentException(valueName + " is empty");
313 }
314 return value;
315 }
316
317 /**
Igor Murashkinb3a78b22014-04-17 14:01:13 -0700318 * Ensures that all elements in the argument floating point array are within the inclusive range
319 *
320 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers
321 * will always be out of range.</p>
322 *
323 * @param value a floating point array of values
324 * @param lower the lower endpoint of the inclusive range
325 * @param upper the upper endpoint of the inclusive range
326 * @param valueName the name of the argument to use if the check fails
327 *
328 * @return the validated floating point value
329 *
330 * @throws IllegalArgumentException if any of the elements in {@code value} were out of range
331 * @throws NullPointerException if the {@code value} was {@code null}
332 */
333 public static float[] checkArrayElementsInRange(float[] value, float lower, float upper,
334 String valueName) {
335 checkNotNull(value, valueName + " must not be null");
336
337 for (int i = 0; i < value.length; ++i) {
338 float v = value[i];
339
340 if (Float.isNaN(v)) {
341 throw new IllegalArgumentException(valueName + "[" + i + "] must not be NaN");
342 } else if (v < lower) {
343 throw new IllegalArgumentException(
344 String.format("%s[%d] is out of range of [%f, %f] (too low)",
345 valueName, i, lower, upper));
346 } else if (v > upper) {
347 throw new IllegalArgumentException(
348 String.format("%s[%d] is out of range of [%f, %f] (too high)",
349 valueName, i, lower, upper));
350 }
351 }
352
353 return value;
354 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700355}