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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.commons.collections.Closure; + +/** + * Closure implementation that chains the specifed closures together. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class ChainedClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = -3520677225766901240L; + + /** The closures to call in turn */ + private final Closure[] iClosures; + + /** + * Factory method that performs validation and copies the parameter array. + * + * @param closures the closures to chain, copied, no nulls + * @return the 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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Closure; + +/** + * Closure implementation that always throws an exception. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public final class ExceptionClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 7179106032121985545L; + + + /** Singleton predicate instance */ + public static final Closure INSTANCE = new ExceptionClosure(); + + /** + * Restricted constructor. + */ + private ExceptionClosure() { + super(); + } + + /** + * Always throw an exception. + */ + public void execute(Object object) { + throw new FunctorException("ExceptionClosure invoked"); + } + +} diff --git a/src/java/org/apache/commons/collections/functors/ExceptionFactory.java b/src/java/org/apache/commons/collections/functors/ExceptionFactory.java new file mode 100644 index 000000000..7ffede890 --- /dev/null +++ b/src/java/org/apache/commons/collections/functors/ExceptionFactory.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/ExceptionFactory.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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Factory; + +/** + * Factory implementation that always throws an exception. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public final class ExceptionFactory implements Factory, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 7179106032121985545L; + + + /** Singleton predicate instance */ + public static final Factory INSTANCE = new ExceptionFactory(); + + /** + * Restricted constructor. + */ + private ExceptionFactory() { + super(); + } + + /** + * Always throw an exception. + */ + public Object create() { + throw new FunctorException("ExceptionFactory invoked"); + } + +} diff --git a/src/java/org/apache/commons/collections/functors/ExceptionPredicate.java b/src/java/org/apache/commons/collections/functors/ExceptionPredicate.java new file mode 100644 index 000000000..be8d1e5fe --- /dev/null +++ b/src/java/org/apache/commons/collections/functors/ExceptionPredicate.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/ExceptionPredicate.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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Predicate; + +/** + * Predicate implementation that always throws an exception. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public final class ExceptionPredicate implements Predicate, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 7179106032121985545L; + + /** Singleton predicate instance */ + public static final Predicate INSTANCE = new ExceptionPredicate(); + + /** + * Restricted constructor. + */ + private ExceptionPredicate() { + super(); + } + + /** + * Always throw an exception + */ + public boolean evaluate(Object object) { + throw new FunctorException("ExceptionPredicate invoked"); + } + +} diff --git a/src/java/org/apache/commons/collections/functors/ExceptionTransformer.java b/src/java/org/apache/commons/collections/functors/ExceptionTransformer.java new file mode 100644 index 000000000..ec1eb9d66 --- /dev/null +++ b/src/java/org/apache/commons/collections/functors/ExceptionTransformer.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/ExceptionTransformer.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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Transformer; + +/** + * Transformer implementation that always throws an exception. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public final class ExceptionTransformer implements Transformer, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 7179106032121985545L; + + + /** Singleton predicate instance */ + public static final Transformer INSTANCE = new ExceptionTransformer(); + + /** + * Restricted constructor. + */ + private ExceptionTransformer() { + super(); + } + + /** + * Always throw an exception. + */ + public Object transform(Object object) { + throw new FunctorException("ExceptionTransformer invoked"); + } + +} diff --git a/src/java/org/apache/commons/collections/functors/ForClosure.java b/src/java/org/apache/commons/collections/functors/ForClosure.java new file mode 100644 index 000000000..f619f232f --- /dev/null +++ b/src/java/org/apache/commons/collections/functors/ForClosure.java @@ -0,0 +1,124 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/ForClosure.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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Closure; + +/** + * Closure implementation that calls another closure n times, like a for loop. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class ForClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = -1190120533393621674L; + + /** The number of times to loop */ + private final int iCount; + /** The closure to call */ + private final Closure iClosure; + + /** + * Factory method that performs validation. + *

+ * 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 + * . + * + */ +package org.apache.commons.collections.functors; + +import org.apache.commons.collections.Closure; +import org.apache.commons.collections.Predicate; + +/** + * Internal utilities for functors. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +class FunctorUtils { + + /** + * Clone the predicates to ensure that the internal reference can't be messed with. + * + * @param predicates the predicates to copy + * @return the cloned predicates + */ + 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 + */ + static void validate(Predicate[] predicates) { + if (predicates == null) { + throw new IllegalArgumentException("The predicate array must not be null"); + } + 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 + */ + 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 + */ + static void validate(Closure[] closures) { + if (closures == null) { + throw new IllegalArgumentException("The closure array must not be null"); + } + 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"); + } + } + } + +} diff --git a/src/java/org/apache/commons/collections/functors/IfClosure.java b/src/java/org/apache/commons/collections/functors/IfClosure.java new file mode 100644 index 000000000..f47b71eb5 --- /dev/null +++ b/src/java/org/apache/commons/collections/functors/IfClosure.java @@ -0,0 +1,132 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/IfClosure.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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Closure; +import org.apache.commons.collections.Predicate; + +/** + * Closure implementation acts as an if statement calling one or other closure + * based on a predicate. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class IfClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 3518477308466486130L; + + /** The test */ + private final Predicate iPredicate; + /** The closure to use if true */ + private final Closure iTrueClosure; + /** The closure to use if false */ + private final Closure iFalseClosure; + + /** + * Factory method that performs validation. + * + * @param predicates array of predicates, cloned, no nulls + * @param closures matching array of closures, cloned, no nulls + * @param defaultClosure the closure to use if no match, null means nop + * @return the 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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Closure; + +/** + * Closure implementation that does nothing. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class NOPClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 3518477308466486130L; + + /** Singleton predicate instance */ + public static final Closure INSTANCE = new NOPClosure(); + + /** + * Constructor + */ + private NOPClosure() { + super(); + } + + /** + * Do nothing + */ + public void execute(Object input) { + // do nothing + } + +} diff --git a/src/java/org/apache/commons/collections/functors/SwitchClosure.java b/src/java/org/apache/commons/collections/functors/SwitchClosure.java new file mode 100644 index 000000000..a77bd0257 --- /dev/null +++ b/src/java/org/apache/commons/collections/functors/SwitchClosure.java @@ -0,0 +1,184 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/SwitchClosure.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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.collections.Closure; +import org.apache.commons.collections.Predicate; + +/** + * Closure implementation calls the closure whose predicate returns true, + * like a switch statement. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class SwitchClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = 3518477308466486130L; + + /** 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; + + /** + * Factory method that performs validation and copies the parameter arrays. + * + * @param predicates array of predicates, cloned, no nulls + * @param closures matching array of closures, cloned, no nulls + * @param defaultClosure the closure to use if no match, null means nop + * @return the 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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Closure; +import org.apache.commons.collections.Transformer; + +/** + * Closure implementation that calls a Transformer using the input object + * and ignore the result. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class TransformerClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = -5194992589193388969L; + + /** The transformer to wrap */ + private final Transformer iTransformer; + + /** + * Factory method that performs validation. + *

+ * 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 + * . + * + */ +package org.apache.commons.collections.functors; + +import java.io.Serializable; + +import org.apache.commons.collections.Closure; +import org.apache.commons.collections.Predicate; + +/** + * Closure implementation that executes a closure repeatedly until a condition is met, + * like a do-while or while loop. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/23 17:01:35 $ + * + * @author Stephen Colebourne + */ +public class WhileClosure implements Closure, Serializable { + + /** Serial version UID */ + static final long serialVersionUID = -3110538116913760108L; + + /** 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; + + /** + * Factory method that performs validation. + * + * @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 + * @return the 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) {} }