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 checkArgument(boolean expression)27 public static void checkArgument(boolean expression) { 28 if (!expression) { 29 throw new IllegalArgumentException(); 30 } 31 } 32 33 /** 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 */ checkNotNull(final T reference)41 public static <T> T checkNotNull(final T reference) { 42 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 */ checkNotNull(final T reference, final Object errorMessage)58 public static <T> T checkNotNull(final T reference, final Object errorMessage) { 59 if (reference == null) { 60 throw new NullPointerException(String.valueOf(errorMessage)); 61 } 62 return reference; 63 } 64 65 /** 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 */ checkState(final boolean expression)72 public static void checkState(final boolean expression) { 73 if (!expression) { 74 throw new IllegalStateException(); 75 } 76 } 77 78 /** 79 * Check the requested flags, throwing if any requested flags are outside 80 * the allowed set. 81 */ checkFlagsArgument(final int requestedFlags, final int allowedFlags)82 public static void checkFlagsArgument(final int requestedFlags, final int allowedFlags) { 83 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 } 89 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 */ checkArgumentNonnegative(final int value, final String errorMessage)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 */ checkArgumentNonnegative(final long value, final String errorMessage)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 */ checkArgumentPositive(final int value, final String errorMessage)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 */ checkArgumentFinite(final float value, final String valueName)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 */ checkArgumentInRange(float value, float lower, float upper, String valueName)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 /** 194 * 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 */ checkArgumentInRange(int value, int lower, int upper, String valueName)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 /** 221 * Ensures that the array is not {@code null}, and none of its elements are {@code null}. 222 * 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 */ checkArrayElementsNotNull(final T[] value, final String valueName)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 /** 246 * 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 */ checkCollectionElementsNotNull(final Collection<T> value, final String valueName)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 */ checkCollectionNotEmpty(final Collection<T> value, final String valueName)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 /** 297 * 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 */ checkArrayElementsInRange(float[] value, float lower, float upper, String valueName)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 } 334 } 335