View Javadoc

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 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 }