Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (C) 2000-2016 Atomikos
*
* This code ("Atomikos TransactionsEssentials"), by itself,
* is being distributed under the
* Apache License, Version 2.0 ("License"), a copy of which may be found at
* http://www.atomikos.com/licenses/apache-license-2.0.txt .
* You may not use this file except in compliance with the License.
*
* While the License grants certain patent license rights,
* those patent license rights only extend to the use of
* Atomikos TransactionsEssentials by itself.
*
* This code (Atomikos TransactionsEssentials) contains certain interfaces
* in package (namespace) com.atomikos.icatch
* (including com.atomikos.icatch.Participant) which, if implemented, may
* infringe one or more patents held by Atomikos.
* It should be appreciated that you may NOT implement such interfaces;
* licensing to implement these interfaces must be obtained separately from Atomikos.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
package com.atomikos.finitestates;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Hashtable;
import com.atomikos.icatch.TxState;
/**
*
*
* Implementation of a finite state machine. The following
* consistency is provided:
*
*
getState returns a snapshot (state may change continuously)
*
FSMPreEnterListeners have the guarantee that getState() returns the same
* value each time during the preEnter notification.
*
FSMEnterListeners have no guarantee that the getState() method will
* return the state that was entered - this state may have changed since.
*
*
*/
public class FSMImp implements FSM
{
private TxState state_ = null;
//the current state
private Hashtable> enterlisteners_ = null;
//the enter listeners
private Hashtable> preenterlisteners_ = null;
//pre enter listeners
private Hashtable> transitionlisteners_ = null;
//transition listeners
private Hashtable> pretransitionlisteners_ = null;
//pretransition listeners
private TransitionTable transitiontable_ = null;
//records the legal transitions
private Object eventsource_ = null;
private Object stateLatch_;
/**
*Constructor.
*
*@param transitiontable The transitiontable with valid
*transitions.
*
*@param initialstate The initial state of the FSM.
*/
public FSMImp ( TransitionTable transitiontable , TxState initialstate )
{
this ( null, transitiontable, initialstate );
eventsource_ = this;
}
/**
*Creates a new instance with a given event source.
*Useful for cases where finite state machine behaviour is modelled
*by delegation to an instance of this class.
*
*@param eventsource The object to be used as source of events.
*@param transitiontable The transitiontable for state changes.
*@param initialstate The initial state of the FSM.
*/
public FSMImp ( Object eventsource, TransitionTable transitiontable,
TxState initialstate )
{
transitiontable_ = transitiontable;
state_ = initialstate;
enterlisteners_ = new Hashtable>();
preenterlisteners_ = new Hashtable>();
transitionlisteners_ = new Hashtable>();
pretransitionlisteners_ = new Hashtable>();
eventsource_ = eventsource;
stateLatch_ = new Object();
}
/**
*Help function for adding enter listeners.
*
*@param listeners One of the listener tables.
*@param lstnr The listener to add.
*@param state The state for which the listener wants to be notified.
*/
protected synchronized void addEnterListener(Hashtable> listeners,
EventListener lstnr,
TxState state)
{
Hashtable lstnrs = ( Hashtable ) listeners.get(state);
if ( lstnrs == null )
lstnrs = new Hashtable();
if ( !lstnrs.containsKey(lstnr) )
lstnrs.put( lstnr , new Object() );
listeners.put( state , lstnrs );
}
/**
*Help function for adding transition listeners.
*
*@param listeners One of the transition listener tables.
*@param lstnr The listener to add.
*@param from The start state of the transition.
*@param to The end state of the transition.
*/
protected synchronized void addTransitionListener(Hashtable listeners,
Object lstnr,
TxState from,
TxState to)
{
Hashtable lstnrs = ( Hashtable ) listeners.get(from);
if (lstnrs == null)
lstnrs = new Hashtable();
Hashtable tolstnrs = (Hashtable ) lstnrs.get(to);
if (tolstnrs == null)
tolstnrs = new Hashtable();
if (!tolstnrs.containsKey(lstnr))
tolstnrs.put(lstnr,new Object());
lstnrs.put(to,tolstnrs);
listeners.put(from,lstnrs);
}
/**
*Notify the enter listeners.
*
*@param listeners One of the enter listener tables.
*@param state The state about to enter (or entered).
*@param pre True iff before entering.
*/
protected void notifyListeners(Hashtable> listeners, TxState state,
boolean pre)
{
Hashtable lstnrs = null;
FSMEnterEvent event = new FSMEnterEvent (eventsource_, state);
synchronized ( this ) {
lstnrs= listeners.get ( state );
if ( lstnrs == null )
return;
//clone to avoid concurrency effects outside synch block
//during iteration hereafter
lstnrs = ( Hashtable ) lstnrs.clone();
}
//notify OUTSIDE SYNCH to minimize deadlocks
Enumeration enumm=lstnrs.keys();
while (enumm.hasMoreElements()) {
EventListener listener=enumm.nextElement();
if ( pre && ( listener instanceof FSMPreEnterListener ))
((FSMPreEnterListener) listener).preEnter (event);
else if (!pre && (listener instanceof FSMEnterListener))
((FSMEnterListener) listener).entered ( event );
}
}
/**
*Notify transition listeners.
*
*@param listeners One of the transition listener tables.
*@param from The initial state.
*@param to The end state.
*@param pre True iff before transition.
*/
protected void notifyListeners ( Hashtable> listeners, TxState from ,
TxState to , boolean pre )
{
FSMTransitionEvent event = new FSMTransitionEvent (eventsource_, from, to );
Hashtable lstnrs = null;
Hashtable tolstnrs = null;
synchronized ( this ) {
lstnrs = ( Hashtable ) listeners.get( from );
if ( lstnrs == null )
return;
tolstnrs = ( Hashtable ) lstnrs.get( to );
if ( tolstnrs == null )
return;
//clone to avoid concurrency effects
//during iteration outside synch block
lstnrs = ( Hashtable ) lstnrs.clone();
tolstnrs = ( Hashtable ) tolstnrs.clone();
}
//iterator outside synch to avoid deadlocks
Enumeration enumm = tolstnrs.keys();
while ( enumm.hasMoreElements() ) {
Object listener = enumm.nextElement();
if ( pre && ( listener instanceof FSMPreTransitionListener )) {
((FSMPreTransitionListener)listener).beforeTransition(event);
}
else if (!pre && (listener instanceof FSMTransitionListener)) {
((FSMTransitionListener) listener).transitionPerformed(event);
}
}
}
/**
*@see com.atomikos.finitestates.FSM
*/
public TxState getState()
{
//Note: this method should NOT be synchronized on the FSM itself, to avoid deadlocks
//in re-entrant 2PC calls!
TxState ret = null;
//don't synch on FSM -> use latch object instead
synchronized ( stateLatch_ ) {
ret = state_;
}
return ret;
}
private void setStateObject ( TxState state )
{
//synchronize on stateLatch ONLY to make sure that getState
//returns the latest (non-cached) value
synchronized ( stateLatch_ ) {
this.state_ = state;
}
}
/**
*@see com.atomikos.finitestates.StateMutable
*/
public void setState(TxState state)
throws IllegalStateException
{
TxState oldstate = null;
synchronized ( this ) {
if (!transitiontable_.legalTransition(state_,state))
throw new IllegalStateException("Transition not allowed: "+
state_ +" to "+state);
oldstate = state_;
notifyListeners(preenterlisteners_ , state , true);
notifyListeners(pretransitionlisteners_ , oldstate , state , true);
setStateObject ( state );
}
//ENTER EVENTS ARE OUTSIDE SYNCH BLOCK TO MINIMIZE DEADLOCKS!!!
notifyListeners(enterlisteners_ , state , false);
notifyListeners(transitionlisteners_ , oldstate, state, false);
}
/**
*@see com.atomikos.finitestates.FSMEnterEventSource
*/
public void addFSMEnterListener(FSMEnterListener lstnr, TxState state)
{
addEnterListener(enterlisteners_ , lstnr , state);
}
/**
*@see com.atomikos.finitestates.FSMPreEnterEventSource
*/
public void addFSMPreEnterListener(FSMPreEnterListener lstnr,
TxState state)
{
addEnterListener(preenterlisteners_ , lstnr , state);
}
/**
*@see com.atomikos.finitestates.FSMTransitionEventSource
*/
public void addFSMTransitionListener(FSMTransitionListener lstnr,
TxState from, TxState to)
{
addTransitionListener ( transitionlisteners_ , lstnr , from , to );
}
/**
*@see com.atomikos.finitestates.FSMPreTransitionEventSource
*/
public void addFSMPreTransitionListener(FSMPreTransitionListener lstnr,
TxState from, TxState to)
{
addTransitionListener( pretransitionlisteners_ , lstnr , from , to );
}
}