List of usage examples for org.springframework.statemachine StateMachine getStateMachineAccessor
StateMachineAccessor<S, E> getStateMachineAccessor();
From source file:org.springframework.statemachine.config.AbstractStateMachineFactory.java
/** * Main constructor that create a {@link StateMachine}. * * @param uuid for internal usage. Can be null, in that case a random one will be generated. * @param machineId represent a user Id, up to you to set what you want. * @return a {@link StateMachine}/* w w w.j a va 2s . c o m*/ */ @SuppressWarnings("unchecked") public StateMachine<S, E> getStateMachine(UUID uuid, String machineId) { StateMachineModel<S, E> stateMachineModel = resolveStateMachineModel(machineId); if (stateMachineModel.getConfigurationData().isVerifierEnabled()) { StateMachineModelVerifier<S, E> verifier = stateMachineModel.getConfigurationData().getVerifier(); if (verifier == null) { verifier = new CompositeStateMachineModelVerifier<S, E>(); } verifier.verify(stateMachineModel); } // shared DefaultExtendedState defaultExtendedState = new DefaultExtendedState(); StateMachine<S, E> machine = null; // we store mappings from state id's to states which gets // created during the process. This is needed for transitions to // find a correct mappings because they use state id's, not actual // states. final Map<S, State<S, E>> stateMap = new HashMap<S, State<S, E>>(); Stack<MachineStackItem<S, E>> regionStack = new Stack<MachineStackItem<S, E>>(); Stack<StateData<S, E>> stateStack = new Stack<StateData<S, E>>(); Map<Object, StateMachine<S, E>> machineMap = new HashMap<Object, StateMachine<S, E>>(); Map<S, StateHolder<S, E>> holderMap = new HashMap<S, StateHolder<S, E>>(); Iterator<Node<StateData<S, E>>> iterator = buildStateDataIterator(stateMachineModel); while (iterator.hasNext()) { Node<StateData<S, E>> node = iterator.next(); StateData<S, E> stateData = node.getData(); StateData<S, E> peek = stateStack.isEmpty() ? null : stateStack.peek(); // simply push and continue if (stateStack.isEmpty()) { stateStack.push(stateData); continue; } boolean stackContainsSameParent = false; Iterator<StateData<S, E>> ii = stateStack.iterator(); while (ii.hasNext()) { StateData<S, E> sd = ii.next(); if (stateData != null && ObjectUtils.nullSafeEquals(stateData.getState(), sd.getParent())) { stackContainsSameParent = true; break; } } if (stateData != null && !stackContainsSameParent) { stateStack.push(stateData); continue; } Collection<StateData<S, E>> stateDatas = popSameParents(stateStack); int initialCount = getInitialCount(stateDatas); Collection<Collection<StateData<S, E>>> regionsStateDatas = splitIntoRegions(stateDatas); Collection<TransitionData<S, E>> transitionsData = getTransitionData(iterator.hasNext(), stateDatas, stateMachineModel); if (initialCount > 1) { for (Collection<StateData<S, E>> regionStateDatas : regionsStateDatas) { machine = buildMachine(machineMap, stateMap, holderMap, regionStateDatas, transitionsData, resolveBeanFactory(stateMachineModel), contextEvents, defaultExtendedState, stateMachineModel.getTransitionsData(), resolveTaskExecutor(stateMachineModel), resolveTaskScheduler(stateMachineModel), machineId, null, stateMachineModel); regionStack.push(new MachineStackItem<S, E>(machine)); } Collection<Region<S, E>> regions = new ArrayList<Region<S, E>>(); while (!regionStack.isEmpty()) { MachineStackItem<S, E> pop = regionStack.pop(); regions.add(pop.machine); } S parent = (S) peek.getParent(); RegionState<S, E> rstate = buildRegionStateInternal(parent, regions, null, stateData != null ? stateData.getEntryActions() : null, stateData != null ? stateData.getExitActions() : null, new DefaultPseudoState<S, E>(PseudoStateKind.INITIAL)); if (stateData != null) { stateMap.put(stateData.getState(), rstate); } else { // TODO: don't like that we create a last machine here Collection<State<S, E>> states = new ArrayList<State<S, E>>(); states.add(rstate); Transition<S, E> initialTransition = new InitialTransition<S, E>(rstate); StateMachine<S, E> m = buildStateMachineInternal(states, new ArrayList<Transition<S, E>>(), rstate, initialTransition, null, defaultExtendedState, null, contextEvents, resolveBeanFactory(stateMachineModel), resolveTaskExecutor(stateMachineModel), resolveTaskScheduler(stateMachineModel), beanName, machineId != null ? machineId : stateMachineModel.getConfigurationData().getMachineId(), uuid, stateMachineModel); machine = m; } } else { machine = buildMachine(machineMap, stateMap, holderMap, stateDatas, transitionsData, resolveBeanFactory(stateMachineModel), contextEvents, defaultExtendedState, stateMachineModel.getTransitionsData(), resolveTaskExecutor(stateMachineModel), resolveTaskScheduler(stateMachineModel), machineId, uuid, stateMachineModel); if (peek.isInitial() || (!peek.isInitial() && !machineMap.containsKey(peek.getParent()))) { machineMap.put(peek.getParent(), machine); } } stateStack.push(stateData); } // setup autostart for top-level machine if (machine instanceof LifecycleObjectSupport) { ((LifecycleObjectSupport) machine) .setAutoStartup(stateMachineModel.getConfigurationData().isAutoStart()); } // set top-level machine as relay final StateMachine<S, E> fmachine = machine; fmachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() { @Override public void apply(StateMachineAccess<S, E> function) { function.setRelay(fmachine); } }); // add monitoring hooks final StateMachineMonitor<S, E> stateMachineMonitor = stateMachineModel.getConfigurationData() .getStateMachineMonitor(); if (stateMachineMonitor != null || defaultStateMachineMonitor != null) { fmachine.getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S, E>>() { @Override public void apply(StateMachineAccess<S, E> function) { if (defaultStateMachineMonitor != null) { function.addStateMachineMonitor(defaultStateMachineMonitor); } if (stateMachineMonitor != null) { function.addStateMachineMonitor(stateMachineMonitor); } } }); } // TODO: should error out if sec is enabled but spring-security is not in cp if (stateMachineModel.getConfigurationData().isSecurityEnabled()) { final StateMachineSecurityInterceptor<S, E> securityInterceptor = new StateMachineSecurityInterceptor<S, E>( stateMachineModel.getConfigurationData().getTransitionSecurityAccessDecisionManager(), stateMachineModel.getConfigurationData().getEventSecurityAccessDecisionManager(), stateMachineModel.getConfigurationData().getEventSecurityRule()); log.info("Adding security interceptor " + securityInterceptor); fmachine.getStateMachineAccessor() .doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() { @Override public void apply(StateMachineAccess<S, E> function) { function.addStateMachineInterceptor(securityInterceptor); } }); } // setup distributed state machine if needed. // we wrap previously build machine with a distributed // state machine and set it to use given ensemble. if (stateMachineModel.getConfigurationData().getStateMachineEnsemble() != null) { DistributedStateMachine<S, E> distributedStateMachine = new DistributedStateMachine<S, E>( stateMachineModel.getConfigurationData().getStateMachineEnsemble(), machine); distributedStateMachine.setAutoStartup(stateMachineModel.getConfigurationData().isAutoStart()); distributedStateMachine.afterPropertiesSet(); machine = distributedStateMachine; } for (StateMachineListener<S, E> listener : stateMachineModel.getConfigurationData() .getStateMachineListeners()) { machine.addStateListener(listener); } // go through holders and fix state references which // were not known at a time holder was created for (Entry<S, StateHolder<S, E>> holder : holderMap.entrySet()) { holder.getValue().setState(stateMap.get(holder.getKey())); } return delegateAutoStartup(machine); }
From source file:org.springframework.statemachine.support.AbstractStateMachine.java
@SuppressWarnings("unchecked") @Override/*from www.ja v a2 s . c om*/ public StateMachineAccessor<S, E> getStateMachineAccessor() { // TODO: needs cleaning and perhaps not an anonymous function return new StateMachineAccessor<S, E>() { @Override public void doWithAllRegions(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess) { stateMachineAccess.apply(AbstractStateMachine.this); for (State<S, E> state : states) { if (state.isSubmachineState()) { StateMachine<S, E> submachine = ((AbstractState<S, E>) state).getSubmachine(); submachine.getStateMachineAccessor().doWithAllRegions(stateMachineAccess); } else if (state.isOrthogonal()) { Collection<Region<S, E>> regions = ((AbstractState<S, E>) state).getRegions(); for (Region<S, E> region : regions) { ((StateMachine<S, E>) region).getStateMachineAccessor() .doWithAllRegions(stateMachineAccess); } } } } @Override public List<StateMachineAccess<S, E>> withAllRegions() { List<StateMachineAccess<S, E>> list = new ArrayList<StateMachineAccess<S, E>>(); list.add(AbstractStateMachine.this); for (State<S, E> state : states) { if (state.isSubmachineState()) { StateMachine<S, E> submachine = ((AbstractState<S, E>) state).getSubmachine(); if (submachine instanceof StateMachineAccess) { list.add((StateMachineAccess<S, E>) submachine); } } else if (state.isOrthogonal()) { Collection<Region<S, E>> regions = ((AbstractState<S, E>) state).getRegions(); for (Region<S, E> region : regions) { list.add((StateMachineAccess<S, E>) region); } } } return list; } @Override public void doWithRegion(StateMachineFunction<StateMachineAccess<S, E>> stateMachineAccess) { stateMachineAccess.apply(AbstractStateMachine.this); } @Override public StateMachineAccess<S, E> withRegion() { return AbstractStateMachine.this; } }; }
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;//from www . j a v a 2 s .com 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(); } }