001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.rules.closure.support;
017    
018    import java.util.ArrayList;
019    import java.util.Collection;
020    import java.util.Iterator;
021    
022    import org.springframework.rules.closure.Closure;
023    import org.springframework.rules.constraint.Constraint;
024    import org.springframework.rules.closure.ElementGenerator;
025    
026    /**
027     * Convenience utility class which provides a number of algorithms involving
028     * function objects such as closures and constraints.
029     *
030     * @author Keith Donald
031     */
032    public class Algorithms {
033    
034            /** The shared instance. */
035            private static Algorithms INSTANCE = new Algorithms();
036    
037            /**
038             * Load the shared instance
039             *
040             * @param instance
041             */
042            public static void load(Algorithms instance) {
043                    INSTANCE = instance;
044            }
045    
046            /**
047             * Singleton instance accessor
048             *
049             * @return The algorithms instance
050             */
051            public static Algorithms instance() {
052                    return INSTANCE;
053            }
054    
055            /**
056             * Returns true if any elements in the given collection meet the specified
057             * predicate condition.
058             *
059             * @param collection the collection
060             * @param constraint the iterator
061             * @return true or false
062             */
063            public boolean anyTrue(Collection collection, Constraint constraint) {
064                    return anyTrue(collection.iterator(), constraint);
065            }
066    
067            /**
068             * Returns true if any elements in the given collection meet the specified
069             * predicate condition.
070             *
071             * @param it the iterator
072             * @param constraint the constraint
073             * @return true or false
074             */
075            public boolean anyTrue(Iterator it, Constraint constraint) {
076                    return new IteratorTemplate(it).anyTrue(constraint);
077            }
078    
079            /**
080             * Returns true if all elements in the given collection meet the specified
081             * predicate condition.
082             *
083             * @param collection
084             * @param constraint
085             * @return true or false
086             */
087            public boolean allTrue(Collection collection, Constraint constraint) {
088                    return allTrue(collection.iterator(), constraint);
089            }
090    
091            /**
092             * Returns true if all elements in the given collection meet the specified
093             * predicate condition.
094             *
095             * @param it the iterator
096             * @param constraint the constraint
097             * @return true if all true, false otherwise
098             */
099            public boolean allTrue(Iterator it, Constraint constraint) {
100                    return new IteratorTemplate(it).allTrue(constraint);
101            }
102    
103            /**
104             * Find the first element in the collection matching the specified
105             * constraint.
106             *
107             * @param collection the collection
108             * @param constraint the predicate
109             * @return The first object match, or null if no match
110             */
111            public Object findFirst(Collection collection, Constraint constraint) {
112                    return findFirst(collection.iterator(), constraint);
113            }
114    
115            /**
116             * Find the first element in the collection matching the specified
117             * constraint.
118             *
119             * @param it the iterator
120             * @param constraint the predicate
121             * @return The first object match, or null if no match
122             */
123            public Object findFirst(Iterator it, Constraint constraint) {
124                    return new IteratorTemplate(it).findFirst(constraint);
125            }
126    
127            /**
128             * Find all the elements in the collection that match the specified
129             * constraint.
130             *
131             * @param collection
132             * @param constraint
133             * @return The objects that match, or a empty collection if none match
134             */
135            public Collection findAll(Collection collection, Constraint constraint) {
136                    return findAll(collection.iterator(), constraint);
137            }
138    
139            /**
140             * Find all the elements in the collection that match the specified
141             * constraint.
142             *
143             * @param it the iterator
144             * @param constraint the constraint
145             * @return The objects that match, or a empty collection if none match
146             */
147            public Collection findAll(Iterator it, Constraint constraint) {
148                    ElementGenerator finder = new IteratorTemplate(it).findAll(constraint);
149                    final Collection results = new ArrayList();
150                    finder.run(new Block() {
151                            protected void handle(Object element) {
152                                    results.add(element);
153                            }
154                    });
155                    return results;
156            }
157    
158            /**
159             * Execute the provided closure for each element in the collection.
160             *
161             * @param collection the collection
162             * @param closure the callback
163             */
164            public void forEach(Collection collection, Closure closure) {
165                    forEach(collection.iterator(), closure);
166            }
167    
168            /**
169             * Execute the provided closure for each element in the collection.
170             *
171             * @param it the iterator
172             * @param closure the callback
173             */
174            public void forEach(Iterator it, Closure closure) {
175                    new IteratorTemplate(it).run(closure);
176            }
177    }