Example usage for org.springframework.statemachine.transition Transition getTarget

List of usage examples for org.springframework.statemachine.transition Transition getTarget

Introduction

In this page you can find the example usage for org.springframework.statemachine.transition Transition getTarget.

Prototype

State<S, E> getTarget();

Source Link

Document

Gets the target state of this transition.

Usage

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(/*  w w w  . j  a v  a2 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);
            }
        });
    }
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

private Transition<S, E> findTransition(State<S, E> from, State<S, E> to) {
    for (Transition<S, E> transition : transitions) {
        if (transition.getSource() == from && transition.getTarget() == to) {
            return transition;
        }/*from  w w  w  .ja v a2  s.c  o m*/
    }
    return null;
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

synchronized void setCurrentState(State<S, E> state, Message<E> message, Transition<S, E> transition,
        boolean exit, StateMachine<S, E> stateMachine, Collection<State<S, E>> sources,
        Collection<State<S, E>> targets) {
    State<S, E> findDeep = findDeepParent(state);
    boolean isTargetSubOf = false;
    if (transition != null) {
        isTargetSubOf = StateMachineUtils.isSubstate(state, transition.getSource());
        if (isTargetSubOf && currentState == transition.getTarget()) {
            state = transition.getSource();
        }//w  ww.j  ava 2 s .c om
    }

    boolean nonDeepStatePresent = false;

    if (states.contains(state)) {
        if (exit) {
            exitCurrentState(state, message, transition, stateMachine, sources, targets);
        }
        State<S, E> notifyFrom = currentState;
        currentState = state;
        if (!isRunning()) {
            start();
        }
        entryToState(state, message, transition, stateMachine);
        notifyStateChanged(buildStateContext(Stage.STATE_CHANGED, message, null, getRelayStateMachine(),
                notifyFrom, state));
        nonDeepStatePresent = true;
    } else if (currentState == null && StateMachineUtils.isSubstate(findDeep, state)) {
        if (exit) {
            exitCurrentState(findDeep, message, transition, stateMachine, sources, targets);
        }
        State<S, E> notifyFrom = currentState;
        currentState = findDeep;
        if (!isRunning()) {
            start();
        }
        entryToState(findDeep, message, transition, stateMachine);
        notifyStateChanged(buildStateContext(Stage.STATE_CHANGED, message, null, getRelayStateMachine(),
                notifyFrom, findDeep));
    }

    if (currentState != null && !nonDeepStatePresent) {
        if (findDeep != null) {
            if (exit) {
                exitCurrentState(state, message, transition, stateMachine, sources, targets);
            }
            if (currentState == findDeep) {

                if (currentState.isSubmachineState()) {
                    StateMachine<S, E> submachine = ((AbstractState<S, E>) currentState).getSubmachine();
                    // need to check complete as submachine may now return non null
                    if (!submachine.isComplete() && submachine.getState() == state) {
                        if (currentState == findDeep) {
                            if (isTargetSubOf) {
                                entryToState(currentState, message, transition, stateMachine);
                            }
                            currentState = findDeep;
                            ((AbstractStateMachine<S, E>) submachine).setCurrentState(state, message,
                                    transition, false, stateMachine);
                            return;
                        }
                    }
                } else if (currentState.isOrthogonal()) {
                    Collection<Region<S, E>> regions = ((AbstractState<S, E>) currentState).getRegions();
                    for (Region<S, E> region : regions) {
                        if (region.getState() == state) {
                            if (currentState == findDeep) {
                                if (isTargetSubOf) {
                                    entryToState(currentState, message, transition, stateMachine);
                                }
                                currentState = findDeep;
                                ((AbstractStateMachine<S, E>) region).setCurrentState(state, message,
                                        transition, false, stateMachine);
                                return;
                            }
                        }

                    }
                }
            }
            boolean shouldTryEntry = findDeep != currentState;
            if (!shouldTryEntry && (transition.getSource() == currentState
                    && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
                shouldTryEntry = true;
            }
            currentState = findDeep;
            if (shouldTryEntry) {
                entryToState(currentState, message, transition, stateMachine, sources, targets);
            }

            if (currentState.isSubmachineState()) {
                StateMachine<S, E> submachine = ((AbstractState<S, E>) currentState).getSubmachine();
                ((AbstractStateMachine<S, E>) submachine).setCurrentState(state, message, transition, false,
                        stateMachine);
            } else if (currentState.isOrthogonal()) {
                Collection<Region<S, E>> regions = ((AbstractState<S, E>) currentState).getRegions();
                for (Region<S, E> region : regions) {
                    ((AbstractStateMachine<S, E>) region).setCurrentState(state, message, transition, false,
                            stateMachine);
                }
            }
        }
    }
    if (history != null && transition.getKind() != TransitionKind.INITIAL) {
        // do not set history if this is initial transition as
        // it would break history state set via reset as
        // we get here i.e. when machine is started in reset.
        // and it really doesn't make sense to set initial state for history
        // if we get here via initial transition
        if (history.getKind() == PseudoStateKind.HISTORY_SHALLOW) {
            ((HistoryPseudoState<S, E>) history).setState(findDeep);
        } else if (history.getKind() == PseudoStateKind.HISTORY_DEEP) {
            ((HistoryPseudoState<S, E>) history).setState(state);
        }
    }
    // if state was set from parent and we're now complete
    // also initiate stop
    if (stateMachine != this && isComplete()) {
        stop();
    }
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

private void exitFromState(State<S, E> state, Message<E> message, Transition<S, E> transition,
        StateMachine<S, E> stateMachine, Collection<State<S, E>> sources, Collection<State<S, E>> targets) {
    if (state == null) {
        return;/*from  w ww . ja v a2  s.c  o m*/
    }
    log.trace("Trying Exit state=[" + state + "]");
    StateContext<S, E> stateContext = buildStateContext(Stage.STATE_EXIT, message, transition, stateMachine);

    if (transition != null) {

        State<S, E> findDeep = findDeepParent(transition.getTarget());
        boolean isTargetSubOfOtherState = findDeep != null && findDeep != currentState;
        boolean isSubOfSource = StateMachineUtils.isSubstate(transition.getSource(), currentState);
        boolean isSubOfTarget = StateMachineUtils.isSubstate(transition.getTarget(), currentState);

        if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getSource(), transition.getTarget())
                && transition.getSource() == currentState) {
            return;
        } else if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getTarget(), transition.getSource())
                && transition.getTarget() == currentState) {
            return;
        }

        // TODO: this and entry below should be done via a separate
        // voter of some sort which would reveal transition path
        // we could make a choice on.
        if (currentState == transition.getSource() && currentState == transition.getTarget()) {
        } else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getSource()) {
        } else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
        } else if (isTargetSubOfOtherState) {
        } else if (!isSubOfSource && !isSubOfTarget && findDeep == null) {
        } else if (!isSubOfSource && !isSubOfTarget && (transition.getSource() == currentState
                && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
        } else if (StateMachineUtils.isNormalPseudoState(transition.getTarget())) {
            if (isPseudoStateSubstate(findDeep, targets)) {
                return;
            }
        } else if (findDeep != null && findDeep != state && findDeep.getStates().contains(state)) {
        } else if (!isSubOfSource && !isSubOfTarget) {
            return;
        }

    }

    log.debug("Exit state=[" + state + "]");
    state.exit(stateContext);

    notifyStateExited(buildStateContext(Stage.STATE_EXIT, message, null, getRelayStateMachine(), state, null));
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

private void entryToState(State<S, E> state, Message<E> message, Transition<S, E> transition,
        StateMachine<S, E> stateMachine, Collection<State<S, E>> sources, Collection<State<S, E>> targets) {
    if (state == null) {
        return;//w  ww.j a v  a2s .  co  m
    }
    log.trace("Trying Enter state=[" + state + "]");
    StateContext<S, E> stateContext = buildStateContext(Stage.STATE_ENTRY, message, transition, stateMachine,
            sources, targets);

    if (transition != null) {
        State<S, E> findDeep1 = findDeepParent(transition.getTarget());
        State<S, E> findDeep2 = findDeepParent(transition.getSource());
        boolean isComingFromOtherSubmachine = findDeep1 != null && findDeep2 != null
                && findDeep2 != currentState;

        boolean isSubOfSource = StateMachineUtils.isSubstate(transition.getSource(), currentState);
        boolean isSubOfTarget = StateMachineUtils.isSubstate(transition.getTarget(), currentState);

        if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getSource(), transition.getTarget())
                && transition.getSource() == currentState) {
            return;
        } else if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getTarget(), transition.getSource())
                && transition.getTarget() == currentState) {
            return;
        }

        if (currentState == transition.getSource() && currentState == transition.getTarget()) {
        } else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
        } else if (isComingFromOtherSubmachine) {
        } else if (!isSubOfSource && !isSubOfTarget && findDeep2 == null) {
        } else if (isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
            if (isDirectSubstate(transition.getSource(), transition.getTarget())
                    && transition.getKind() != TransitionKind.LOCAL && isInitial(transition.getTarget())) {
                return;
            }
        } else if (!isSubOfSource && !isSubOfTarget && (transition.getSource() == currentState
                && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
        } else if (!isSubOfSource && !isSubOfTarget) {
            if (!StateMachineUtils.isTransientPseudoState(transition.getTarget())) {
                return;
            }
        }
    }

    // with linked joins, we need to enter state but should not notify.
    // state entries are needed to track join logic.
    if (!StateMachineUtils.isPseudoState(state, PseudoStateKind.JOIN)) {
        notifyStateEntered(
                buildStateContext(Stage.STATE_ENTRY, message, transition, getRelayStateMachine(), null, state));
    }
    log.debug("Enter state=[" + state + "]");
    state.entry(stateContext);
}

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 ww w.j a  va 2  s .  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;
}