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.UnaryProcedure;
25  
26  /**
27   * A {@link UnaryProcedure UnaryProcedure}
28   * that {@link UnaryProcedure#run runs} an ordered
29   * sequence of {@link UnaryProcedure UnaryProcedures}.
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   * @param <A> the argument type.
41   * @version $Revision: 1363382 $ $Date: 2012-07-19 12:23:19 -0300 (Thu, 19 Jul 2012) $
42   */
43  public class UnarySequence<A> implements UnaryProcedure<A>, Serializable {
44  
45      /**
46       * serialVersionUID declaration.
47       */
48      private static final long serialVersionUID = 9194268249717820246L;
49      // attributes
50      // ------------------------------------------------------------------------
51      /**
52       * The data structure to store the procedure sequence.
53       */
54      private final List<UnaryProcedure<? super A>> list = new ArrayList<UnaryProcedure<? super A>>();
55  
56      // constructor
57      // ------------------------------------------------------------------------
58      /**
59       * Create a new UnarySequence.
60       */
61      public UnarySequence() {
62          super();
63      }
64  
65      /**
66       * Create a new UnarySequence instance.
67       *
68       * @param procedures to run sequentially
69       */
70      public UnarySequence(UnaryProcedure<? super A>... procedures) {
71          this();
72          if (procedures != null) {
73              for (UnaryProcedure<? super A> p : procedures) {
74                  then(p);
75              }
76          }
77      }
78  
79      /**
80       * Create a new UnarySequence instance.
81       *
82       * @param procedures to run sequentially
83       */
84      public UnarySequence(Iterable<UnaryProcedure<? super A>> procedures) {
85          this();
86          if (procedures != null) {
87              for (UnaryProcedure<? super A> p : procedures) {
88                  then(p);
89              }
90          }
91      }
92  
93      // modifiers
94      // ------------------------------------------------------------------------
95      /**
96       * Fluently add a UnaryProcedure to the sequence.
97       * @param p UnaryProcedure to add
98       * @return this
99       */
100     public UnarySequence<A> then(UnaryProcedure<? super A> p) {
101         if (p != null) {
102             list.add(p);
103         }
104         return this;
105     }
106 
107     // predicate interface
108     // ------------------------------------------------------------------------
109     /**
110      * {@inheritDoc}
111      */
112     public void run(A obj) {
113         for (Iterator<UnaryProcedure<? super A>> iter = list.iterator(); iter.hasNext();) {
114             iter.next().run(obj);
115         }
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     @Override
122     public boolean equals(Object that) {
123         return that == this || (that instanceof UnarySequence<?> && equals((UnarySequence<?>) that));
124     }
125 
126     /**
127      * Learn whether another UnarySequence is equal to this.
128      * @param that UnarySequence to test
129      * @return boolean
130      */
131     public boolean equals(UnarySequence<?> that) {
132         // by construction, list is never null
133         return null != that && list.equals(that.list);
134     }
135 
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     public int hashCode() {
141         // by construction, list is never null
142         return "UnarySequence".hashCode() ^ list.hashCode();
143     }
144 
145     /**
146      * {@inheritDoc}
147      */
148     @Override
149     public String toString() {
150         return "UnarySequence<" + list + ">";
151     }
152 
153 }