From 86c1cfa6374547832ad54e7853839d10fabb90d4 Mon Sep 17 00:00:00 2001
From: Henri Yandell 1st function with only the validation option 2nd function with an additional String message parameter. This should
+ * be used only if no additional parameters have to be provided. Instead of using
+ * String operations to create the message String, the following 3rd variant
+ * should be used. Since commons-lang-3.0, for each validation function a similar 3rd validation function exists
+ * with a list of additional message parameters as Objects in ellipsis notation.
+ * This is used instead of simply passing a message String due to performance reasons!
+ * When using a message string, all parameters would have to be string concatenated
+ * before the call, even if no problem arises which would cost performance.
+ * Instead of this, we will concatenate (with spaces) all given msgObjects.toString()
+ * only in case of a failed validation! If the first parameter of the msgObject is a
+ * String, it will be taken as the format string for {@code MessageFormat}.
+ * Simply validating an Argument without further message:
+ *
+ *
+ *
+ * Validating an Argument and adding a message to the IllegalArgumentException:
+ *
+ *
+ *
+ * If the first parameter of the msgObject is a String {@code MessageFormat} will be used:
+ *
+ * Validate.isNotNull(surName);
+ *
+ *
+ *
+ * Validate.isNotNull(surName, "surname must be set");
+ *
+ *
+ * Examples:
+ *
+ * public void myFn(String argString, Integer argInt) {
+ * Validate.notNull(argString);
+ * Validate.notNull(argInt);
+ * Validate.isTrue(argInt.intValue > 3);
+ * }
+ *
+ *
+ * public void myFn(String argString, Integer argInt) {
+ * Validate.notNull(argInt, "Integer parameter must be set);
+ * Validate.isTrue(argInt.intValue > 3, "Integer parameter must be <=3!");
+ * }
+ *
+ *
+ * Validate.isTrue(argInt1.intValue > argInt2.intValue, "param2 actually is {1} but must larger than param1 {0} !", argInt1, argInt2);
+ *
+ *
The same function sometimes exists multiple times in a 4th form with a single message String parameter + * and an additional value parameter. This is essentially the same like the 3rd form, but with fixed + * object values to preserve backward compatibility with Validate 2.0!
+ *
If the message String contains a "{0}"
, it will be passed to
+ * {@code MessageFormat} with the value parameter as single Object parameter. If not, the value parameter
+ * will simply get concatenated to the message String separated with a space.
+ *
Validate an argument, throwing IllegalArgumentException
+ * if the test result is false
.
This is used when validating according to an arbitrary boolean expression, + * such as validating a primitive number or using your own custom validation + * expression.
+ * + *+ * Validate.isTrue(argInt1.intValue > argInt2.intValue, + * "param2 actually is {1} but must larger than param1 {0} !", argInt1, argInt2); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + * @param expression a boolean expression + * @throws IllegalArgumentException if expression isfalse
+ */
+ public static void isTrue(boolean expression, Object... msgObjects) {
+ if (expression == false) {
+ throw new IllegalArgumentException(getMessage(msgObjects));
+ }
+ }
+
// notNull
//---------------------------------------------------------------------------------
@@ -221,6 +313,28 @@ public class Validate {
notNull(object, "The validated object is null");
}
+
+ /**
+ * Validate an argument, throwing IllegalArgumentException
+ * if the argument is null
.
+ * Validate.notNull(myObject, "This happens while processing user {0}, currentUser); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + * @param object Object to validate + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + */ + public static void notNull(Object object, Object... msgObjects) { + if (object == null) { + throw new IllegalArgumentException(getMessage(msgObjects)); + } + } + // notEmpty array //--------------------------------------------------------------------------------- @@ -259,6 +373,26 @@ public class Validate { notEmpty(array, "The validated array is empty"); } + /** + *Validate an argument, throwing IllegalArgumentException
+ * if the argument array is empty (null
or no elements).
+ * Validate.notEmpty(myArray, "This happens while processing user {0}, currentUser); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + * @param array the array to check is not empty + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + * @throws IllegalArgumentException if the array is empty + */ + public static void notEmpty(Object[] array, Object... msgObjects) { + notEmpty(array, getMessage(msgObjects)); + } + // notEmpty collection //--------------------------------------------------------------------------------- @@ -297,6 +431,26 @@ public class Validate { notEmpty(collection, "The validated collection is empty"); } + /** + *Validate an argument, throwing IllegalArgumentException
+ * if the argument Collection is empty (null
or no elements).
+ * Validate.notEmpty(myCollection, "This happens while processing user {0}, currentUser); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + * @param collection the collection to check is not empty + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + * @throws IllegalArgumentException if the collection is empty + */ + public static void notEmpty(Collection> collection, Object... msgObjects) { + notEmpty(collection, getMessage(msgObjects)); + } + // notEmpty map //--------------------------------------------------------------------------------- @@ -335,6 +489,26 @@ public class Validate { notEmpty(map, "The validated map is empty"); } + /** + *Validate an argument, throwing IllegalArgumentException
+ * if the argument Map is empty (null
or no elements).
+ * Validate.notEmpty(myMap, "This happens while processing user {0}, currentUser); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + * @param map the map to check is not empty + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + * @throws IllegalArgumentException if the map is empty + */ + public static void notEmpty(Map,?> map, Object... msgObjects) { + notEmpty(map, getMessage(msgObjects)); + } + // notEmpty string //--------------------------------------------------------------------------------- @@ -373,6 +547,26 @@ public class Validate { notEmpty(string, "The validated string is empty"); } + /** + *Validate an argument, throwing IllegalArgumentException
+ * if the argument String is empty (null
or zero length).
+ * Validate.notEmpty(myString); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + * @param string the string to check is not empty + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + * @throws IllegalArgumentException if the string is empty + */ + public static void notEmpty(String string, Object... msgObjects) { + notEmpty(string, getMessage(msgObjects)); + } + // notNullElements array //--------------------------------------------------------------------------------- @@ -429,6 +623,36 @@ public class Validate { } } + /** + *Validate an argument, throwing IllegalArgumentException
+ * if the argument array has null
elements or is
+ * null
.
+ * Validate.noNullElements(myArray); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + *If the array is null then the message in the exception is 'The validated object is null'.
+ * + * @param array the array to check + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + * @throws IllegalArgumentException if the array hasnull
+ * elements or is null
+ */
+ public static void noNullElements(Object[] array, Object... msgObjects) {
+ Validate.notNull(array);
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] == null) {
+ //X TODO maybe we can add 'i' as 0-th element?
+ throw new IllegalArgumentException(getMessage(msgObjects));
+ }
+ }
+ }
+
// notNullElements collection
//---------------------------------------------------------------------------------
@@ -485,6 +709,41 @@ public class Validate {
}
}
+ /**
+ * Validate an argument, throwing IllegalArgumentException
+ * if the argument Collection has null
elements or is
+ * null
.
+ * Validate.noNullElements(myCollection); + *+ * + *
If the first msgObject is a String, the {@code MessageFormat} will be used to construct the message
+ *Otherwise the message in the exception is 'Validation failed: ' followed by all given + * parameters delimited with spaces.
+ * + *If the collection is null then the message in the exception is 'The validated object is null'.
+ * + * @param collection the collection to check + * @param msgObjects additional Objects added as text message to the InvalidArgumentException + * @throws IllegalArgumentException if the collection has + *null
elements or is null
+ */
+ public static void noNullElements(Collection collection, Object... msgObjects) {
+ Validate.notNull(collection);
+ int i = 0;
+ for (Iterator it = collection.iterator(); it.hasNext(); i++) {
+ if (it.next() == null) {
+ //X TODO how about adding 'i' as 0-th element?
+ throw new IllegalArgumentException(getMessage(msgObjects));
+ }
+ }
+ }
+
+
+ // allElementsOfType collection
+ //---------------------------------------------------------------------------------
+
/**
* Validate an argument, throwing IllegalArgumentException
* if the argument collection is null
or has elements that
@@ -541,4 +800,74 @@ public class Validate {
}
}
+ /**
+ *
+ * Validate an argument, throwing IllegalArgumentException
if the argument collection is
+ * null
or has elements that are not of type clazz
or a subclass.
+ *
+ * Validate.allElementsOfType(collection, String.class); + *+ * + *
+ * The message in the exception is 'The validated collection contains an element not of type clazz at index: '. + *
+ * + * @param collection + * the collection to check, not null + * @param clazz + * theClass
which the collection's elements are expected to be, not null
+ * @since 2.1
+ */
+ public static void allElementsOfType(Collection collection, Class clazz, Object... msgObjects) {
+ Validate.notNull(collection);
+ Validate.notNull(clazz);
+ int i = 0;
+ for (Iterator it = collection.iterator(); it.hasNext(); i++) {
+ if (clazz.isInstance(it.next()) == false) {
+ //X TODO how to add clazz.getName() and i?
+ throw new IllegalArgumentException(getMessage(msgObjects));
+ }
+ }
+ }
+
+ // private helper functions
+ //---------------------------------------------------------------------------------
+
+
+ /**
+ * private helper function to create an error message from the given Objects
+ * If the first object in msgObjects is of type {@code String} then
+ * {@code MessageFormat} will be used to format the output message.
+ *
+ * @param msgObjects
+ * @return concatenated String representation of all the objects
+ */
+ private static String getMessage(Object... msgObjects) {
+ if (msgObjects.length > 0 && msgObjects[0] instanceof String) {
+ String message = (String) msgObjects[0];
+ if (msgObjects.length == 2 && !message.matches("[^\\{]*\\{\\d*\\}.*")) {
+ // if it doesn't contain {0}, {1} etc we simply use string concatenation
+ return message + msgObjects[1]; // no space between to act like original function!
+ }
+
+ MessageFormat form = new MessageFormat((String) msgObjects[0]);
+ Object[] params = new Object[msgObjects.length - 1];
+ System.arraycopy(msgObjects, 1, params, 0, msgObjects.length - 1);
+ return form.format(params);
+ }
+ else {
+ StringBuffer sb = new StringBuffer("Validation failed: [");
+ for(int i = 0; i < msgObjects.length; i++) {
+ if (i > 0) {
+ sb.append(' ');
+ }
+ sb.append(msgObjects[i]);
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+ }
+
}
diff --git a/src/java/org/apache/commons/lang/text/StrBuilder.java b/src/java/org/apache/commons/lang/text/StrBuilder.java
index b8894d495..c823fecc3 100644
--- a/src/java/org/apache/commons/lang/text/StrBuilder.java
+++ b/src/java/org/apache/commons/lang/text/StrBuilder.java
@@ -231,7 +231,7 @@ public class StrBuilder implements CharSequence, Appendable {
public StrBuilder ensureCapacity(int capacity) {
if (capacity > buffer.length) {
char[] old = buffer;
- buffer = new char[capacity];
+ buffer = new char[capacity * 2];
System.arraycopy(old, 0, buffer, 0, size);
}
return this;