View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.statemachine.transition;
21  
22  import org.apache.mina.statemachine.State;
23  import org.apache.mina.statemachine.StateMachine;
24  import org.apache.mina.statemachine.event.Event;
25  
26  /**
27   * Abstract {@link Transition} implementation. Takes care of matching the
28   * current {@link Event}'s id against the id of the {@link Event} this 
29   * {@link Transition} handles. To handle any {@link Event} the id should be set
30   * to {@link Event#WILDCARD_EVENT_ID}.
31   *
32   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
33   */
34  public abstract class AbstractTransition implements Transition {
35      /** The accepted event ID */
36      private final Object eventId;
37  
38      /** The next state, if any */
39      private final State nextState;
40  
41      /**
42       * Creates a new instance which will loopback to the same {@link State} 
43       * for the specified {@link Event} id.
44       * 
45       * @param eventId the {@link Event} id.
46       */
47      public AbstractTransition(Object eventId) {
48          this(eventId, null);
49      }
50  
51      /**
52       * Creates a new instance with the specified {@link State} as next state 
53       * and for the specified {@link Event} id.
54       * 
55       * @param eventId the {@link Event} id.
56       * @param nextState the next {@link State}.
57       */
58      public AbstractTransition(Object eventId, State nextState) {
59          this.eventId = eventId;
60          this.nextState = nextState;
61      }
62  
63      /**
64       * Creates a new instance with the specified {@link State} as next state 
65       * and for the wild card {@link Event} id.
66       * 
67       * @param nextState the next {@link State}.
68       */
69      public AbstractTransition(State nextState) {
70          this.eventId = Event.WILDCARD_EVENT_ID;
71          this.nextState = nextState;
72      }
73  
74      /**
75       * Creates a new instance with a reflexive {@link State} as next state 
76       * and for the wild card {@link Event} id.
77       */
78      public AbstractTransition() {
79          this.eventId = Event.WILDCARD_EVENT_ID;
80          this.nextState = null;
81      }
82  
83      /**
84       * {@inheritDoc}
85       */
86      @Override
87      public State getNextState() {
88          return nextState;
89      }
90  
91      /**
92       * {@inheritDoc}
93       */
94      @Override
95      public boolean execute(Event event) {
96          if (!eventId.equals(Event.WILDCARD_EVENT_ID) && !eventId.equals(event.getId())) {
97              return false;
98          }
99  
100         return doExecute(event);
101     }
102 
103     /**
104      * Executes this {@link Transition}. This method doesn't have to check
105      * if the {@link Event}'s id matches because {@link #execute(Event)} has
106      * already made sure that that is the case.
107      * 
108      * @param event the current {@link Event}.
109      * @return <tt>true</tt> if the {@link Transition} has been executed 
110      *         successfully and the {@link StateMachine} should move to the 
111      *         next {@link State}. <tt>false</tt> otherwise.
112      */
113     protected abstract boolean doExecute(Event event);
114     
115     @Override
116     public boolean equals(Object o) {
117         if (o == this) {
118             return true;
119         }
120 
121         if (!(o instanceof AbstractTransition)) {
122             return false;
123         }
124         
125         AbstractTransition that = (AbstractTransition) o;
126         
127         if (eventId != null) {
128             if (!eventId.equals( that.eventId )) {
129                 return false;
130             }
131         } else {
132             if (that.eventId != null) {
133                 return false;
134             }
135         }
136         
137         
138         if (nextState != null) {
139             return nextState.equals( that.nextState );
140         } else {
141             return that.nextState == null;
142         }
143     }
144 
145     @Override
146     public int hashCode() {
147         int h = 17;
148         
149         if ( eventId != null) {
150             h = h*37 + eventId.hashCode();
151         }
152         
153         if (nextState != null) {
154             h = h*17 + nextState.hashCode();
155         }
156         
157         return h;
158     }
159 
160     @Override
161     public String toString() {
162         StringBuilder sb = new StringBuilder();
163         
164         sb.append("eventId=").append(eventId);
165         sb.append(",nextState=").append(nextState);
166         
167         return sb.toString();
168     }
169 }