1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.functor.core.composite;
18  
19  import java.io.Serializable;
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import org.apache.commons.functor.Procedure;
25  
26  /**
27   * A {@link Procedure Procedure}
28   * that {@link Procedure#run runs} an ordered
29   * sequence of {@link Procedure Procedures}.
30   * When the sequence is empty, this procedure is does
31   * nothing.
32   * <p>
33   * Note that although this class implements
34   * {@link Serializable}, a given instance will
35   * only be truly <code>Serializable</code> if all the
36   * underlying functors are.  Attempts to serialize
37   * an instance whose delegates are not all
38   * <code>Serializable</code> will result in an exception.
39   * </p>
40   * @version $Revision: 1365329 $ $Date: 2012-07-24 19:34:23 -0300 (Tue, 24 Jul 2012) $
41   */
42  public class Sequence implements Procedure, Serializable {
43  
44      /**
45       * serialVersionUID declaration.
46       */
47      private static final long serialVersionUID = 8041703589149547883L;
48      // attributes
49      // ------------------------------------------------------------------------
50      /**
51       * The data structure where storing procedures sequence.
52       */
53      private List<Procedure> list = new ArrayList<Procedure>();
54  
55      // constructor
56      // ------------------------------------------------------------------------
57      /**
58       * Create a new Sequence.
59       */
60      public Sequence() {
61          super();
62      }
63  
64      /**
65       * Create a new Sequence instance.
66       *
67       * @param procedures to run sequentially
68       */
69      public Sequence(Procedure... procedures) {
70          this();
71          if (procedures != null) {
72              for (Procedure p : procedures) {
73                  then(p);
74              }
75          }
76      }
77  
78      /**
79       * Create a new Sequence instance.
80       *
81       * @param procedures to run sequentially
82       */
83      public Sequence(Iterable<Procedure> procedures) {
84          this();
85          if (procedures != null) {
86              for (Procedure p : procedures) {
87                  then(p);
88              }
89          }
90      }
91  
92      // modifiers
93      // ------------------------------------------------------------------------
94      /**
95       * Fluently add a Procedure.
96       * @param p Procedure to add
97       * @return this
98       */
99      public final Sequence then(Procedure p) {
100         if (p != null) {
101             list.add(p);
102         }
103         return this;
104     }
105 
106     // predicate interface
107     // ------------------------------------------------------------------------
108     /**
109      * {@inheritDoc}
110      */
111     public final void run() {
112         for (Iterator<Procedure> iter = list.iterator(); iter.hasNext();) {
113             iter.next().run();
114         }
115     }
116 
117     /**
118      * {@inheritDoc}
119      */
120     @Override
121     public final boolean equals(Object that) {
122         return that == this || (that instanceof Sequence && equals((Sequence) that));
123     }
124 
125     /**
126      * Learn whether a given Sequence is equal to this.
127      * @param that Sequence to test
128      * @return boolean
129      */
130     public boolean equals(Sequence that) {
131         // by construction, list is never null
132         return null != that && list.equals(that.list);
133     }
134 
135     /**
136      * {@inheritDoc}
137      */
138     @Override
139     public int hashCode() {
140         // by construction, list is never null
141         return "Sequence".hashCode() ^ list.hashCode();
142     }
143 
144     /**
145      * {@inheritDoc}
146      */
147     @Override
148     public String toString() {
149         return "Sequence<" + list + ">";
150     }
151 
152 }