Example usage for org.springframework.statemachine.state ExitPseudoState ExitPseudoState

List of usage examples for org.springframework.statemachine.state ExitPseudoState ExitPseudoState

Introduction

In this page you can find the example usage for org.springframework.statemachine.state ExitPseudoState ExitPseudoState.

Prototype

public ExitPseudoState(StateHolder<S, E> state) 

Source Link

Document

Instantiates a new exit pseudo state.

Usage

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.j a  v  a2  s . 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;
}