001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.statemachine.transition; 021 022import org.apache.mina.statemachine.State; 023import org.apache.mina.statemachine.StateMachine; 024import org.apache.mina.statemachine.event.Event; 025 026/** 027 * Abstract {@link Transition} implementation. Takes care of matching the 028 * current {@link Event}'s id against the id of the {@link Event} this 029 * {@link Transition} handles. To handle any {@link Event} the id should be set 030 * to {@link Event#WILDCARD_EVENT_ID}. 031 * 032 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 033 */ 034public abstract class AbstractTransition implements Transition { 035 private final Object eventId; 036 037 private final State nextState; 038 039 /** 040 * Creates a new instance which will loopback to the same {@link State} 041 * for the specified {@link Event} id. 042 * 043 * @param eventId the {@link Event} id. 044 */ 045 public AbstractTransition(Object eventId) { 046 this(eventId, null); 047 } 048 049 /** 050 * Creates a new instance with the specified {@link State} as next state 051 * and for the specified {@link Event} id. 052 * 053 * @param eventId the {@link Event} id. 054 * @param nextState the next {@link State}. 055 */ 056 public AbstractTransition(Object eventId, State nextState) { 057 this.eventId = eventId; 058 this.nextState = nextState; 059 } 060 061 public State getNextState() { 062 return nextState; 063 } 064 065 public boolean execute(Event event) { 066 if (!eventId.equals(Event.WILDCARD_EVENT_ID) && !eventId.equals(event.getId())) { 067 return false; 068 } 069 070 return doExecute(event); 071 } 072 073 /** 074 * Executes this {@link Transition}. This method doesn't have to check 075 * if the {@link Event}'s id matches because {@link #execute(Event)} has 076 * already made sure that that is the case. 077 * 078 * @param event the current {@link Event}. 079 * @return <tt>true</tt> if the {@link Transition} has been executed 080 * successfully and the {@link StateMachine} should move to the 081 * next {@link State}. <tt>false</tt> otherwise. 082 */ 083 protected abstract boolean doExecute(Event event); 084 085 public boolean equals(Object o) { 086 if (o == this) { 087 return true; 088 } 089 090 if (!(o instanceof AbstractTransition)) { 091 return false; 092 } 093 094 AbstractTransition that = (AbstractTransition) o; 095 096 if (eventId != null) { 097 if (!eventId.equals( that.eventId )) { 098 return false; 099 } 100 } else { 101 if (that.eventId != null) { 102 return false; 103 } 104 } 105 106 107 if (nextState != null) { 108 return nextState.equals( that.nextState ); 109 } else { 110 return that.nextState == null; 111 } 112 } 113 114 public int hashCode() { 115 int h = 17; 116 117 if ( eventId != null) { 118 h = h*37 + eventId.hashCode(); 119 } 120 121 if (nextState != null) { 122 h = h*17 + nextState.hashCode(); 123 } 124 125 return h; 126 } 127 128 public String toString() { 129 StringBuilder sb = new StringBuilder(); 130 131 sb.append("eventId=").append(eventId); 132 sb.append(",nextState=").append(nextState); 133 return sb.toString(); 134 } 135}