KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > functors > SwitchClosure


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.collections.functors;
17
18 import java.io.Serializable JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.commons.collections.Closure;
23 import org.apache.commons.collections.Predicate;
24
25 /**
26  * Closure implementation calls the closure whose predicate returns true,
27  * like a switch statement.
28  *
29  * @since Commons Collections 3.0
30  * @version $Revision: 1.5 $ $Date: 2004/05/16 11:47:38 $
31  *
32  * @author Stephen Colebourne
33  */

34 public class SwitchClosure implements Closure, Serializable JavaDoc {
35
36     /** Serial version UID */
37     static final long serialVersionUID = 3518477308466486130L;
38
39     /** The tests to consider */
40     private final Predicate[] iPredicates;
41     /** The matching closures to call */
42     private final Closure[] iClosures;
43     /** The default closure to call if no tests match */
44     private final Closure iDefault;
45
46     /**
47      * Factory method that performs validation and copies the parameter arrays.
48      *
49      * @param predicates array of predicates, cloned, no nulls
50      * @param closures matching array of closures, cloned, no nulls
51      * @param defaultClosure the closure to use if no match, null means nop
52      * @return the <code>chained</code> closure
53      * @throws IllegalArgumentException if array is null
54      * @throws IllegalArgumentException if any element in the array is null
55      */

56     public static Closure getInstance(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
57         FunctorUtils.validate(predicates);
58         FunctorUtils.validate(closures);
59         if (predicates.length != closures.length) {
60             throw new IllegalArgumentException JavaDoc("The predicate and closure arrays must be the same size");
61         }
62         if (predicates.length == 0) {
63             return (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
64         }
65         predicates = FunctorUtils.copy(predicates);
66         closures = FunctorUtils.copy(closures);
67         return new SwitchClosure(predicates, closures, defaultClosure);
68     }
69
70     /**
71      * Create a new Closure that calls one of the closures depending
72      * on the predicates.
73      * <p>
74      * The Map consists of Predicate keys and Closure values. A closure
75      * is called if its matching predicate returns true. Each predicate is evaluated
76      * until one returns true. If no predicates evaluate to true, the default
77      * closure is called. The default closure is set in the map with a
78      * null key. The ordering is that of the iterator() method on the entryset
79      * collection of the map.
80      *
81      * @param predicatesAndClosures a map of predicates to closures
82      * @return the <code>switch</code> closure
83      * @throws IllegalArgumentException if the map is null
84      * @throws IllegalArgumentException if any closure in the map is null
85      * @throws ClassCastException if the map elements are of the wrong type
86      */

87     public static Closure getInstance(Map JavaDoc predicatesAndClosures) {
88         Closure[] closures = null;
89         Predicate[] preds = null;
90         if (predicatesAndClosures == null) {
91             throw new IllegalArgumentException JavaDoc("The predicate and closure map must not be null");
92         }
93         if (predicatesAndClosures.size() == 0) {
94             return NOPClosure.INSTANCE;
95         }
96         // convert to array like this to guarantee iterator() ordering
97
Closure defaultClosure = (Closure) predicatesAndClosures.remove(null);
98         int size = predicatesAndClosures.size();
99         if (size == 0) {
100             return (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
101         }
102         closures = new Closure[size];
103         preds = new Predicate[size];
104         int i = 0;
105         for (Iterator JavaDoc it = predicatesAndClosures.entrySet().iterator(); it.hasNext();) {
106             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
107             preds[i] = (Predicate) entry.getKey();
108             closures[i] = (Closure) entry.getValue();
109             i++;
110         }
111         return new SwitchClosure(preds, closures, defaultClosure);
112     }
113     
114     /**
115      * Constructor that performs no validation.
116      * Use <code>getInstance</code> if you want that.
117      *
118      * @param predicates array of predicates, not cloned, no nulls
119      * @param closures matching array of closures, not cloned, no nulls
120      * @param defaultClosure the closure to use if no match, null means nop
121      */

122     public SwitchClosure(Predicate[] predicates, Closure[] closures, Closure defaultClosure) {
123         super();
124         iPredicates = predicates;
125         iClosures = closures;
126         iDefault = (defaultClosure == null ? NOPClosure.INSTANCE : defaultClosure);
127     }
128
129     /**
130      * Executes the closure whose matching predicate returns true
131      *
132      * @param input the input object
133      */

134     public void execute(Object JavaDoc input) {
135         for (int i = 0; i < iPredicates.length; i++) {
136             if (iPredicates[i].evaluate(input) == true) {
137                 iClosures[i].execute(input);
138                 return;
139             }
140         }
141         iDefault.execute(input);
142     }
143
144     /**
145      * Gets the predicates, do not modify the array.
146      *
147      * @return the predicates
148      * @since Commons Collections 3.1
149      */

150     public Predicate[] getPredicates() {
151         return iPredicates;
152     }
153
154     /**
155      * Gets the closures, do not modify the array.
156      *
157      * @return the closures
158      * @since Commons Collections 3.1
159      */

160     public Closure[] getClosures() {
161         return iClosures;
162     }
163
164     /**
165      * Gets the default closure.
166      *
167      * @return the default closure
168      * @since Commons Collections 3.1
169      */

170     public Closure getDefaultClosure() {
171         return iDefault;
172     }
173     
174 }
175
Popular Tags