1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.shiro.util; 20 21 import java.util.Collection; 22 import java.util.Map; 23 24 /** 25 * Assertion utility class that assists in validating arguments. 26 * Useful for identifying programmer errors early and clearly at runtime. 27 * Usage also reduces a program's 28 * <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a>. 29 * 30 * <p>For example, if the contract of a public method states it does not 31 * allow <code>null</code> arguments, Assert can be used to validate that 32 * contract. Doing this clearly indicates a contract violation when it 33 * occurs and protects the class's invariants. 34 * 35 * <p>Typically used to validate method arguments rather than configuration 36 * properties, to check for cases that are usually programmer errors rather than 37 * configuration errors. In contrast to config initialization code, there is 38 * usally no point in falling back to defaults in such methods. 39 * 40 * <p>This class is similar to JUnit's assertion library. If an argument value is 41 * deemed invalid, an {@link IllegalArgumentException} is thrown (typically). 42 * For example: 43 * 44 * <pre class="code"> 45 * Assert.notNull(clazz, "The class must not be null"); 46 * Assert.isTrue(i > 0, "The value must be greater than zero");</pre> 47 * 48 * Mainly for internal use within the framework; consider Jakarta's Commons Lang 49 * >= 2.0 for a more comprehensive suite of assertion utilities. 50 * <p/> 51 * <em>Gratefully borrowed from the Spring Framework, also Apache 2.0 licensed</em> 52 * 53 * @author Keith Donald 54 * @author Juergen Hoeller 55 * @author Colin Sampaleanu 56 * @author Rob Harrop 57 * @since 1.3 58 */ 59 public abstract class Assert { 60 61 /** 62 * Assert a boolean expression, throwing <code>IllegalArgumentException</code> 63 * if the test result is <code>false</code>. 64 * <pre class="code">Assert.isTrue(i > 0, "The value must be greater than zero");</pre> 65 * @param expression a boolean expression 66 * @param message the exception message to use if the assertion fails 67 * @throws IllegalArgumentException if expression is <code>false</code> 68 */ 69 public static void isTrue(boolean expression, String message) { 70 if (!expression) { 71 throw new IllegalArgumentException(message); 72 } 73 } 74 75 /** 76 * Assert a boolean expression, throwing <code>IllegalArgumentException</code> 77 * if the test result is <code>false</code>. 78 * <pre class="code">Assert.isTrue(i > 0);</pre> 79 * @param expression a boolean expression 80 * @throws IllegalArgumentException if expression is <code>false</code> 81 */ 82 public static void isTrue(boolean expression) { 83 isTrue(expression, "[Assertion failed] - this expression must be true"); 84 } 85 86 /** 87 * Assert that an object is <code>null</code> . 88 * <pre class="code">Assert.isNull(value, "The value must be null");</pre> 89 * @param object the object to check 90 * @param message the exception message to use if the assertion fails 91 * @throws IllegalArgumentException if the object is not <code>null</code> 92 */ 93 public static void isNull(Object object, String message) { 94 if (object != null) { 95 throw new IllegalArgumentException(message); 96 } 97 } 98 99 /** 100 * Assert that an object is <code>null</code> . 101 * <pre class="code">Assert.isNull(value);</pre> 102 * @param object the object to check 103 * @throws IllegalArgumentException if the object is not <code>null</code> 104 */ 105 public static void isNull(Object object) { 106 isNull(object, "[Assertion failed] - the object argument must be null"); 107 } 108 109 /** 110 * Assert that an object is not <code>null</code> . 111 * <pre class="code">Assert.notNull(clazz, "The class must not be null");</pre> 112 * @param object the object to check 113 * @param message the exception message to use if the assertion fails 114 * @throws IllegalArgumentException if the object is <code>null</code> 115 */ 116 public static void notNull(Object object, String message) { 117 if (object == null) { 118 throw new IllegalArgumentException(message); 119 } 120 } 121 122 /** 123 * Assert that an object is not <code>null</code> . 124 * <pre class="code">Assert.notNull(clazz);</pre> 125 * @param object the object to check 126 * @throws IllegalArgumentException if the object is <code>null</code> 127 */ 128 public static void notNull(Object object) { 129 notNull(object, "[Assertion failed] - this argument is required; it must not be null"); 130 } 131 132 /** 133 * Assert that the given String is not empty; that is, 134 * it must not be <code>null</code> and not the empty String. 135 * <pre class="code">Assert.hasLength(name, "Name must not be empty");</pre> 136 * @param text the String to check 137 * @param message the exception message to use if the assertion fails 138 * @see StringUtils#hasLength 139 */ 140 public static void hasLength(String text, String message) { 141 if (!StringUtils.hasLength(text)) { 142 throw new IllegalArgumentException(message); 143 } 144 } 145 146 /** 147 * Assert that the given String is not empty; that is, 148 * it must not be <code>null</code> and not the empty String. 149 * <pre class="code">Assert.hasLength(name);</pre> 150 * @param text the String to check 151 * @see StringUtils#hasLength 152 */ 153 public static void hasLength(String text) { 154 hasLength(text, 155 "[Assertion failed] - this String argument must have length; it must not be null or empty"); 156 } 157 158 /** 159 * Assert that the given String has valid text content; that is, it must not 160 * be <code>null</code> and must contain at least one non-whitespace character. 161 * <pre class="code">Assert.hasText(name, "'name' must not be empty");</pre> 162 * @param text the String to check 163 * @param message the exception message to use if the assertion fails 164 * @see StringUtils#hasText 165 */ 166 public static void hasText(String text, String message) { 167 if (!StringUtils.hasText(text)) { 168 throw new IllegalArgumentException(message); 169 } 170 } 171 172 /** 173 * Assert that the given String has valid text content; that is, it must not 174 * be <code>null</code> and must contain at least one non-whitespace character. 175 * <pre class="code">Assert.hasText(name, "'name' must not be empty");</pre> 176 * @param text the String to check 177 * @see StringUtils#hasText 178 */ 179 public static void hasText(String text) { 180 hasText(text, 181 "[Assertion failed] - this String argument must have text; it must not be null, empty, or blank"); 182 } 183 184 /** 185 * Assert that the given text does not contain the given substring. 186 * <pre class="code">Assert.doesNotContain(name, "rod", "Name must not contain 'rod'");</pre> 187 * @param textToSearch the text to search 188 * @param substring the substring to find within the text 189 * @param message the exception message to use if the assertion fails 190 */ 191 public static void doesNotContain(String textToSearch, String substring, String message) { 192 if (StringUtils.hasLength(textToSearch) && StringUtils.hasLength(substring) && 193 textToSearch.indexOf(substring) != -1) { 194 throw new IllegalArgumentException(message); 195 } 196 } 197 198 /** 199 * Assert that the given text does not contain the given substring. 200 * <pre class="code">Assert.doesNotContain(name, "rod");</pre> 201 * @param textToSearch the text to search 202 * @param substring the substring to find within the text 203 */ 204 public static void doesNotContain(String textToSearch, String substring) { 205 doesNotContain(textToSearch, substring, 206 "[Assertion failed] - this String argument must not contain the substring [" + substring + "]"); 207 } 208 209 210 /** 211 * Assert that an array has elements; that is, it must not be 212 * <code>null</code> and must have at least one element. 213 * <pre class="code">Assert.notEmpty(array, "The array must have elements");</pre> 214 * @param array the array to check 215 * @param message the exception message to use if the assertion fails 216 * @throws IllegalArgumentException if the object array is <code>null</code> or has no elements 217 */ 218 public static void notEmpty(Object[] array, String message) { 219 if (array == null || array.length == 0) { 220 throw new IllegalArgumentException(message); 221 } 222 } 223 224 /** 225 * Assert that an array has elements; that is, it must not be 226 * <code>null</code> and must have at least one element. 227 * <pre class="code">Assert.notEmpty(array);</pre> 228 * @param array the array to check 229 * @throws IllegalArgumentException if the object array is <code>null</code> or has no elements 230 */ 231 public static void notEmpty(Object[] array) { 232 notEmpty(array, "[Assertion failed] - this array must not be empty: it must contain at least 1 element"); 233 } 234 235 /** 236 * Assert that an array has no null elements. 237 * Note: Does not complain if the array is empty! 238 * <pre class="code">Assert.noNullElements(array, "The array must have non-null elements");</pre> 239 * @param array the array to check 240 * @param message the exception message to use if the assertion fails 241 * @throws IllegalArgumentException if the object array contains a <code>null</code> element 242 */ 243 public static void noNullElements(Object[] array, String message) { 244 if (array != null) { 245 for (int i = 0; i < array.length; i++) { 246 if (array[i] == null) { 247 throw new IllegalArgumentException(message); 248 } 249 } 250 } 251 } 252 253 /** 254 * Assert that an array has no null elements. 255 * Note: Does not complain if the array is empty! 256 * <pre class="code">Assert.noNullElements(array);</pre> 257 * @param array the array to check 258 * @throws IllegalArgumentException if the object array contains a <code>null</code> element 259 */ 260 public static void noNullElements(Object[] array) { 261 noNullElements(array, "[Assertion failed] - this array must not contain any null elements"); 262 } 263 264 /** 265 * Assert that a collection has elements; that is, it must not be 266 * <code>null</code> and must have at least one element. 267 * <pre class="code">Assert.notEmpty(collection, "Collection must have elements");</pre> 268 * @param collection the collection to check 269 * @param message the exception message to use if the assertion fails 270 * @throws IllegalArgumentException if the collection is <code>null</code> or has no elements 271 */ 272 public static void notEmpty(Collection collection, String message) { 273 if (isEmpty(collection)) { 274 throw new IllegalArgumentException(message); 275 } 276 } 277 278 /** 279 * Assert that a collection has elements; that is, it must not be 280 * <code>null</code> and must have at least one element. 281 * <pre class="code">Assert.notEmpty(collection, "Collection must have elements");</pre> 282 * @param collection the collection to check 283 * @throws IllegalArgumentException if the collection is <code>null</code> or has no elements 284 */ 285 public static void notEmpty(Collection collection) { 286 notEmpty(collection, 287 "[Assertion failed] - this collection must not be empty: it must contain at least 1 element"); 288 } 289 290 /** 291 * Assert that a Map has entries; that is, it must not be <code>null</code> 292 * and must have at least one entry. 293 * <pre class="code">Assert.notEmpty(map, "Map must have entries");</pre> 294 * @param map the map to check 295 * @param message the exception message to use if the assertion fails 296 * @throws IllegalArgumentException if the map is <code>null</code> or has no entries 297 */ 298 public static void notEmpty(Map map, String message) { 299 if (isEmpty(map)) { 300 throw new IllegalArgumentException(message); 301 } 302 } 303 304 /** 305 * Assert that a Map has entries; that is, it must not be <code>null</code> 306 * and must have at least one entry. 307 * <pre class="code">Assert.notEmpty(map);</pre> 308 * @param map the map to check 309 * @throws IllegalArgumentException if the map is <code>null</code> or has no entries 310 */ 311 public static void notEmpty(Map map) { 312 notEmpty(map, "[Assertion failed] - this map must not be empty; it must contain at least one entry"); 313 } 314 315 316 /** 317 * Assert that the provided object is an instance of the provided class. 318 * <pre class="code">Assert.instanceOf(Foo.class, foo);</pre> 319 * @param clazz the required class 320 * @param obj the object to check 321 * @throws IllegalArgumentException if the object is not an instance of clazz 322 * @see Class#isInstance 323 */ 324 public static void isInstanceOf(Class clazz, Object obj) { 325 isInstanceOf(clazz, obj, ""); 326 } 327 328 /** 329 * Assert that the provided object is an instance of the provided class. 330 * <pre class="code">Assert.instanceOf(Foo.class, foo);</pre> 331 * @param type the type to check against 332 * @param obj the object to check 333 * @param message a message which will be prepended to the message produced by 334 * the function itself, and which may be used to provide context. It should 335 * normally end in a ": " or ". " so that the function generate message looks 336 * ok when prepended to it. 337 * @throws IllegalArgumentException if the object is not an instance of clazz 338 * @see Class#isInstance 339 */ 340 public static void isInstanceOf(Class type, Object obj, String message) { 341 notNull(type, "Type to check against must not be null"); 342 if (!type.isInstance(obj)) { 343 throw new IllegalArgumentException(message + 344 "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + 345 "] must be an instance of " + type); 346 } 347 } 348 349 /** 350 * Assert that <code>superType.isAssignableFrom(subType)</code> is <code>true</code>. 351 * <pre class="code">Assert.isAssignable(Number.class, myClass);</pre> 352 * @param superType the super type to check 353 * @param subType the sub type to check 354 * @throws IllegalArgumentException if the classes are not assignable 355 */ 356 public static void isAssignable(Class superType, Class subType) { 357 isAssignable(superType, subType, ""); 358 } 359 360 /** 361 * Assert that <code>superType.isAssignableFrom(subType)</code> is <code>true</code>. 362 * <pre class="code">Assert.isAssignable(Number.class, myClass);</pre> 363 * @param superType the super type to check against 364 * @param subType the sub type to check 365 * @param message a message which will be prepended to the message produced by 366 * the function itself, and which may be used to provide context. It should 367 * normally end in a ": " or ". " so that the function generate message looks 368 * ok when prepended to it. 369 * @throws IllegalArgumentException if the classes are not assignable 370 */ 371 public static void isAssignable(Class superType, Class subType, String message) { 372 notNull(superType, "Type to check against must not be null"); 373 if (subType == null || !superType.isAssignableFrom(subType)) { 374 throw new IllegalArgumentException(message + subType + " is not assignable to " + superType); 375 } 376 } 377 378 379 /** 380 * Assert a boolean expression, throwing <code>IllegalStateException</code> 381 * if the test result is <code>false</code>. Call isTrue if you wish to 382 * throw IllegalArgumentException on an assertion failure. 383 * <pre class="code">Assert.state(id == null, "The id property must not already be initialized");</pre> 384 * @param expression a boolean expression 385 * @param message the exception message to use if the assertion fails 386 * @throws IllegalStateException if expression is <code>false</code> 387 */ 388 public static void state(boolean expression, String message) { 389 if (!expression) { 390 throw new IllegalStateException(message); 391 } 392 } 393 394 /** 395 * Assert a boolean expression, throwing {@link IllegalStateException} 396 * if the test result is <code>false</code>. 397 * <p>Call {@link #isTrue(boolean)} if you wish to 398 * throw {@link IllegalArgumentException} on an assertion failure. 399 * <pre class="code">Assert.state(id == null);</pre> 400 * @param expression a boolean expression 401 * @throws IllegalStateException if the supplied expression is <code>false</code> 402 */ 403 public static void state(boolean expression) { 404 state(expression, "[Assertion failed] - this state invariant must be true"); 405 } 406 407 408 ////////////////////////// 409 // From CollectionUtils // 410 ////////////////////////// 411 // CollectionUtils cannot be removed from shiro-core until 2.0 as it has a dependency on PrincipalCollection 412 413 private static boolean isEmpty(Map m) { 414 return m == null || m.isEmpty(); 415 } 416 417 private static boolean isEmpty(Collection c) { 418 return c == null || c.isEmpty(); 419 } 420 421 }