55
55
*/
56
56
public abstract class Assert {
57
57
58
+ /**
59
+ * Assert a boolean expression, throwing an {@code IllegalStateException}
60
+ * if the expression evaluates to {@code false}.
61
+ * <p>Call {@link #isTrue} if you wish to throw an {@code IllegalArgumentException}
62
+ * on an assertion failure.
63
+ * <pre class="code">Assert.state(id == null, "The id property must not already be initialized");</pre>
64
+ * @param expression a boolean expression
65
+ * @param message the exception message to use if the assertion fails
66
+ * @throws IllegalStateException if {@code expression} is {@code false}
67
+ */
68
+ public static void state (boolean expression , String message ) {
69
+ if (!expression ) {
70
+ throw new IllegalStateException (message );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * @deprecated as of 4.3.7, in favor of {@link #state(boolean, String)}
76
+ */
77
+ @ Deprecated
78
+ public static void state (boolean expression ) {
79
+ state (expression , "[Assertion failed] - this state invariant must be true" );
80
+ }
81
+
58
82
/**
59
83
* Assert a boolean expression, throwing an {@code IllegalArgumentException}
60
84
* if the expression evaluates to {@code false}.
@@ -287,21 +311,20 @@ public static void notEmpty(Map<?, ?> map) {
287
311
288
312
/**
289
313
* Assert that the provided object is an instance of the provided class.
290
- * <pre class="code">Assert.instanceOf(Foo.class, foo, "Processing Foo: ");</pre>
314
+ * <pre class="code">Assert.instanceOf(Foo.class, foo, "Foo expected ");</pre>
291
315
* @param type the type to check against
292
316
* @param obj the object to check
293
- * @param message a message which will be prepended to the message generated
294
- * by this method in order to provide further context. It should normally end
295
- * in ":" or "." so that the generated message looks OK when appended to it.
317
+ * @param message a message which will be prepended to provide further context.
318
+ * If it is empty or ends in ":" or ";" or "," or ".", a full exception message
319
+ * will be appended. If it ends in a space, the name of the offending object's
320
+ * type will be appended. In any other case, a ":" with a space and the name
321
+ * of the offending object's type will be appended.
296
322
* @throws IllegalArgumentException if the object is not an instance of type
297
- * @see Class#isInstance
298
323
*/
299
324
public static void isInstanceOf (Class <?> type , Object obj , String message ) {
300
325
notNull (type , "Type to check against must not be null" );
301
326
if (!type .isInstance (obj )) {
302
- String className = (obj != null ? obj .getClass ().getName () : "null" );
303
- throw new IllegalArgumentException (StringUtils .hasLength (message ) ? message + ": " + className :
304
- "Object of class [" + className + "] must be an instance of " + type );
327
+ instanceCheckFailed (type , obj , message );
305
328
}
306
329
}
307
330
@@ -311,27 +334,27 @@ public static void isInstanceOf(Class<?> type, Object obj, String message) {
311
334
* @param type the type to check against
312
335
* @param obj the object to check
313
336
* @throws IllegalArgumentException if the object is not an instance of type
314
- * @see Class#isInstance
315
337
*/
316
338
public static void isInstanceOf (Class <?> type , Object obj ) {
317
339
isInstanceOf (type , obj , "" );
318
340
}
319
341
320
342
/**
321
343
* Assert that {@code superType.isAssignableFrom(subType)} is {@code true}.
322
- * <pre class="code">Assert.isAssignable(Number.class, myClass);</pre>
344
+ * <pre class="code">Assert.isAssignable(Number.class, myClass, "Number expected" );</pre>
323
345
* @param superType the super type to check against
324
346
* @param subType the sub type to check
325
- * @param message a message which will be prepended to the message generated
326
- * by this method in order to provide further context. It should normally end
327
- * in ":" or "." so that the generated message looks OK when appended to it.
347
+ * @param message a message which will be prepended to provide further context.
348
+ * If it is empty or ends in ":" or ";" or "," or ".", a full exception message
349
+ * will be appended. If it ends in a space, the name of the offending sub type
350
+ * will be appended. In any other case, a ":" with a space and the name of the
351
+ * offending sub type will be appended.
328
352
* @throws IllegalArgumentException if the classes are not assignable
329
353
*/
330
354
public static void isAssignable (Class <?> superType , Class <?> subType , String message ) {
331
355
notNull (superType , "Super type to check against must not be null" );
332
356
if (subType == null || !superType .isAssignableFrom (subType )) {
333
- throw new IllegalArgumentException (StringUtils .hasLength (message ) ? message + ": " + subType :
334
- subType + " is not assignable to " + superType );
357
+ assignableCheckFailed (superType , subType , message );
335
358
}
336
359
}
337
360
@@ -346,28 +369,50 @@ public static void isAssignable(Class<?> superType, Class<?> subType) {
346
369
isAssignable (superType , subType , "" );
347
370
}
348
371
349
- /**
350
- * Assert a boolean expression, throwing an {@code IllegalStateException}
351
- * if the expression evaluates to {@code false}.
352
- * <p>Call {@link #isTrue} if you wish to throw an {@code IllegalArgumentException}
353
- * on an assertion failure.
354
- * <pre class="code">Assert.state(id == null, "The id property must not already be initialized");</pre>
355
- * @param expression a boolean expression
356
- * @param message the exception message to use if the assertion fails
357
- * @throws IllegalStateException if {@code expression} is {@code false}
358
- */
359
- public static void state (boolean expression , String message ) {
360
- if (!expression ) {
361
- throw new IllegalStateException (message );
372
+
373
+ private static void instanceCheckFailed (Class <?> type , Object obj , String msg ) {
374
+ String className = (obj != null ? obj .getClass ().getName () : "null" );
375
+ String result = "" ;
376
+ boolean defaultMessage = true ;
377
+ if (StringUtils .hasLength (msg )) {
378
+ if (endsWithSeparator (msg )) {
379
+ result = msg + " " ;
380
+ }
381
+ else {
382
+ result = messageWithTypeName (msg , className );
383
+ defaultMessage = false ;
384
+ }
385
+ }
386
+ if (defaultMessage ) {
387
+ result = result + ("Object of class [" + className + "] must be an instance of " + type );
362
388
}
389
+ throw new IllegalArgumentException (result );
363
390
}
364
391
365
- /**
366
- * @deprecated as of 4.3.7, in favor of {@link #state(boolean, String)}
367
- */
368
- @ Deprecated
369
- public static void state (boolean expression ) {
370
- state (expression , "[Assertion failed] - this state invariant must be true" );
392
+ private static void assignableCheckFailed (Class <?> superType , Class <?> subType , String msg ) {
393
+ String result = "" ;
394
+ boolean defaultMessage = true ;
395
+ if (StringUtils .hasLength (msg )) {
396
+ if (endsWithSeparator (msg )) {
397
+ result = msg + " " ;
398
+ }
399
+ else {
400
+ result = messageWithTypeName (msg , subType );
401
+ defaultMessage = false ;
402
+ }
403
+ }
404
+ if (defaultMessage ) {
405
+ result = result + (subType + " is not assignable to " + superType );
406
+ }
407
+ throw new IllegalArgumentException (result );
408
+ }
409
+
410
+ private static boolean endsWithSeparator (String msg ) {
411
+ return (msg .endsWith (":" ) || msg .endsWith (";" ) || msg .endsWith ("," ) || msg .endsWith ("." ));
412
+ }
413
+
414
+ private static String messageWithTypeName (String msg , Object typeName ) {
415
+ return msg + (msg .endsWith (" " ) ? "" : ": " ) + typeName ;
371
416
}
372
417
373
418
}
0 commit comments