• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.internal.util;
18 
19 import java.util.Collection;
20 
21 /**
22  * Simple static methods to be called at the start of your own methods to verify
23  * correct arguments and state.
24  */
25 public 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      */
checkNotNull(final T reference)35     public static <T> T checkNotNull(final T reference) {
36         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      */
checkNotNull(final T reference, final Object errorMessage)52     public static <T> T checkNotNull(final T reference, final Object errorMessage) {
53         if (reference == null) {
54             throw new NullPointerException(String.valueOf(errorMessage));
55         }
56         return reference;
57     }
58 
59     /**
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      */
checkState(final boolean expression)66     public static void checkState(final boolean expression) {
67         if (!expression) {
68             throw new IllegalStateException();
69         }
70     }
71 
72     /**
73      * Check the requested flags, throwing if any requested flags are outside
74      * the allowed set.
75      */
checkFlagsArgument(final int requestedFlags, final int allowedFlags)76     public static void checkFlagsArgument(final int requestedFlags, final int allowedFlags) {
77         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     }
83 
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      */
checkArgumentNonnegative(final int value, final String errorMessage)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      */
checkArgumentNonnegative(final long value, final String errorMessage)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      */
checkArgumentPositive(final int value, final String errorMessage)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      */
checkArgumentFinite(final float value, final String valueName)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      */
checkArgumentInRange(float value, float lower, float upper, String valueName)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     /**
188      * 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      */
checkArgumentInRange(int value, int lower, int upper, String valueName)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     /**
215      * Ensures that the array is not {@code null}, and none of its elements are {@code null}.
216      *
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      */
checkArrayElementsNotNull(final T[] value, final String valueName)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     /**
240      * 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      */
checkCollectionElementsNotNull(final Collection<T> value, final String valueName)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      */
checkCollectionNotEmpty(final Collection<T> value, final String valueName)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     /**
291      * 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      */
checkArrayElementsInRange(float[] value, float lower, float upper, String valueName)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     }
328 }
329