001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.util; 020 021import java.util.Collection; 022import java.util.Map; 023 024/** 025 * Assertion utility class that assists in validating arguments. 026 * Useful for identifying programmer errors early and clearly at runtime. 027 * Usage also reduces a program's 028 * <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a>. 029 * 030 * <p>For example, if the contract of a public method states it does not 031 * allow <code>null</code> arguments, Assert can be used to validate that 032 * contract. Doing this clearly indicates a contract violation when it 033 * occurs and protects the class's invariants. 034 * 035 * <p>Typically used to validate method arguments rather than configuration 036 * properties, to check for cases that are usually programmer errors rather than 037 * configuration errors. In contrast to config initialization code, there is 038 * usally no point in falling back to defaults in such methods. 039 * 040 * <p>This class is similar to JUnit's assertion library. If an argument value is 041 * deemed invalid, an {@link IllegalArgumentException} is thrown (typically). 042 * For example: 043 * 044 * <pre class="code"> 045 * Assert.notNull(clazz, "The class must not be null"); 046 * Assert.isTrue(i > 0, "The value must be greater than zero");</pre> 047 * 048 * Mainly for internal use within the framework; consider Jakarta's Commons Lang 049 * >= 2.0 for a more comprehensive suite of assertion utilities. 050 * <p/> 051 * <em>Gratefully borrowed from the Spring Framework, also Apache 2.0 licensed</em> 052 * 053 * @author Keith Donald 054 * @author Juergen Hoeller 055 * @author Colin Sampaleanu 056 * @author Rob Harrop 057 * @since 1.3 058 */ 059public abstract class Assert { 060 061 /** 062 * Assert a boolean expression, throwing <code>IllegalArgumentException</code> 063 * if the test result is <code>false</code>. 064 * <pre class="code">Assert.isTrue(i > 0, "The value must be greater than zero");</pre> 065 * @param expression a boolean expression 066 * @param message the exception message to use if the assertion fails 067 * @throws IllegalArgumentException if expression is <code>false</code> 068 */ 069 public static void isTrue(boolean expression, String message) { 070 if (!expression) { 071 throw new IllegalArgumentException(message); 072 } 073 } 074 075 /** 076 * Assert a boolean expression, throwing <code>IllegalArgumentException</code> 077 * if the test result is <code>false</code>. 078 * <pre class="code">Assert.isTrue(i > 0);</pre> 079 * @param expression a boolean expression 080 * @throws IllegalArgumentException if expression is <code>false</code> 081 */ 082 public static void isTrue(boolean expression) { 083 isTrue(expression, "[Assertion failed] - this expression must be true"); 084 } 085 086 /** 087 * Assert that an object is <code>null</code> . 088 * <pre class="code">Assert.isNull(value, "The value must be null");</pre> 089 * @param object the object to check 090 * @param message the exception message to use if the assertion fails 091 * @throws IllegalArgumentException if the object is not <code>null</code> 092 */ 093 public static void isNull(Object object, String message) { 094 if (object != null) { 095 throw new IllegalArgumentException(message); 096 } 097 } 098 099 /** 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}