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 org.apache.commons.functor.Predicate;
20  import org.apache.commons.functor.Procedure;
21  import org.apache.commons.lang3.Validate;
22  
23  import java.io.Serializable;
24  
25  /**
26   * Abstract base class for {@link WhileDoProcedure} and {@link DoWhileProcedure}
27   * used to implement loop procedures.
28   * <p>
29   * @version $Revision: 1365329 $ $Date: 2012-07-24 19:34:23 -0300 (Tue, 24 Jul 2012) $
30   */
31  public abstract class AbstractLoopProcedure implements Procedure, Serializable {
32      /**
33       * serialVersionUID declaration.
34       */
35      private static final long serialVersionUID = -5903381842630236070L;
36  
37      /** Base hash integer used to shift hash. */
38      private static final int HASH_SHIFT = 4;
39  
40      /**
41       * The condition has to be verified that while true,
42       * forces the action repetition.
43       */
44      private final Predicate condition;
45  
46      /**
47       * The action to be repeated until the condition is true.
48       */
49      private final Procedure action;
50  
51      /**
52       * Create a new AbstractLoopProcedure.
53       * @param condition while true, repeat
54       * @param action loop body
55       */
56      protected AbstractLoopProcedure(Predicate condition, Procedure action) {
57          this.condition = Validate.notNull(condition, "Predicate argument must not be null");
58          this.action = Validate.notNull(action, "Predicate argument must not be null");
59      }
60  
61      /**
62       * {@inheritDoc}
63       */
64      @Override
65      public final boolean equals(Object object) {
66          if (object == this) {
67              return true;
68          }
69          if (!(object instanceof AbstractLoopProcedure)) {
70              return false;
71          }
72          AbstractLoopProcedure that = (AbstractLoopProcedure) object;
73          return (getCondition().equals(that.getCondition())
74                  && (getAction().equals(that.getAction())));
75      }
76  
77      /**
78       * {@inheritDoc}
79       */
80      @Override
81      public int hashCode() {
82          return hashCode("AbstractLoopProcedure".hashCode());
83      }
84  
85      /**
86       * {@inheritDoc}
87       */
88      @Override
89      public String toString() {
90          return getClass().getName() + "<" + getCondition() + "," + getAction() + ">";
91      }
92  
93      /**
94       * Create a hashCode by manipulating an input hashCode and factoring in instance state.
95       * @param hash incoming hashCode
96       * @return int
97       */
98      protected int hashCode(int hash) {
99          hash <<= HASH_SHIFT;
100         hash ^= getAction().hashCode();
101         hash <<= HASH_SHIFT;
102         hash ^= getCondition().hashCode();
103         return hash;
104     }
105 
106     /**
107      * Get the condition.
108      * @return Predicate
109      */
110     protected final Predicate getCondition() {
111         return condition;
112     }
113 
114     /**
115      * Get the action.
116      * @return Procedure
117      */
118     protected final Procedure getAction() {
119         return action;
120     }
121 
122 }