List of usage examples for org.springframework.statemachine.transition TransitionKind INTERNAL
TransitionKind INTERNAL
To view the source code for org.springframework.statemachine.transition TransitionKind INTERNAL.
Click Source Link
From source file:demo.web.StateMachineController.java
@PostConstruct public void setup() { stateMachine.addStateListener(new StateMachineListenerAdapter<States, Events>() { @Override//from w ww. java2s . c o m public void stateEntered(State<States, Events> state) { StateMachineMessage message = new StateMachineMessage(); message.setMessage("Enter state " + state.getId().toString()); simpMessagingTemplate.convertAndSend("/topic/sm.message", message); } @Override public void stateExited(State<States, Events> state) { StateMachineMessage message = new StateMachineMessage(); message.setMessage("Exit state " + state.getId().toString()); simpMessagingTemplate.convertAndSend("/topic/sm.message", message); } @Override public void stateChanged(State<States, Events> from, State<States, Events> to) { Map<Object, Object> variables = stateMachine.getExtendedState().getVariables(); ArrayList<StateMachineEvent> list = new ArrayList<StateMachineEvent>(); for (States state : stateMachine.getState().getIds()) { list.add(new StateMachineEvent(state.toString())); } simpMessagingTemplate.convertAndSend("/topic/sm.states", list); simpMessagingTemplate.convertAndSend("/topic/sm.variables", variables); } @Override public void transitionEnded(Transition<States, Events> transition) { if (transition != null && transition.getKind() == TransitionKind.INTERNAL) { Map<Object, Object> variables = stateMachine.getExtendedState().getVariables(); simpMessagingTemplate.convertAndSend("/topic/sm.variables", variables); } } @Override public void stateMachineError(StateMachine<States, Events> stateMachine, Exception exception) { handleStateMachineError(new StateMachineException("Received error from machine", exception)); } }); stateMachineEnsemble.addEnsembleListener(new EnsembleListenerAdapter<States, Events>() { @Override public void ensembleLeaderGranted(StateMachine<States, Events> stateMachine) { StateMachineMessage message = new StateMachineMessage(); message.setMessage("Leader granted " + stateMachine.getUuid().toString()); simpMessagingTemplate.convertAndSend("/topic/sm.message", message); } @Override public void ensembleLeaderRevoked(StateMachine<States, Events> stateMachine) { StateMachineMessage message = new StateMachineMessage(); message.setMessage("Leader revoked " + stateMachine.getUuid().toString()); simpMessagingTemplate.convertAndSend("/topic/sm.message", message); } }); }
From source file:org.springframework.statemachine.config.AbstractStateMachineFactory.java
@SuppressWarnings("unchecked") private StateMachine<S, E> buildMachine(Map<Object, StateMachine<S, E>> machineMap, Map<S, State<S, E>> stateMap, Map<S, StateHolder<S, E>> holderMap, Collection<StateData<S, E>> stateDatas, Collection<TransitionData<S, E>> transitionsData, BeanFactory beanFactory, Boolean contextEvents, DefaultExtendedState defaultExtendedState, TransitionsData<S, E> stateMachineTransitions, TaskExecutor taskExecutor, TaskScheduler taskScheduler, String machineId, UUID uuid, StateMachineModel<S, E> stateMachineModel) { State<S, E> state = null; State<S, E> initialState = null; PseudoState<S, E> historyState = null; Action<S, E> initialAction = null; Collection<State<S, E>> states = new ArrayList<State<S, E>>(); // for now loop twice and build states for // non initial/end pseudostates last for (StateData<S, E> stateData : stateDatas) { StateMachine<S, E> stateMachine = machineMap.get(stateData.getState()); if (stateMachine == null) { // get a submachine from state data if we didn't have // it already. stays null if we don't have one. stateMachine = stateData.getSubmachine(); if (stateMachine == null && stateData.getSubmachineFactory() != null) { stateMachine = stateData.getSubmachineFactory().getStateMachine(machineId); }//from w w w .ja v a2s . c o m } state = stateMap.get(stateData.getState()); if (state != null) { states.add(state); if (stateData.isInitial()) { initialState = state; } continue; } if (stateMachine != null) { PseudoState<S, E> pseudoState = null; if (stateData.isInitial()) { pseudoState = new DefaultPseudoState<S, E>(PseudoStateKind.INITIAL); } state = new StateMachineState<S, E>(stateData.getState(), stateMachine, stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), pseudoState); // TODO: below if/else doesn't feel right if (stateDatas.size() > 1 && stateData.isInitial()) { initialState = state; initialAction = stateData.getInitialAction(); } else if (stateDatas.size() == 1) { initialState = state; initialAction = stateData.getInitialAction(); } states.add(state); } else { PseudoState<S, E> pseudoState = null; if (stateData.isInitial()) { pseudoState = new DefaultPseudoState<S, E>(PseudoStateKind.INITIAL); } else if (stateData.isEnd()) { pseudoState = new DefaultPseudoState<S, E>(PseudoStateKind.END); } else if (stateData.getPseudoStateKind() == PseudoStateKind.HISTORY_SHALLOW) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.HISTORY_DEEP) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.JOIN) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.FORK) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.CHOICE) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.JUNCTION) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.ENTRY) { continue; } else if (stateData.getPseudoStateKind() == PseudoStateKind.EXIT) { continue; } state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); if (stateData.isInitial()) { initialState = state; initialAction = stateData.getInitialAction(); } states.add(state); } stateMap.put(stateData.getState(), state); } for (StateData<S, E> stateData : stateDatas) { if (stateData.getPseudoStateKind() == PseudoStateKind.HISTORY_SHALLOW) { State<S, E> defaultState = null; S s = stateData.getState(); Collection<HistoryData<S, E>> historys = stateMachineTransitions.getHistorys(); for (HistoryData<S, E> history : historys) { if (history.getSource().equals(s)) { defaultState = stateMap.get(history.getTarget()); } } StateHolder<S, E> defaultStateHolder = new StateHolder<S, E>(defaultState); StateHolder<S, E> containingStateHolder = new StateHolder<S, E>( stateMap.get(stateData.getParent())); if (containingStateHolder.getState() == null) { holderMap.put((S) stateData.getParent(), containingStateHolder); } PseudoState<S, E> pseudoState = new HistoryPseudoState<S, E>(PseudoStateKind.HISTORY_SHALLOW, defaultStateHolder, containingStateHolder); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); historyState = pseudoState; } else if (stateData.getPseudoStateKind() == PseudoStateKind.HISTORY_DEEP) { State<S, E> defaultState = null; S s = stateData.getState(); Collection<HistoryData<S, E>> historys = stateMachineTransitions.getHistorys(); for (HistoryData<S, E> history : historys) { if (history.getSource().equals(s)) { defaultState = stateMap.get(history.getTarget()); } } StateHolder<S, E> defaultStateHolder = new StateHolder<S, E>(defaultState); StateHolder<S, E> containingStateHolder = new StateHolder<S, E>( stateMap.get(stateData.getParent())); if (containingStateHolder.getState() == null) { holderMap.put((S) stateData.getParent(), containingStateHolder); } PseudoState<S, E> pseudoState = new HistoryPseudoState<S, E>(PseudoStateKind.HISTORY_DEEP, defaultStateHolder, containingStateHolder); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); historyState = pseudoState; } if (stateData.getPseudoStateKind() == PseudoStateKind.CHOICE) { S s = stateData.getState(); List<ChoiceData<S, E>> list = stateMachineTransitions.getChoices().get(s); List<ChoiceStateData<S, E>> choices = new ArrayList<ChoiceStateData<S, E>>(); for (ChoiceData<S, E> c : list) { StateHolder<S, E> holder = new StateHolder<S, E>(stateMap.get(c.getTarget())); if (holder.getState() == null) { holderMap.put(c.getTarget(), holder); } choices.add(new ChoiceStateData<S, E>(holder, c.getGuard())); } PseudoState<S, E> pseudoState = new ChoicePseudoState<S, E>(choices); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); } else if (stateData.getPseudoStateKind() == PseudoStateKind.JUNCTION) { S s = stateData.getState(); List<JunctionData<S, E>> list = stateMachineTransitions.getJunctions().get(s); List<JunctionStateData<S, E>> junctions = new ArrayList<JunctionStateData<S, E>>(); for (JunctionData<S, E> c : list) { StateHolder<S, E> holder = new StateHolder<S, E>(stateMap.get(c.getTarget())); if (holder.getState() == null) { holderMap.put(c.getTarget(), holder); } junctions.add(new JunctionStateData<S, E>(holder, c.getGuard())); } PseudoState<S, E> pseudoState = new JunctionPseudoState<S, E>(junctions); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); } else if (stateData.getPseudoStateKind() == PseudoStateKind.ENTRY) { S s = stateData.getState(); Collection<EntryData<S, E>> entrys = stateMachineTransitions.getEntrys(); for (EntryData<S, E> entry : entrys) { if (s.equals(entry.getSource())) { PseudoState<S, E> pseudoState = new EntryPseudoState<S, E>(stateMap.get(entry.getTarget())); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); break; } } } else if (stateData.getPseudoStateKind() == PseudoStateKind.EXIT) { S s = stateData.getState(); Collection<ExitData<S, E>> exits = stateMachineTransitions.getExits(); for (ExitData<S, E> entry : exits) { if (s.equals(entry.getSource())) { StateHolder<S, E> holder = new StateHolder<S, E>(stateMap.get(entry.getTarget())); if (holder.getState() == null) { holderMap.put(entry.getTarget(), holder); } PseudoState<S, E> pseudoState = new ExitPseudoState<S, E>(holder); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); break; } } } else if (stateData.getPseudoStateKind() == PseudoStateKind.FORK) { S s = stateData.getState(); List<S> list = stateMachineTransitions.getForks().get(s); List<State<S, E>> forks = new ArrayList<State<S, E>>(); for (S fs : list) { forks.add(stateMap.get(fs)); } PseudoState<S, E> pseudoState = new ForkPseudoState<S, E>(forks); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); } else if (stateData.getPseudoStateKind() == PseudoStateKind.JOIN) { S s = stateData.getState(); List<S> list = stateMachineTransitions.getJoins().get(s); List<State<S, E>> joins = new ArrayList<State<S, E>>(); // if join source is a regionstate, get // it's end states from regions if (list.size() == 1) { State<S, E> ss1 = stateMap.get(list.get(0)); if (ss1 instanceof RegionState) { Collection<Region<S, E>> regions = ((RegionState<S, E>) ss1).getRegions(); for (Region<S, E> r : regions) { Collection<State<S, E>> ss2 = r.getStates(); for (State<S, E> ss3 : ss2) { if (ss3.getPseudoState() != null && ss3.getPseudoState().getKind() == PseudoStateKind.END) { joins.add(ss3); continue; } } } } } else { for (S fs : list) { joins.add(stateMap.get(fs)); } } List<JoinStateData<S, E>> joinTargets = new ArrayList<JoinStateData<S, E>>(); Collection<TransitionData<S, E>> transitions = stateMachineTransitions.getTransitions(); for (TransitionData<S, E> tt : transitions) { if (tt.getSource() == s) { StateHolder<S, E> holder = new StateHolder<S, E>(stateMap.get(tt.getTarget())); if (holder.getState() == null) { holderMap.put(tt.getTarget(), holder); } joinTargets.add(new JoinStateData<S, E>(holder, tt.getGuard())); } } JoinPseudoState<S, E> pseudoState = new JoinPseudoState<S, E>(joins, joinTargets); state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(), stateData.getExitActions(), stateData.getStateActions(), pseudoState, stateMachineModel); states.add(state); stateMap.put(stateData.getState(), state); } } Collection<Transition<S, E>> transitions = new ArrayList<Transition<S, E>>(); for (TransitionData<S, E> transitionData : transitionsData) { S source = transitionData.getSource(); S target = transitionData.getTarget(); E event = transitionData.getEvent(); Long period = transitionData.getPeriod(); Integer count = transitionData.getCount(); Trigger<S, E> trigger = null; if (event != null) { trigger = new EventTrigger<S, E>(event); } else if (period != null) { TimerTrigger<S, E> t = new TimerTrigger<S, E>(period, count != null ? count : 0); if (beanFactory != null) { t.setBeanFactory(beanFactory); } if (taskExecutor != null) { t.setTaskExecutor(taskExecutor); } if (taskScheduler != null) { t.setTaskScheduler(taskScheduler); } trigger = t; ((AbstractState<S, E>) stateMap.get(source)).getTriggers().add(trigger); } if (transitionData.getKind() == TransitionKind.EXTERNAL) { // TODO can we do this? if (stateMap.get(source) == null || stateMap.get(target) == null) { continue; } DefaultExternalTransition<S, E> transition = new DefaultExternalTransition<S, E>( stateMap.get(source), stateMap.get(target), transitionData.getActions(), event, transitionData.getGuard(), trigger, transitionData.getSecurityRule()); transitions.add(transition); } else if (transitionData.getKind() == TransitionKind.LOCAL) { // TODO can we do this? if (stateMap.get(source) == null || stateMap.get(target) == null) { continue; } DefaultLocalTransition<S, E> transition = new DefaultLocalTransition<S, E>(stateMap.get(source), stateMap.get(target), transitionData.getActions(), event, transitionData.getGuard(), trigger, transitionData.getSecurityRule()); transitions.add(transition); } else if (transitionData.getKind() == TransitionKind.INTERNAL) { DefaultInternalTransition<S, E> transition = new DefaultInternalTransition<S, E>( stateMap.get(source), transitionData.getActions(), event, transitionData.getGuard(), trigger, transitionData.getSecurityRule()); transitions.add(transition); } } if (stateMachineTransitions.getJoins() != null) { for (Entry<S, List<S>> entry : stateMachineTransitions.getJoins().entrySet()) { if (stateMap.get(entry.getKey()) != null) { List<S> entryList = entry.getValue(); for (S entryState : entryList) { State<S, E> source = stateMap.get(entryState); if (source != null && !source.isOrthogonal()) { State<S, E> target = stateMap.get(entry.getKey()); DefaultExternalTransition<S, E> transition = new DefaultExternalTransition<S, E>(source, target, null, null, null, null, null); transitions.add(transition); } } } } } Transition<S, E> initialTransition = new InitialTransition<S, E>(initialState, initialAction); StateMachine<S, E> machine = buildStateMachineInternal(states, transitions, initialState, initialTransition, null, defaultExtendedState, historyState, contextEvents, beanFactory, taskExecutor, taskScheduler, beanName, machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId(), uuid, stateMachineModel); return machine; }
From source file:org.springframework.statemachine.support.AbstractStateMachine.java
@Override protected void onInit() throws Exception { super.onInit(); Assert.notNull(initialState, "Initial state must be set"); Assert.state(/*from www. ja va2 s .co m*/ initialState.getPseudoState() != null && initialState.getPseudoState().getKind() == PseudoStateKind.INITIAL, "Initial state's pseudostate kind must be INITIAL"); lastState = null; extendedState.setExtendedStateChangeListener(new ExtendedStateChangeListener() { @Override public void changed(Object key, Object value) { notifyExtendedStateChanged(key, value, buildStateContext(Stage.EXTENDED_STATE_CHANGED, null, null, getRelayStateMachine())); } }); // process given transitions for (Transition<S, E> transition : transitions) { Trigger<S, E> trigger = transition.getTrigger(); if (trigger != null) { // we have same triggers with different transitions triggerToTransitionMap.put(trigger, transition); } else { triggerlessTransitions.add(transition); } } for (State<S, E> state : states) { if (state.isSubmachineState()) { StateMachine<S, E> submachine = ((AbstractState<S, E>) state).getSubmachine(); submachine.addStateListener(new StateMachineListenerRelay()); } else if (state.isOrthogonal()) { Collection<Region<S, E>> regions = ((AbstractState<S, E>) state).getRegions(); for (Region<S, E> region : regions) { region.addStateListener(new StateMachineListenerRelay()); } } if (state.getPseudoState() != null && (state.getPseudoState().getKind() == PseudoStateKind.HISTORY_DEEP || state.getPseudoState().getKind() == PseudoStateKind.HISTORY_DEEP)) { history = state.getPseudoState(); } } DefaultStateMachineExecutor<S, E> executor = new DefaultStateMachineExecutor<S, E>(this, getRelayStateMachine(), transitions, triggerToTransitionMap, triggerlessTransitions, initialTransition, initialEvent); if (getBeanFactory() != null) { executor.setBeanFactory(getBeanFactory()); } if (getTaskExecutor() != null) { executor.setTaskExecutor(getTaskExecutor()); } executor.afterPropertiesSet(); executor.setStateMachineExecutorTransit(new StateMachineExecutorTransit<S, E>() { @Override public void transit(Transition<S, E> t, StateContext<S, E> ctx, Message<E> message) { long now = System.currentTimeMillis(); // TODO: fix above stateContext as it's not used notifyTransitionStart( buildStateContext(Stage.TRANSITION_START, message, t, getRelayStateMachine())); notifyTransition(buildStateContext(Stage.TRANSITION, message, t, getRelayStateMachine())); if (t.getTarget().getPseudoState() != null && t.getTarget().getPseudoState().getKind() == PseudoStateKind.JOIN) { exitFromState(t.getSource(), message, t, getRelayStateMachine()); } else { if (t.getKind() == TransitionKind.INITIAL) { switchToState(t.getTarget(), message, t, getRelayStateMachine()); notifyStateMachineStarted( buildStateContext(Stage.STATEMACHINE_START, message, t, getRelayStateMachine())); } else if (t.getKind() != TransitionKind.INTERNAL) { switchToState(t.getTarget(), message, t, getRelayStateMachine()); } } // TODO: looks like events should be called here and anno processing earlier notifyTransitionEnd(buildStateContext(Stage.TRANSITION_END, message, t, getRelayStateMachine())); notifyTransitionMonitor(getRelayStateMachine(), t, System.currentTimeMillis() - now); } }); stateMachineExecutor = executor; for (Transition<S, E> t : getTransitions()) { t.addActionListener(new ActionListener<S, E>() { @Override public void onExecute(StateMachine<S, E> stateMachine, Action<S, E> action, long duration) { notifyActionMonitor(stateMachine, action, duration); } }); } for (State<S, E> s : getStates()) { s.addActionListener(new ActionListener<S, E>() { @Override public void onExecute(StateMachine<S, E> stateMachine, Action<S, E> action, long duration) { notifyActionMonitor(stateMachine, action, duration); } }); } }