1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.collections15.functors.closure;
17
18
19 import net.sf.collections15.Closure;
20
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.List;
25
26 /***
27 * <code>Closure</code> implementation that chains the specified
28 * <code>Closure</code>s together.
29 *
30 * @author Chris Lambrou
31 * @since Collections15 1.0
32 */
33 public class ChainedClosure <E> implements Closure<E>, Serializable
34 {
35
36 static final long serialVersionUID = 8990943394014635386L;
37
38 /***
39 * The chain of <code>Closure</code>s.
40 */
41 private final List<Closure<? super E>> closures;
42
43 /***
44 * Constructs a new <code>ChainedClosure</code> that chains the
45 * <code>Closure</code>s specified in a collection.
46 *
47 * @param closures The <code>Closure</code>s to be chained together. Cannot
48 * be <code>null</code>, but may be empty.
49 * <p/>
50 * The chained <code>Closure</code>'s {@link #execute}
51 * method will execute the <code>Closure</code>s in the
52 * order specified by this collection's iterator. Note that
53 * the <code>Closure</code>s are copied from this
54 * collection, so sub-sequent modifications to the
55 * collection will not affect the execution order of the new
56 * <code>ChainedClosure</code>.
57 *
58 * @throws IllegalArgumentException Thrown if the collection, or any of its
59 * elements are <code>null</code>.
60 */
61 private ChainedClosure(Collection<Closure<? super E>> closures)
62 {
63 if (closures == null) {
64 throw new IllegalArgumentException("null closures collection");
65 }
66 this.closures = new ArrayList<Closure<? super E>>(closures.size());
67 for (Closure<? super E> closure : closures) {
68 if (closure == null) {
69 throw new IllegalArgumentException("null closure found in closure collection");
70 }
71 this.closures.add(closure);
72 }
73 }
74
75 /***
76 * Returns a new <code>Closure</code> that chains the <code>Closure</code>s
77 * specified in a collection.
78 *
79 * @param closures The <code>Closure</code>s to be chained together. Cannot
80 * be <code>null</code>, but may be empty.
81 * <p/>
82 * The <code>Closure</code>'s {@link #execute} method will
83 * execute the <code>Closure</code>s in the order specified
84 * by this collection's iterator. Note that the
85 * <code>Closure</code>s are copied from this collection, so
86 * sub-sequent modifications to the collection will not
87 * affect the execution order of the new chained
88 * <code>Closure</code>.
89 *
90 * @throws IllegalArgumentException Thrown if the collection, or any of its
91 * elements are <code>null</code>.
92 */
93 public static <T> ChainedClosure<T> getInstance(Collection<Closure<? super T>> closures)
94 {
95 return new ChainedClosure<T>(closures);
96 }
97
98 /***
99 * Execute the <code>Closure</code>s in the chain.
100 *
101 * @param input The input object passed to each <code>Closure</code> in the
102 * chain.
103 */
104 public void execute(E input)
105 {
106 for (Closure<? super E> closure : closures) {
107 closure.execute(input);
108 }
109 }
110 }