001/**
002 *
003 * Copyright 2018-2020 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack.fsm;
018
019import java.io.IOException;
020
021import org.jivesoftware.smack.SmackException;
022import org.jivesoftware.smack.XMPPException;
023import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
024import org.jivesoftware.smack.c2s.internal.WalkStateGraphContext;
025
026/**
027 * Note that this is an non-static inner class of XmppClientToServerConnection so that states can inspect and modify
028 * the connection.
029 */
030public abstract class State {
031
032    protected final StateDescriptor stateDescriptor;
033
034    protected final ModularXmppClientToServerConnectionInternal connectionInternal;
035
036    protected State(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) {
037        this.stateDescriptor = stateDescriptor;
038        this.connectionInternal = connectionInternal;
039    }
040
041    /**
042     * Check if the state should be activated.
043     *
044     * @param walkStateGraphContext the context of the current state graph walk.
045     * @return <code>null</code> if the state should be activated.
046     * @throws SmackException in case a Smack exception occurs.
047     */
048    public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext)
049                    throws SmackException {
050        return null;
051    }
052
053    public abstract StateTransitionResult.AttemptResult transitionInto(WalkStateGraphContext walkStateGraphContext)
054                    throws IOException, SmackException, InterruptedException, XMPPException;
055
056    public StateDescriptor getStateDescriptor() {
057        return stateDescriptor;
058    }
059
060    public void resetState() {
061    }
062
063    @Override
064    public String toString() {
065        return "State " + stateDescriptor + ' ' + connectionInternal.connection;
066    }
067
068    protected final void ensureNotOnOurWayToAuthenticatedAndResourceBound(
069                    WalkStateGraphContext walkStateGraphContext) {
070        if (walkStateGraphContext.isFinalStateAuthenticatedAndResourceBound()) {
071            throw new IllegalStateException(
072                            "Smack should never attempt to reach the authenticated and resource bound state over "
073                                            + this
074                                            + ". This is probably a programming error within Smack, please report it to the develoeprs.");
075        }
076    }
077
078}