diff --git a/src/java/org/apache/commons/collections/ClosureUtils.java b/src/java/org/apache/commons/collections/ClosureUtils.java
index 77bfc9c56..188acfdd7 100644
--- a/src/java/org/apache/commons/collections/ClosureUtils.java
+++ b/src/java/org/apache/commons/collections/ClosureUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/ClosureUtils.java,v 1.4 2003/11/23 14:41:27 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/ClosureUtils.java,v 1.5 2003/11/23 17:01:36 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -57,12 +57,18 @@
*/
package org.apache.commons.collections;
-import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
-import org.apache.commons.collections.functors.FunctorException;
+import org.apache.commons.collections.functors.ChainedClosure;
+import org.apache.commons.collections.functors.ExceptionClosure;
+import org.apache.commons.collections.functors.ForClosure;
+import org.apache.commons.collections.functors.IfClosure;
+import org.apache.commons.collections.functors.NOPClosure;
+import org.apache.commons.collections.functors.SwitchClosure;
+import org.apache.commons.collections.functors.TransformerClosure;
+import org.apache.commons.collections.functors.WhileClosure;
/**
* ClosureUtils
provides reference implementations and utilities
@@ -82,21 +88,12 @@ import org.apache.commons.collections.functors.FunctorException;
* All the supplied closures are Serializable.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.4 $ $Date: 2003/11/23 14:41:27 $
+ * @version $Revision: 1.5 $ $Date: 2003/11/23 17:01:36 $
*
* @author Stephen Colebourne
*/
public class ClosureUtils {
- /**
- * A Closure that always throws an exception
- */
- private static final Closure EXCEPTION_CLOSURE = new ExceptionClosure();
- /**
- * A Closure that does nothing
- */
- private static final Closure NOP_CLOSURE = new NOPClosure();
-
/**
* This class is not normally instantiated.
*/
@@ -111,7 +108,7 @@ public class ClosureUtils {
* @return the closure
*/
public static Closure exceptionClosure() {
- return EXCEPTION_CLOSURE;
+ return ExceptionClosure.INSTANCE;
}
/**
@@ -121,7 +118,7 @@ public class ClosureUtils {
* @return the closure
*/
public static Closure nopClosure() {
- return NOP_CLOSURE;
+ return NOPClosure.INSTANCE;
}
/**
@@ -129,70 +126,50 @@ public class ClosureUtils {
* The transformer will be called using the closure's input object.
* The transformer's result will be ignored.
*
- * @param transformer the transformer to run each time in the closure
- * @return the closure.
+ * @param transformer the transformer to run each time in the closure, null means nop
+ * @return the closure
*/
public static Closure asClosure(Transformer transformer) {
- if (transformer == null) {
- throw new IllegalArgumentException("The transformer must not be null");
- }
- return new TransformerClosure(transformer);
+ return TransformerClosure.getInstance(transformer);
}
/**
* Creates a Closure that will call the closure count
times.
+ *
+ * A null closure or zero count returns the NOPClosure
.
*
* @param count the number of times to loop
* @param closure the closure to call repeatedly
* @return the for
closure
- * @throws IllegalArgumentException if either argument is null
*/
public static Closure forClosure(int count, Closure closure) {
- if (count < 0) {
- throw new IllegalArgumentException("The loop count must not be less than zero, it was " + count);
- }
- if (closure == null) {
- throw new IllegalArgumentException("The closure must not be null");
- }
- return new ForClosure(count, closure);
+ return ForClosure.getInstance(count, closure);
}
/**
* Creates a Closure that will call the closure repeatedly until the
* predicate returns false.
*
- * @param predicate the predicate to use as an end of loop test
- * @param closure the closure to call repeatedly
+ * @param predicate the predicate to use as an end of loop test, not null
+ * @param closure the closure to call repeatedly, not null
* @return the while
closure
* @throws IllegalArgumentException if either argument is null
*/
public static Closure whileClosure(Predicate predicate, Closure closure) {
- if (predicate == null) {
- throw new IllegalArgumentException("The predicate must not be null");
- }
- if (closure == null) {
- throw new IllegalArgumentException("The closure must not be null");
- }
- return new WhileClosure(predicate, closure, false);
+ return WhileClosure.getInstance(predicate, closure, false);
}
/**
* Creates a Closure that will call the closure once and then repeatedly
* until the predicate returns false.
*
- * @param closure the closure to call repeatedly
- * @param predicate the predicate to use as an end of loop test
+ * @param closure the closure to call repeatedly, not null
+ * @param predicate the predicate to use as an end of loop test, not null
* @return the do-while
closure
* @throws IllegalArgumentException if either argument is null
*/
public static Closure doWhileClosure(Closure closure, Predicate predicate) {
- if (closure == null) {
- throw new IllegalArgumentException("The closure must not be null");
- }
- if (predicate == null) {
- throw new IllegalArgumentException("The predicate must not be null");
- }
- return new WhileClosure(predicate, closure, true);
+ return WhileClosure.getInstance(predicate, closure, true);
}
/**
@@ -234,9 +211,7 @@ public class ClosureUtils {
* @throws IllegalArgumentException if either closure is null
*/
public static Closure chainedClosure(Closure closure1, Closure closure2) {
- Closure[] closures = new Closure[] { closure1, closure2 };
- validate(closures);
- return new ChainedClosure(closures);
+ return ChainedClosure.getInstance(closure1, closure2);
}
/**
@@ -246,13 +221,10 @@ public class ClosureUtils {
* @param closures an array of closures to chain
* @return the chained
closure
* @throws IllegalArgumentException if the closures array is null
- * @throws IllegalArgumentException if the closures array has 0 elements
* @throws IllegalArgumentException if any closure in the array is null
*/
public static Closure chainedClosure(Closure[] closures) {
- closures = copy(closures);
- validate(closures);
- return new ChainedClosure(closures);
+ return ChainedClosure.getInstance(closures);
}
/**
@@ -267,17 +239,7 @@ public class ClosureUtils {
* @throws IllegalArgumentException if any closure in the collection is null
*/
public static Closure chainedClosure(Collection closures) {
- if (closures == null) {
- throw new IllegalArgumentException("The closure collection must not be null");
- }
- // convert to array like this to guarantee iterator() ordering
- Closure[] cmds = new Closure[closures.size()];
- int i = 0;
- for (Iterator it = closures.iterator(); it.hasNext();) {
- cmds[i++] = (Closure) it.next();
- }
- validate(cmds);
- return new ChainedClosure(cmds);
+ return ChainedClosure.getInstance(closures);
}
/**
@@ -291,8 +253,8 @@ public class ClosureUtils {
* @throws IllegalArgumentException if the predicate is null
* @throws IllegalArgumentException if either closure is null
*/
- public static Closure switchClosure(Predicate predicate, Closure trueClosure, Closure falseClosure) {
- return switchClosureInternal(new Predicate[] { predicate }, new Closure[] { trueClosure }, falseClosure);
+ public static Closure ifClosure(Predicate predicate, Closure trueClosure, Closure falseClosure) {
+ return IfClosure.getInstance(predicate, trueClosure, falseClosure);
}
/**
@@ -303,16 +265,15 @@ public class ClosureUtils {
* location 0 returned true. Each predicate is evaluated
* until one returns true.
*
- * @param predicates an array of predicates to check
- * @param closures an array of closures to call
+ * @param predicates an array of predicates to check, not null
+ * @param closures an array of closures to call, not null
* @return the switch
closure
* @throws IllegalArgumentException if the either array is null
- * @throws IllegalArgumentException if the either array has 0 elements
* @throws IllegalArgumentException if any element in the arrays is null
* @throws IllegalArgumentException if the arrays are different sizes
*/
public static Closure switchClosure(Predicate[] predicates, Closure[] closures) {
- return switchClosureInternal(copy(predicates), copy(closures), null);
+ return SwitchClosure.getInstance(predicates, closures, null);
}
/**
@@ -324,17 +285,16 @@ public class ClosureUtils {
* until one returns true. If no predicates evaluate to true, the default
* closure is called.
*
- * @param predicates an array of predicates to check
- * @param closures an array of closures to call
+ * @param predicates an array of predicates to check, not null
+ * @param closures an array of closures to call, not null
* @param defaultClosure the default to call if no predicate matches
* @return the switch
closure
* @throws IllegalArgumentException if the either array is null
- * @throws IllegalArgumentException if the either array has 0 elements
* @throws IllegalArgumentException if any element in the arrays is null
* @throws IllegalArgumentException if the arrays are different sizes
*/
public static Closure switchClosure(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
- return switchClosureInternal(copy(predicates), copy(closures), defaultClosure);
+ return SwitchClosure.getInstance(predicates, closures, defaultClosure);
}
/**
@@ -356,48 +316,7 @@ public class ClosureUtils {
* @throws ClassCastException if the map elements are of the wrong type
*/
public static Closure switchClosure(Map predicatesAndClosures) {
- Closure[] trs = null;
- Predicate[] preds = null;
- if (predicatesAndClosures == null) {
- throw new IllegalArgumentException("The predicate and closure map must not be null");
- }
- // convert to array like this to guarantee iterator() ordering
- Closure def = (Closure) predicatesAndClosures.remove(null);
- int size = predicatesAndClosures.size();
- trs = new Closure[size];
- preds = new Predicate[size];
- int i = 0;
- for (Iterator it = predicatesAndClosures.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- preds[i] = (Predicate) entry.getKey();
- trs[i] = (Closure) entry.getValue();
- i++;
- }
- return switchClosureInternal(preds, trs, def);
- }
-
- /**
- * Validate input and create closure.
- *
- * @param predicates an array of predicates to check
- * @param closures an array of closures to call
- * @param defaultClosure the default to call if no predicate matches
- * @return the switch
closure
- * @throws IllegalArgumentException if the either array is null
- * @throws IllegalArgumentException if the either array has 0 elements
- * @throws IllegalArgumentException if any element in the arrays is null
- * @throws IllegalArgumentException if the arrays are different sizes
- */
- private static Closure switchClosureInternal(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
- validate(predicates);
- validate(closures);
- if (predicates.length != closures.length) {
- throw new IllegalArgumentException("The predicate and closure arrays must be the same size");
- }
- if (defaultClosure == null) {
- defaultClosure = nopClosure();
- }
- return new SwitchClosure(predicates, closures, defaultClosure);
+ return SwitchClosure.getInstance(predicatesAndClosures);
}
/**
@@ -435,278 +354,4 @@ public class ClosureUtils {
return switchClosure(preds, trs, def);
}
- /**
- * Clone the predicates to ensure that the internal reference can't be messed with.
- *
- * @param predicates the predicates to copy
- * @return the cloned predicates
- */
- private static Predicate[] copy(Predicate[] predicates) {
- if (predicates == null) {
- return null;
- }
- return (Predicate[]) predicates.clone();
- }
-
- /**
- * Validate the predicates to ensure that all is well.
- *
- * @param predicates the predicates to validate
- * @return the validated predicates
- */
- private static void validate(Predicate[] predicates) {
- if (predicates == null) {
- throw new IllegalArgumentException("The predicate array must not be null");
- }
- if (predicates.length < 1) {
- throw new IllegalArgumentException(
- "At least 1 predicate must be specified in the predicate array, size was " + predicates.length);
- }
- for (int i = 0; i < predicates.length; i++) {
- if (predicates[i] == null) {
- throw new IllegalArgumentException("The predicate array must not contain a null predicate, index " + i + " was null");
- }
- }
- }
-
- /**
- * Clone the closures to ensure that the internal reference can't be messed with.
- *
- * @param closures the closures to copy
- * @return the cloned closures
- */
- private static Closure[] copy(Closure[] closures) {
- if (closures == null) {
- return null;
- }
- return (Closure[]) closures.clone();
- }
-
- /**
- * Validate the closures to ensure that all is well.
- *
- * @param closures the closures to validate
- * @return the validated closures
- */
- private static void validate(Closure[] closures) {
- if (closures == null) {
- throw new IllegalArgumentException("The closure array must not be null");
- }
- if (closures.length < 1) {
- throw new IllegalArgumentException(
- "At least 1 closure must be specified in the closure array, size was " + closures.length);
- }
- for (int i = 0; i < closures.length; i++) {
- if (closures[i] == null) {
- throw new IllegalArgumentException("The closure array must not contain a null closure, index " + i + " was null");
- }
- }
- }
-
- // ExceptionClosure
- //----------------------------------------------------------------------------------
-
- /**
- * ExceptionClosure always throws an exception
- */
- private static class ExceptionClosure implements Closure, Serializable {
-
- /**
- * Constructor
- */
- private ExceptionClosure() {
- super();
- }
-
- /**
- * Always throw an exception
- */
- public void execute(Object input) {
- throw new FunctorException("ExceptionClosure invoked");
- }
- }
-
- // NOPClosure
- //----------------------------------------------------------------------------------
-
- /**
- * NOPClosure does nothing
- */
- private static class NOPClosure implements Closure, Serializable {
-
- /**
- * Constructor
- */
- private NOPClosure() {
- super();
- }
-
- /**
- * Do nothing
- */
- public void execute(Object input) {
- // do nothing
- }
- }
-
- // TransformerClosure
- //----------------------------------------------------------------------------------
-
- /**
- * TransformerClosure calls a Transformer using the input object and ignore the result.
- */
- private static class TransformerClosure implements Closure, Serializable {
- /** The transformer to wrap */
- private final Transformer iTransformer;
-
- /**
- * Constructor to store transformer
- */
- private TransformerClosure(Transformer transformer) {
- super();
- iTransformer = transformer;
- }
-
- /**
- * Call the transformer
- */
- public void execute(Object input) {
- iTransformer.transform(input);
- }
- }
-
- // ChainedClosure
- //----------------------------------------------------------------------------------
-
- /**
- * ChainedClosure calls a list of closures.
- */
- private static class ChainedClosure implements Closure, Serializable {
- /** The closures to call in turn */
- private final Closure[] iClosures;
-
- /**
- * Constructor to store params
- */
- private ChainedClosure(Closure[] closures) {
- super();
- iClosures = closures;
- }
-
- /**
- * Execute a list of closures
- */
- public void execute(Object input) {
- for (int i = 0; i < iClosures.length; i++) {
- iClosures[i].execute(input);
- }
- }
- }
-
- // SwitchClosure
- //----------------------------------------------------------------------------------
-
- /**
- * SwitchClosure calls the closure whose predicate returns true.
- */
- private static class SwitchClosure implements Closure, Serializable {
- /** The tests to consider */
- private final Predicate[] iPredicates;
- /** The matching closures to call */
- private final Closure[] iClosures;
- /** The default closure to call if no tests match */
- private final Closure iDefault;
-
- /**
- * Constructor to store params
- */
- private SwitchClosure(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
- super();
- iPredicates = predicates;
- iClosures = closures;
- iDefault = defaultClosure;
- }
-
- /**
- * Execute the closure whose predicate returns true
- */
- public void execute(Object input) {
- for (int i = 0; i < iPredicates.length; i++) {
- if (iPredicates[i].evaluate(input) == true) {
- iClosures[i].execute(input);
- return;
- }
- }
- iDefault.execute(input);
- }
- }
-
- // ForClosure
- //----------------------------------------------------------------------------------
-
- /**
- * ForClosure calls the closure a fixed number of times.
- */
- private static class ForClosure implements Closure, Serializable {
- /** The number of times to loop */
- private final int iCount;
- /** The closure to call */
- private final Closure iClosure;
-
- /**
- * Constructor to store params
- */
- private ForClosure(int count, Closure closure) {
- super();
- iCount = count;
- iClosure = closure;
- }
-
- /**
- * Execute the closure count times
- */
- public void execute(Object input) {
- for (int i = 0; i < iCount; i++) {
- iClosure.execute(input);
- }
- }
- }
-
- // WhileClosure
- //----------------------------------------------------------------------------------
-
- /**
- * WhileClosure calls the closure until the predicate is false.
- */
- private static class WhileClosure implements Closure, Serializable {
- /** The test condition */
- private final Predicate iPredicate;
- /** The closure to call */
- private final Closure iClosure;
- /** The flag, true is a do loop, false is a while */
- private final boolean iDoLoop;
-
- /**
- * Constructor to store params
- */
- private WhileClosure(Predicate predicate, Closure closure, boolean doLoop) {
- super();
- iPredicate = predicate;
- iClosure = closure;
- iDoLoop = doLoop;
- }
-
- /**
- * Execute the closure until the predicate is false
- */
- public void execute(Object input) {
- if (iDoLoop) {
- iClosure.execute(input);
- }
- while (iPredicate.evaluate(input)) {
- iClosure.execute(input);
- }
- }
- }
-
}
diff --git a/src/java/org/apache/commons/collections/FactoryUtils.java b/src/java/org/apache/commons/collections/FactoryUtils.java
index faec4fd1a..c1fd31d4b 100644
--- a/src/java/org/apache/commons/collections/FactoryUtils.java
+++ b/src/java/org/apache/commons/collections/FactoryUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/FactoryUtils.java,v 1.9 2003/11/23 14:41:27 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/FactoryUtils.java,v 1.10 2003/11/23 17:01:36 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -67,6 +67,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import org.apache.commons.collections.functors.ExceptionFactory;
import org.apache.commons.collections.functors.FunctorException;
/**
@@ -82,16 +83,12 @@ import org.apache.commons.collections.functors.FunctorException;
* All the supplied factories are Serializable.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.9 $ $Date: 2003/11/23 14:41:27 $
+ * @version $Revision: 1.10 $ $Date: 2003/11/23 17:01:36 $
*
* @author Stephen Colebourne
*/
public class FactoryUtils {
- /**
- * A factory that always throws an exception
- */
- private static final Factory EXCEPTION_FACTORY = new ExceptionFactory();
/**
* A factory that always returns null
*/
@@ -111,7 +108,7 @@ public class FactoryUtils {
* @return the factory
*/
public static Factory exceptionFactory() {
- return EXCEPTION_FACTORY;
+ return ExceptionFactory.INSTANCE;
}
/**
@@ -202,29 +199,6 @@ public class FactoryUtils {
return new ReflectionFactory(classToInstantiate, paramTypes, args);
}
- // ExceptionFactory
- //----------------------------------------------------------------------------------
-
- /**
- * ExceptionFactory always throws an exception
- */
- private static class ExceptionFactory implements Factory, Serializable {
-
- /**
- * Constructor
- */
- private ExceptionFactory() {
- super();
- }
-
- /**
- * Always throw an exception
- */
- public Object create() {
- throw new FunctorException("ExceptionFactory invoked");
- }
- }
-
// ConstantFactory
//----------------------------------------------------------------------------------
diff --git a/src/java/org/apache/commons/collections/PredicateUtils.java b/src/java/org/apache/commons/collections/PredicateUtils.java
index ab8d8fd91..cc197c7a6 100644
--- a/src/java/org/apache/commons/collections/PredicateUtils.java
+++ b/src/java/org/apache/commons/collections/PredicateUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/PredicateUtils.java,v 1.11 2003/11/23 14:41:27 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/PredicateUtils.java,v 1.12 2003/11/23 17:01:36 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -63,6 +63,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import org.apache.commons.collections.functors.ExceptionPredicate;
import org.apache.commons.collections.functors.FunctorException;
/**
@@ -90,17 +91,13 @@ import org.apache.commons.collections.functors.FunctorException;
* All the supplied predicates are Serializable.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.11 $ $Date: 2003/11/23 14:41:27 $
+ * @version $Revision: 1.12 $ $Date: 2003/11/23 17:01:36 $
*
* @author Stephen Colebourne
* @author Ola Berg
*/
public class PredicateUtils {
- /**
- * A predicate that always throws an exception
- */
- private static final Predicate EXCEPTION_PREDICATE = new ExceptionPredicate();
/**
* A predicate that always returns true
*/
@@ -135,7 +132,7 @@ public class PredicateUtils {
* @return the predicate
*/
public static Predicate exceptionPredicate() {
- return EXCEPTION_PREDICATE;
+ return ExceptionPredicate.INSTANCE;
}
/**
@@ -584,29 +581,6 @@ public class PredicateUtils {
return preds;
}
- // ExceptionPredicate
- //----------------------------------------------------------------------------------
-
- /**
- * ExceptionPredicate always throws an exception
- */
- private static class ExceptionPredicate implements Predicate, Serializable {
-
- /**
- * Constructor
- */
- private ExceptionPredicate() {
- super();
- }
-
- /**
- * Always throw an exception
- */
- public boolean evaluate(Object object) {
- throw new FunctorException("ExceptionPredicate invoked");
- }
- }
-
// ConstantPredicate
//----------------------------------------------------------------------------------
diff --git a/src/java/org/apache/commons/collections/TransformerUtils.java b/src/java/org/apache/commons/collections/TransformerUtils.java
index c9fcf5ba3..de661e9d0 100644
--- a/src/java/org/apache/commons/collections/TransformerUtils.java
+++ b/src/java/org/apache/commons/collections/TransformerUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/TransformerUtils.java,v 1.6 2003/11/23 14:41:27 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/TransformerUtils.java,v 1.7 2003/11/23 17:01:36 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -64,6 +64,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
+import org.apache.commons.collections.functors.ExceptionTransformer;
import org.apache.commons.collections.functors.FunctorException;
/**
@@ -89,17 +90,13 @@ import org.apache.commons.collections.functors.FunctorException;
* All the supplied transformers are Serializable.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.6 $ $Date: 2003/11/23 14:41:27 $
+ * @version $Revision: 1.7 $ $Date: 2003/11/23 17:01:36 $
*
* @author Stephen Colebourne
* @author James Carman
*/
public class TransformerUtils {
- /**
- * A transformer that always throws an exception
- */
- private static final Transformer EXCEPTION_TRANSFORMER = new ExceptionTransformer();
/**
* A transformer that always returns null
*/
@@ -137,7 +134,7 @@ public class TransformerUtils {
* @return the transformer
*/
public static Transformer exceptionTransformer() {
- return EXCEPTION_TRANSFORMER;
+ return ExceptionTransformer.INSTANCE;
}
/**
@@ -577,29 +574,6 @@ public class TransformerUtils {
}
}
- // ExceptionTransformer
- //----------------------------------------------------------------------------------
-
- /**
- * ExceptionTransformer always throws an exception.
- */
- private static class ExceptionTransformer implements Transformer, Serializable {
-
- /**
- * Constructor
- */
- private ExceptionTransformer() {
- super();
- }
-
- /**
- * Always throw exception
- */
- public Object transform(Object input) {
- throw new FunctorException("ExceptionTransformer invoked");
- }
- }
-
// NOPTransformer
//----------------------------------------------------------------------------------
diff --git a/src/java/org/apache/commons/collections/functors/ChainedClosure.java b/src/java/org/apache/commons/collections/functors/ChainedClosure.java
new file mode 100644
index 000000000..eb8101098
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/ChainedClosure.java
@@ -0,0 +1,164 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/ChainedClosure.java,v 1.1 2003/11/23 17:01:35 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * chained
closure
+ * @throws IllegalArgumentException if the closures array is null
+ * @throws IllegalArgumentException if any closure in the array is null
+ */
+ public static Closure getInstance(Closure[] closures) {
+ FunctorUtils.validate(closures);
+ if (closures.length == 0) {
+ return NOPClosure.INSTANCE;
+ }
+ closures = FunctorUtils.copy(closures);
+ return new ChainedClosure(closures);
+ }
+
+ /**
+ * Create a new Closure that calls each closure in turn, passing the
+ * result into the next closure. The ordering is that of the iterator()
+ * method on the collection.
+ *
+ * @param closures a collection of closures to chain
+ * @return the chained
closure
+ * @throws IllegalArgumentException if the closures collection is null
+ * @throws IllegalArgumentException if any closure in the collection is null
+ */
+ public static Closure getInstance(Collection closures) {
+ if (closures == null) {
+ throw new IllegalArgumentException("Closure collection must not be null");
+ }
+ if (closures.size() == 0) {
+ return NOPClosure.INSTANCE;
+ }
+ // convert to array like this to guarantee iterator() ordering
+ Closure[] cmds = new Closure[closures.size()];
+ int i = 0;
+ for (Iterator it = closures.iterator(); it.hasNext();) {
+ cmds[i++] = (Closure) it.next();
+ }
+ FunctorUtils.validate(cmds);
+ return new ChainedClosure(cmds);
+ }
+
+ /**
+ * Factory method that performs validation.
+ *
+ * @param closure1 the first closure, not null
+ * @param closure2 the second closure, not null
+ * @return the chained
closure
+ * @throws IllegalArgumentException if either closure is null
+ */
+ public static Closure getInstance(Closure closure1, Closure closure2) {
+ if (closure1 == null || closure2 == null) {
+ throw new IllegalArgumentException("Closures must not be null");
+ }
+ Closure[] closures = new Closure[] { closure1, closure2 };
+ return new ChainedClosure(closures);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param closures the closures to chain, not copied, no nulls
+ */
+ public ChainedClosure(Closure[] closures) {
+ super();
+ iClosures = closures;
+ }
+
+ /**
+ * Execute a list of closures.
+ *
+ * @param input the input object passed to each closure
+ */
+ public void execute(Object input) {
+ for (int i = 0; i < iClosures.length; i++) {
+ iClosures[i].execute(input);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/ExceptionClosure.java b/src/java/org/apache/commons/collections/functors/ExceptionClosure.java
new file mode 100644
index 000000000..ec5e00e84
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/ExceptionClosure.java
@@ -0,0 +1,95 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/ExceptionClosure.java,v 1.1 2003/11/23 17:01:35 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * A null closure or zero count returns the NOPClosure
.
+ * A count of one returns the specified closure.
+ *
+ * @param count the number of times to execute the closure
+ * @param closure the closure to execute, not null
+ * @return the for
closure
+ */
+ public static Closure getInstance(int count, Closure closure) {
+ if (count <= 0 || closure == null) {
+ return NOPClosure.INSTANCE;
+ }
+ if (count == 1) {
+ return closure;
+ }
+ return new ForClosure(count, closure);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param count the number of times to execute the closure
+ * @param closure the closure to execute, not null
+ */
+ public ForClosure(int count, Closure closure) {
+ super();
+ iCount = count;
+ iClosure = closure;
+ }
+
+ /**
+ * Execute the closure count times.
+ */
+ public void execute(Object input) {
+ for (int i = 0; i < iCount; i++) {
+ iClosure.execute(input);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/FunctorUtils.java b/src/java/org/apache/commons/collections/functors/FunctorUtils.java
new file mode 100644
index 000000000..93ac52836
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/FunctorUtils.java
@@ -0,0 +1,133 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/FunctorUtils.java,v 1.1 2003/11/23 17:01:35 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * chained
closure
+ * @throws IllegalArgumentException if array is null
+ * @throws IllegalArgumentException if any element in the array is null
+ */
+ public static Closure getInstance(Predicate predicate, Closure trueClosure, Closure falseClosure) {
+ if (predicate == null) {
+ throw new IllegalArgumentException("Predicate must not be null");
+ }
+ if (trueClosure == null || falseClosure == null) {
+ throw new IllegalArgumentException("Closures must not be null");
+ }
+ return new IfClosure(predicate, trueClosure, falseClosure);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param predicate predicate to switch on, not null
+ * @param trueClosure closure used if true, not null
+ * @param falseClosure closure used if false, not null
+ */
+ public IfClosure(Predicate predicate, Closure trueClosure, Closure falseClosure) {
+ super();
+ iPredicate = predicate;
+ iTrueClosure = trueClosure;
+ iFalseClosure = falseClosure;
+ }
+
+ /**
+ * Execute the correct closure.
+ */
+ public void execute(Object input) {
+ if (iPredicate.evaluate(input) == true) {
+ iTrueClosure.execute(input);
+ } else {
+ iFalseClosure.execute(input);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/NOPClosure.java b/src/java/org/apache/commons/collections/functors/NOPClosure.java
new file mode 100644
index 000000000..953a238ec
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/NOPClosure.java
@@ -0,0 +1,94 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/NOPClosure.java,v 1.1 2003/11/23 17:01:35 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * chained
closure
+ * @throws IllegalArgumentException if array is null
+ * @throws IllegalArgumentException if any element in the array is null
+ */
+ public static Closure getInstance(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
+ FunctorUtils.validate(predicates);
+ FunctorUtils.validate(closures);
+ if (predicates.length != closures.length) {
+ throw new IllegalArgumentException("The predicate and closure arrays must be the same size");
+ }
+ if (predicates.length == 0) {
+ return (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
+ }
+ predicates = FunctorUtils.copy(predicates);
+ closures = FunctorUtils.copy(closures);
+ return new SwitchClosure(predicates, closures, defaultClosure);
+ }
+
+ /**
+ * Create a new Closure that calls one of the closures depending
+ * on the predicates.
+ *
+ * The Map consists of Predicate keys and Closure values. A closure
+ * is called if its matching predicate returns true. Each predicate is evaluated
+ * until one returns true. If no predicates evaluate to true, the default
+ * closure is called. The default closure is set in the map with a
+ * null key. The ordering is that of the iterator() method on the entryset
+ * collection of the map.
+ *
+ * @param predicatesAndClosures a map of predicates to closures
+ * @return the switch
closure
+ * @throws IllegalArgumentException if the map is null
+ * @throws IllegalArgumentException if any closure in the map is null
+ * @throws ClassCastException if the map elements are of the wrong type
+ */
+ public static Closure getInstance(Map predicatesAndClosures) {
+ Closure[] closures = null;
+ Predicate[] preds = null;
+ if (predicatesAndClosures == null) {
+ throw new IllegalArgumentException("The predicate and closure map must not be null");
+ }
+ if (predicatesAndClosures.size() == 0) {
+ return NOPClosure.INSTANCE;
+ }
+ // convert to array like this to guarantee iterator() ordering
+ Closure defaultClosure = (Closure) predicatesAndClosures.remove(null);
+ int size = predicatesAndClosures.size();
+ if (size == 0) {
+ return (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
+ }
+ closures = new Closure[size];
+ preds = new Predicate[size];
+ int i = 0;
+ for (Iterator it = predicatesAndClosures.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Map.Entry) it.next();
+ preds[i] = (Predicate) entry.getKey();
+ closures[i] = (Closure) entry.getValue();
+ i++;
+ }
+ return new SwitchClosure(preds, closures, defaultClosure);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param predicates array of predicates, not cloned, no nulls
+ * @param closures matching array of closures, not cloned, no nulls
+ * @param defaultClosure the closure to use if no match, null means nop
+ */
+ public SwitchClosure(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
+ super();
+ iPredicates = predicates;
+ iClosures = closures;
+ iDefault = (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
+ }
+
+ /**
+ * Execute the closure whose predicate returns true
+ */
+ public void execute(Object input) {
+ for (int i = 0; i < iPredicates.length; i++) {
+ if (iPredicates[i].evaluate(input) == true) {
+ iClosures[i].execute(input);
+ return;
+ }
+ }
+ iDefault.execute(input);
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/TransformerClosure.java b/src/java/org/apache/commons/collections/functors/TransformerClosure.java
new file mode 100644
index 000000000..59952f107
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/TransformerClosure.java
@@ -0,0 +1,115 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/TransformerClosure.java,v 1.1 2003/11/23 17:01:35 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * A null transformer will return the NOPClosure
.
+ *
+ * @param transformer the transformer to call, null means nop
+ * @return the transformer
closure
+ */
+ public static Closure getInstance(Transformer transformer) {
+ if (transformer == null) {
+ return NOPClosure.INSTANCE;
+ }
+ return new TransformerClosure(transformer);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param transformer the transformer to call, not null
+ */
+ public TransformerClosure(Transformer transformer) {
+ super();
+ iTransformer = transformer;
+ }
+
+ /**
+ * Call the transformer.
+ */
+ public void execute(Object input) {
+ iTransformer.transform(input);
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/WhileClosure.java b/src/java/org/apache/commons/collections/functors/WhileClosure.java
new file mode 100644
index 000000000..3fc9e9010
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/WhileClosure.java
@@ -0,0 +1,133 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/WhileClosure.java,v 1.1 2003/11/23 17:01:35 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * while
closure
+ * @throws IllegalArgumentException if the predicate or closure is null
+ */
+ public static Closure getInstance(Predicate predicate, Closure closure, boolean doLoop) {
+ if (predicate == null) {
+ throw new IllegalArgumentException("Predicate must not be null");
+ }
+ if (closure == null) {
+ throw new IllegalArgumentException("Closure must not be null");
+ }
+ return new WhileClosure(predicate, closure, doLoop);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param predicate the predicate used to evaluate when the loop terminates, not null
+ * @param closure the closure the execute, not null
+ * @param doLoop true to act as a do-while loop, always executing the closure once
+ */
+ public WhileClosure(Predicate predicate, Closure closure, boolean doLoop) {
+ super();
+ iPredicate = predicate;
+ iClosure = closure;
+ iDoLoop = doLoop;
+ }
+
+ /**
+ * Execute the closure until the predicate is false.
+ */
+ public void execute(Object input) {
+ if (iDoLoop) {
+ iClosure.execute(input);
+ }
+ while (iPredicate.evaluate(input)) {
+ iClosure.execute(input);
+ }
+ }
+
+}
+
diff --git a/src/test/org/apache/commons/collections/TestClosureUtils.java b/src/test/org/apache/commons/collections/TestClosureUtils.java
index 6a8c9666d..c7c5657f8 100644
--- a/src/test/org/apache/commons/collections/TestClosureUtils.java
+++ b/src/test/org/apache/commons/collections/TestClosureUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestClosureUtils.java,v 1.4 2003/11/23 14:41:27 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestClosureUtils.java,v 1.5 2003/11/23 17:01:36 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -68,12 +68,13 @@ import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.apache.commons.collections.functors.FunctorException;
+import org.apache.commons.collections.functors.NOPClosure;
/**
* Tests the org.apache.commons.collections.ClosureUtils class.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.4 $ $Date: 2003/11/23 14:41:27 $
+ * @version $Revision: 1.5 $ $Date: 2003/11/23 17:01:36 $
*
* @author Stephen Colebourne
*/
@@ -174,12 +175,11 @@ public class TestClosureUtils extends junit.framework.TestCase {
MockClosure cmd = new MockClosure();
ClosureUtils.forClosure(5, cmd).execute(null);
assertEquals(5, cmd.count);
- try {
- ClosureUtils.forClosure(-1, new MockClosure());
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(0, new MockClosure()));
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(-1, new MockClosure()));
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(1, null));
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.forClosure(3, null));
+ assertSame(cmd, ClosureUtils.forClosure(1, cmd));
}
// whileClosure
@@ -237,72 +237,33 @@ public class TestClosureUtils extends junit.framework.TestCase {
ClosureUtils.chainedClosure(coll).execute(null);
assertEquals(1, a.count);
assertEquals(2, b.count);
- }
-
- public void testChainedClosureEx1a() {
+
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.chainedClosure(new Closure[0]));
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.chainedClosure(Collections.EMPTY_LIST));
+
try {
ClosureUtils.chainedClosure(null, null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testChainedClosureEx1b() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.chainedClosure((Closure[]) null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testChainedClosureEx1c() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.chainedClosure((Collection) null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testChainedClosureEx2() {
- try {
- ClosureUtils.chainedClosure(new Closure[0]);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testChainedClosureEx3() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.chainedClosure(new Closure[] {null, null});
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testChainedClosureEx4() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
- ClosureUtils.chainedClosure(Collections.EMPTY_LIST);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testChainedClosureEx5() {
- try {
- Collection coll = new ArrayList();
+ coll = new ArrayList();
coll.add(null);
coll.add(null);
ClosureUtils.chainedClosure(coll);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
+ fail();
+ } catch (IllegalArgumentException ex) {}
}
// switchClosure
@@ -311,13 +272,13 @@ public class TestClosureUtils extends junit.framework.TestCase {
public void testSwitchClosure() {
MockClosure a = new MockClosure();
MockClosure b = new MockClosure();
- ClosureUtils.switchClosure(PredicateUtils.truePredicate(), a, b).execute(null);
+ ClosureUtils.ifClosure(PredicateUtils.truePredicate(), a, b).execute(null);
assertEquals(1, a.count);
assertEquals(0, b.count);
a = new MockClosure();
b = new MockClosure();
- ClosureUtils.switchClosure(PredicateUtils.falsePredicate(), a, b).execute(null);
+ ClosureUtils.ifClosure(PredicateUtils.falsePredicate(), a, b).execute(null);
assertEquals(0, a.count);
assertEquals(1, b.count);
@@ -376,81 +337,33 @@ public class TestClosureUtils extends junit.framework.TestCase {
assertEquals(0, a.count);
assertEquals(0, b.count);
assertEquals(1, c.count);
- }
+
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.switchClosure(new Predicate[0], new Closure[0]));
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.switchClosure(new HashMap()));
+ map = new HashMap();
+ map.put(null, null);
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.switchClosure(map));
- public void testSwitchClosureEx1a() {
try {
ClosureUtils.switchClosure(null, null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx1b() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.switchClosure((Predicate[]) null, (Closure[]) null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx1c() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.switchClosure((Map) null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx2() {
- try {
- ClosureUtils.switchClosure(new Predicate[0], new Closure[0]);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx3() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.switchClosure(new Predicate[2], new Closure[2]);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx4() {
- try {
- ClosureUtils.switchClosure(new HashMap());
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx5() {
- try {
- Map map = new HashMap();
- map.put(null, null);
- map.put(null, null);
- ClosureUtils.switchClosure(map);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchClosureEx6() {
+ fail();
+ } catch (IllegalArgumentException ex) {}
try {
ClosureUtils.switchClosure(new Predicate[2], new Closure[1]);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
+ fail();
+ } catch (IllegalArgumentException ex) {}
}
// switchMapClosure
@@ -486,24 +399,13 @@ public class TestClosureUtils extends junit.framework.TestCase {
assertEquals(0, a.count);
assertEquals(0, b.count);
assertEquals(1, c.count);
- }
- public void testSwitchMapClosureEx1() {
+ assertSame(NOPClosure.INSTANCE, ClosureUtils.switchMapClosure(new HashMap()));
+
try {
ClosureUtils.switchMapClosure(null);
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
- }
-
- public void testSwitchMapClosureEx2() {
- try {
- ClosureUtils.switchMapClosure(new HashMap());
- } catch (IllegalArgumentException ex) {
- return;
- }
- fail();
+ fail();
+ } catch (IllegalArgumentException ex) {}
}