Home | History | Annotate | Download | only in util
      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      */
     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      */
     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      */
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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