List of usage examples for org.springframework.statemachine.state State getIds
Collection<S> getIds();
From source file:org.zrgs.spring.statemachine.AbstractStateMachineCommands.java
@SuppressWarnings("unused") @CliCommand(value = "sm state", help = "Prints current state") public String state() { State<S, E> state = stateMachine.getState(); if (state != null) { return StringUtils.collectionToCommaDelimitedString(state.getIds()); } else {/*from w w w . ja v a 2 s .c o m*/ return "No state"; } }
From source file:org.springframework.statemachine.processor.StateMachineHandlerCallHelper.java
private boolean annotationHandlerSourceTargetMatch(String[] msources, String[] mtargets, Annotation methodAnnotation, State<S, E> sourceState, State<S, E> targetState) { Map<String, Object> annotationAttributes = AnnotationUtils.getAnnotationAttributes(methodAnnotation); Object source = annotationAttributes.get("source"); Object target = annotationAttributes.get("target"); Collection<String> scoll = StateMachineUtils.toStringCollection(source); if (scoll.isEmpty() && msources != null) { scoll = Arrays.asList(msources); }//from w w w . j a va2 s.co m Collection<String> tcoll = StateMachineUtils.toStringCollection(target); if (tcoll.isEmpty() && mtargets != null) { tcoll = Arrays.asList(mtargets); } boolean handle = false; if (!scoll.isEmpty() && !tcoll.isEmpty()) { if (sourceState != null && targetState != null && StateMachineUtils.containsAtleastOne(scoll, StateMachineUtils.toStringCollection(sourceState.getIds())) && StateMachineUtils.containsAtleastOne(tcoll, StateMachineUtils.toStringCollection(targetState.getIds()))) { handle = true; } } else if (!scoll.isEmpty()) { if (sourceState != null && StateMachineUtils.containsAtleastOne(scoll, StateMachineUtils.toStringCollection(sourceState.getIds()))) { handle = true; } } else if (!tcoll.isEmpty()) { if (targetState != null && StateMachineUtils.containsAtleastOne(tcoll, StateMachineUtils.toStringCollection(targetState.getIds()))) { handle = true; } } else if (scoll.isEmpty() && tcoll.isEmpty()) { handle = true; } return handle; }
From source file:org.springframework.statemachine.support.AbstractStateMachine.java
@Override public void resetStateMachine(StateMachineContext<S, E> stateMachineContext) { // TODO: this function needs a serious rewrite if (stateMachineContext == null) { log.info("Got null context, resetting to initial state and clearing extended state"); currentState = initialState;/* w ww . j av a 2 s . c om*/ extendedState.getVariables().clear(); return; } if (log.isDebugEnabled()) { log.debug("Request to reset state machine: stateMachine=[" + this + "] stateMachineContext=[" + stateMachineContext + "]"); } setId(stateMachineContext.getId()); S state = stateMachineContext.getState(); boolean stateSet = false; // handle state reset for (State<S, E> s : getStates()) { for (State<S, E> ss : s.getStates()) { if (state != null && ss.getIds().contains(state)) { currentState = s; // setting lastState here is needed for restore lastState = currentState; // TODO: not sure about starting submachine/regions here, though // needed if we only transit to super state or reset regions if (s.isSubmachineState()) { StateMachine<S, E> submachine = ((AbstractState<S, E>) s).getSubmachine(); for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) { submachine.getStateMachineAccessor() .doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() { @Override public void apply(StateMachineAccess<S, E> function) { function.resetStateMachine(child); } }); } submachine.start(); } else if (s.isOrthogonal() && stateMachineContext.getChilds() != null) { Collection<Region<S, E>> regions = ((AbstractState<S, E>) s).getRegions(); for (Region<S, E> region : regions) { for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) { ((StateMachine<S, E>) region).getStateMachineAccessor() .doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() { @Override public void apply(StateMachineAccess<S, E> function) { function.resetStateMachine(child); } }); } } for (Region<S, E> region : regions) { region.start(); } } if (log.isDebugEnabled()) { log.debug("State reseted: stateMachine=[" + this + "] stateMachineContext=[" + stateMachineContext + "]"); } stateSet = true; break; } else if (!stateMachineContext.getChilds().isEmpty()) { // we're here because root machine only have regions if (s.isOrthogonal()) { Collection<Region<S, E>> regions = ((AbstractState<S, E>) s).getRegions(); for (Region<S, E> region : regions) { for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) { ((StateMachine<S, E>) region).getStateMachineAccessor() .doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() { @Override public void apply(StateMachineAccess<S, E> function) { function.resetStateMachine(child); } }); } } for (Region<S, E> region : regions) { region.start(); } } } } if (stateSet) { break; } } // handle history reset here as above state reset loop breaks out if (history != null && stateMachineContext.getHistoryStates() != null) { // setting history for 'this' machine State<S, E> h = null; for (State<S, E> hh : getStates()) { if (hh.getId().equals(stateMachineContext.getHistoryStates().get(null))) { h = hh; break; } } if (h != null) { ((HistoryPseudoState<S, E>) history).setState(h); } } for (State<S, E> s : getStates()) { // setting history for 'submachines' if (s.isSubmachineState()) { StateMachine<S, E> submachine = ((AbstractState<S, E>) s).getSubmachine(); PseudoState<S, E> submachineHistory = ((AbstractStateMachine<S, E>) submachine).getHistoryState(); if (submachineHistory != null) { State<S, E> h = null; for (State<S, E> hh : submachine.getStates()) { if (hh.getId().equals(stateMachineContext.getHistoryStates().get(s.getId()))) { h = hh; break; } } if (h != null) { ((HistoryPseudoState<S, E>) submachineHistory).setState(h); } } } } if (stateSet && stateMachineContext.getExtendedState() != null) { this.extendedState = stateMachineContext.getExtendedState(); } }
From source file:org.springframework.statemachine.support.AbstractStateMachine.java
protected synchronized boolean acceptEvent(Message<E> message) { if ((currentState != null && currentState.shouldDefer(message))) { log.info("Current state " + currentState + " deferred event " + message); stateMachineExecutor.queueDeferredEvent(message); return true; }//from w w w .ja v a 2s . c om if ((currentState != null && currentState.sendEvent(message))) { return true; } if (log.isDebugEnabled()) { log.debug("Queue event " + message + " " + this); } for (Transition<S, E> transition : transitions) { State<S, E> source = transition.getSource(); Trigger<S, E> trigger = transition.getTrigger(); if (StateMachineUtils.containsAtleastOne(source.getIds(), currentState.getIds())) { if (trigger != null && trigger.evaluate(new DefaultTriggerContext<S, E>(message.getPayload()))) { stateMachineExecutor.queueEvent(message); return true; } } } // if we're about to not accept event, check defer again in case // state was changed between original check and now if ((currentState != null && currentState.shouldDefer(message))) { log.info("Current state " + currentState + " deferred event " + message); stateMachineExecutor.queueDeferredEvent(message); return true; } return false; }
From source file:org.springframework.statemachine.support.DefaultStateMachineExecutor.java
private boolean handleTriggerTrans(List<Transition<S, E>> trans, Message<E> queuedMessage) { boolean transit = false; for (Transition<S, E> t : trans) { if (t == null) { continue; }//from w ww . j a v a 2s.co m State<S, E> source = t.getSource(); if (source == null) { continue; } State<S, E> currentState = stateMachine.getState(); if (currentState == null) { continue; } if (!StateMachineUtils.containsAtleastOne(source.getIds(), currentState.getIds())) { continue; } // special handling of join if (StateMachineUtils.isPseudoState(t.getTarget(), PseudoStateKind.JOIN)) { if (joinSyncStates.isEmpty()) { List<State<S, E>> joins = ((JoinPseudoState<S, E>) t.getTarget().getPseudoState()).getJoins(); joinSyncStates.addAll(joins); } joinSyncTransitions.add(t); boolean removed = joinSyncStates.remove(t.getSource()); boolean joincomplete = removed & joinSyncStates.isEmpty(); if (joincomplete) { for (Transition<S, E> tt : joinSyncTransitions) { StateContext<S, E> stateContext = buildStateContext(queuedMessage, tt, relayStateMachine); tt.transit(stateContext); stateMachineExecutorTransit.transit(tt, stateContext, queuedMessage); } joinSyncTransitions.clear(); break; } else { continue; } } StateContext<S, E> stateContext = buildStateContext(queuedMessage, t, relayStateMachine); try { stateContext = interceptors.preTransition(stateContext); } catch (Exception e) { // currently expect that if exception is // thrown, this transition will not match. // i.e. security may throw AccessDeniedException log.info("Interceptors threw exception", e); stateContext = null; } if (stateContext == null) { break; } try { transit = t.transit(stateContext); } catch (Exception e) { log.warn("Transition " + t + " caused error " + e); } if (transit) { stateMachineExecutorTransit.transit(t, stateContext, queuedMessage); interceptors.postTransition(stateContext); break; } } return transit; }
From source file:org.springframework.statemachine.support.DefaultStateMachineExecutor.java
private boolean processEventQueue() { if (log.isDebugEnabled()) { log.debug("Process event queue, size=" + eventQueue.size()); }/*from w ww .ja v a 2 s .co m*/ Message<E> queuedEvent = eventQueue.poll(); State<S, E> currentState = stateMachine.getState(); if (queuedEvent != null) { if ((currentState != null && currentState.shouldDefer(queuedEvent))) { log.info("Current state " + currentState + " deferred event " + queuedEvent); queueDeferredEvent(queuedEvent); return true; } for (Transition<S, E> transition : transitions) { State<S, E> source = transition.getSource(); Trigger<S, E> trigger = transition.getTrigger(); if (StateMachineUtils.containsAtleastOne(source.getIds(), currentState.getIds())) { if (trigger != null && trigger.evaluate(new DefaultTriggerContext<S, E>(queuedEvent.getPayload()))) { queueTrigger(trigger, queuedEvent); return true; } } } } return false; }
From source file:org.springframework.statemachine.support.DefaultStateMachineExecutor.java
private void processTriggerQueue() { if (!isRunning()) { return;//from w w w. j a v a 2s.c o m } if (!initialHandled.getAndSet(true)) { ArrayList<Transition<S, E>> trans = new ArrayList<Transition<S, E>>(); trans.add(initialTransition); // TODO: should we merge if initial event is actually used? if (initialEvent != null) { handleInitialTrans(initialTransition, initialEvent); } else { handleInitialTrans(initialTransition, forwardedInitialEvent); } return; } if (log.isDebugEnabled()) { log.debug("Process trigger queue, size=" + triggerQueue.size() + " " + this); } TriggerQueueItem queueItem = triggerQueue.poll(); // keep message here so that we can // pass it to triggerless transitions State<S, E> currentState = stateMachine.getState(); if (queueItem != null && currentState != null) { if (log.isDebugEnabled()) { log.debug("Process trigger item " + queueItem + " " + this); } // queued message is kept on a class level order to let // triggerless transition to receive this message if it doesn't // kick in in this poll loop. queuedMessage = queueItem.message; E event = queuedMessage != null ? queuedMessage.getPayload() : null; // need all transitions trigger could match, event trigger may match // multiple // need to go up from substates and ask if trigger transit, if not // check super ArrayList<Transition<S, E>> trans = new ArrayList<Transition<S, E>>(); if (event != null) { ArrayList<S> ids = new ArrayList<S>(currentState.getIds()); Collections.reverse(ids); for (S id : ids) { for (Entry<Trigger<S, E>, Transition<S, E>> e : triggerToTransitionMap.entrySet()) { Trigger<S, E> tri = e.getKey(); E ee = tri.getEvent(); Transition<S, E> tra = e.getValue(); if (event.equals(ee)) { if (tra.getSource().getId().equals(id) && !trans.contains(tra)) { trans.add(tra); continue; } } } } } // most likely timer if (trans.isEmpty()) { trans.add(triggerToTransitionMap.get(queueItem.trigger)); } // go through candidates and transit max one handleTriggerTrans(trans, queuedMessage); } if (stateMachine.getState() != null) { // loop triggerless transitions here so that // all "chained" transitions will get queue message boolean transit = false; do { transit = handleTriggerTrans(triggerlessTransitions, queuedMessage); } while (transit); } }