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