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