Search in sources :

Example 1 with StateTransitionResult

use of org.jivesoftware.smack.fsm.StateTransitionResult in project Smack by igniterealtime.

the class ModularXmppClientToServerConnection method attemptEnterState.

/**
 * Attempt to enter a state. Note that this method may return <code>null</code> if this state can be safely ignored.
 *
 * @param successorStateVertex the successor state vertex.
 * @param walkStateGraphContext the "walk state graph" context.
 * @return A state transition result or <code>null</code> if this state can be ignored.
 * @throws SmackException if Smack detected an exceptional situation.
 * @throws XMPPException if an XMPP protocol error was received.
 * @throws IOException if an I/O error occurred.
 * @throws InterruptedException if the calling thread was interrupted.
 */
private StateTransitionResult attemptEnterState(GraphVertex<State> successorStateVertex, WalkStateGraphContext walkStateGraphContext) throws SmackException, XMPPException, IOException, InterruptedException {
    final GraphVertex<State> initialStateVertex = currentStateVertex;
    final State initialState = initialStateVertex.getElement();
    final State successorState = successorStateVertex.getElement();
    final StateDescriptor successorStateDescriptor = successorState.getStateDescriptor();
    if (!successorStateDescriptor.isMultiVisitState() && walkStateGraphContext.stateAlreadyVisited(successorState)) {
        // 'Compression' state. We return 'null' here to signal that the state can safely be ignored.
        return null;
    }
    if (successorStateDescriptor.isNotImplemented()) {
        StateTransitionResult.TransitionImpossibleBecauseNotImplemented transtionImpossibleBecauseNotImplemented = new StateTransitionResult.TransitionImpossibleBecauseNotImplemented(successorStateDescriptor);
        invokeConnectionStateMachineListener(new ConnectionStateEvent.TransitionNotPossible(initialState, successorState, transtionImpossibleBecauseNotImplemented));
        return transtionImpossibleBecauseNotImplemented;
    }
    final StateTransitionResult.AttemptResult transitionAttemptResult;
    try {
        StateTransitionResult.TransitionImpossible transitionImpossible = successorState.isTransitionToPossible(walkStateGraphContext);
        if (transitionImpossible != null) {
            invokeConnectionStateMachineListener(new ConnectionStateEvent.TransitionNotPossible(initialState, successorState, transitionImpossible));
            return transitionImpossible;
        }
        invokeConnectionStateMachineListener(new ConnectionStateEvent.AboutToTransitionInto(initialState, successorState));
        transitionAttemptResult = successorState.transitionInto(walkStateGraphContext);
    } catch (SmackException | IOException | InterruptedException | XMPPException e) {
        // Unwind the state here too, since this state will not be unwound by walkStateGraph(), as it will not
        // become a predecessor state in the walk.
        unwindState(successorState);
        throw e;
    }
    if (transitionAttemptResult instanceof StateTransitionResult.Failure) {
        StateTransitionResult.Failure transitionFailureResult = (StateTransitionResult.Failure) transitionAttemptResult;
        invokeConnectionStateMachineListener(new ConnectionStateEvent.TransitionFailed(initialState, successorState, transitionFailureResult));
        return transitionAttemptResult;
    }
    // If transitionAttemptResult is not an instance of TransitionFailureResult, then it has to be of type
    // TransitionSuccessResult.
    StateTransitionResult.Success transitionSuccessResult = (StateTransitionResult.Success) transitionAttemptResult;
    currentStateVertex = successorStateVertex;
    invokeConnectionStateMachineListener(new ConnectionStateEvent.SuccessfullyTransitionedInto(successorState, transitionSuccessResult));
    return transitionSuccessResult;
}
Also used : SmackException(org.jivesoftware.smack.SmackException) IOException(java.io.IOException) ConnectionStateEvent(org.jivesoftware.smack.fsm.ConnectionStateEvent) LookupConnectionEndpointsSuccess(org.jivesoftware.smack.c2s.XmppClientToServerTransport.LookupConnectionEndpointsSuccess) State(org.jivesoftware.smack.fsm.State) NoOpState(org.jivesoftware.smack.fsm.NoOpState) AttemptResult(org.jivesoftware.smack.fsm.StateTransitionResult.AttemptResult) StateDescriptor(org.jivesoftware.smack.fsm.StateDescriptor) StateTransitionResult(org.jivesoftware.smack.fsm.StateTransitionResult) XMPPException(org.jivesoftware.smack.XMPPException)

Example 2 with StateTransitionResult

use of org.jivesoftware.smack.fsm.StateTransitionResult in project Smack by igniterealtime.

the class ModularXmppClientToServerConnection method walkStateGraphInternal.

private void walkStateGraphInternal(WalkStateGraphContext walkStateGraphContext) throws IOException, SmackException, InterruptedException, XMPPException {
    // Save a copy of the current state
    final GraphVertex<State> initialStateVertex = currentStateVertex;
    final State initialState = initialStateVertex.getElement();
    final StateDescriptor initialStateDescriptor = initialState.getStateDescriptor();
    walkStateGraphContext.recordWalkTo(initialState);
    // Check if this is the walk's final state.
    if (walkStateGraphContext.isWalksFinalState(initialStateDescriptor)) {
        // If this is used as final state, then it should be marked as such.
        assert initialStateDescriptor.isFinalState();
        // We reached the final state.
        invokeConnectionStateMachineListener(new ConnectionStateEvent.FinalStateReached(initialState));
        return;
    }
    List<GraphVertex<State>> outgoingStateEdges = initialStateVertex.getOutgoingEdges();
    // See if we need to handle mandatory intermediate states.
    GraphVertex<State> mandatoryIntermediateStateVertex = walkStateGraphContext.maybeReturnMandatoryImmediateState(outgoingStateEdges);
    if (mandatoryIntermediateStateVertex != null) {
        StateTransitionResult reason = attemptEnterState(mandatoryIntermediateStateVertex, walkStateGraphContext);
        if (reason instanceof StateTransitionResult.Success) {
            walkStateGraph(walkStateGraphContext);
            return;
        }
        // We could not enter a mandatory intermediate state. Throw here.
        throw new StateMachineException.SmackMandatoryStateFailedException(mandatoryIntermediateStateVertex.getElement(), reason);
    }
    for (Iterator<GraphVertex<State>> it = outgoingStateEdges.iterator(); it.hasNext(); ) {
        GraphVertex<State> successorStateVertex = it.next();
        State successorState = successorStateVertex.getElement();
        // state.
        if (walkStateGraphContext.wouldCauseCycle(successorStateVertex)) {
            // Ignore this successor.
            invokeConnectionStateMachineListener(new ConnectionStateEvent.TransitionIgnoredDueCycle(initialStateVertex, successorStateVertex));
        } else {
            StateTransitionResult result = attemptEnterState(successorStateVertex, walkStateGraphContext);
            if (result instanceof StateTransitionResult.Success) {
                break;
            }
            // record it.
            if (result != null) {
                walkStateGraphContext.recordFailedState(successorState, result);
            }
        }
        if (!it.hasNext()) {
            throw StateMachineException.SmackStateGraphDeadEndException.from(walkStateGraphContext, initialStateVertex);
        }
    }
    // Walk the state graph by recursion.
    walkStateGraph(walkStateGraphContext);
}
Also used : GraphVertex(org.jivesoftware.smack.fsm.StateDescriptorGraph.GraphVertex) State(org.jivesoftware.smack.fsm.State) NoOpState(org.jivesoftware.smack.fsm.NoOpState) StateDescriptor(org.jivesoftware.smack.fsm.StateDescriptor) StateTransitionResult(org.jivesoftware.smack.fsm.StateTransitionResult) ConnectionStateEvent(org.jivesoftware.smack.fsm.ConnectionStateEvent) LookupConnectionEndpointsSuccess(org.jivesoftware.smack.c2s.XmppClientToServerTransport.LookupConnectionEndpointsSuccess)

Aggregations

LookupConnectionEndpointsSuccess (org.jivesoftware.smack.c2s.XmppClientToServerTransport.LookupConnectionEndpointsSuccess)2 ConnectionStateEvent (org.jivesoftware.smack.fsm.ConnectionStateEvent)2 NoOpState (org.jivesoftware.smack.fsm.NoOpState)2 State (org.jivesoftware.smack.fsm.State)2 StateDescriptor (org.jivesoftware.smack.fsm.StateDescriptor)2 StateTransitionResult (org.jivesoftware.smack.fsm.StateTransitionResult)2 IOException (java.io.IOException)1 SmackException (org.jivesoftware.smack.SmackException)1 XMPPException (org.jivesoftware.smack.XMPPException)1 GraphVertex (org.jivesoftware.smack.fsm.StateDescriptorGraph.GraphVertex)1 AttemptResult (org.jivesoftware.smack.fsm.StateTransitionResult.AttemptResult)1