Example usage for org.springframework.statemachine.state State isOrthogonal

List of usage examples for org.springframework.statemachine.state State isOrthogonal

Introduction

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

Prototype

boolean isOrthogonal();

Source Link

Document

Checks if state is an orthogonal state.

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(/*from  ww  w  .  jav  a 2  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

@SuppressWarnings("unchecked")
@Override/*w w  w .jav a2 s  .c  o m*/
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;/* ww  w  .  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();
    }
}