001/**
002 *
003 * Copyright 2019-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.isr;
018
019import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.AuthenticatedAndResourceBoundStateDescriptor;
020import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.ConnectedButUnauthenticatedStateDescriptor;
021import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.SaslAuthenticationStateDescriptor;
022import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionModule;
023import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
024import org.jivesoftware.smack.c2s.internal.WalkStateGraphContext;
025import org.jivesoftware.smack.fsm.State;
026import org.jivesoftware.smack.fsm.StateDescriptor;
027import org.jivesoftware.smack.fsm.StateTransitionResult;
028
029public class InstantStreamResumptionModule extends ModularXmppClientToServerConnectionModule<InstantStreamResumptionModuleDescriptor> {
030
031    protected InstantStreamResumptionModule(InstantStreamResumptionModuleDescriptor instantStreamResumptionModuleDescriptor,
032                    ModularXmppClientToServerConnectionInternal connectionInternal) {
033        super(instantStreamResumptionModuleDescriptor, connectionInternal);
034    }
035
036    public static final class InstantStreamResumptionStateDescriptor extends StateDescriptor {
037        private InstantStreamResumptionStateDescriptor() {
038            super(InstantStreamResumptionState.class, 397, StateDescriptor.Property.notImplemented);
039
040            addSuccessor(AuthenticatedAndResourceBoundStateDescriptor.class);
041            addPredeccessor(ConnectedButUnauthenticatedStateDescriptor.class);
042            declarePrecedenceOver(SaslAuthenticationStateDescriptor.class);
043        }
044
045        @Override
046        protected InstantStreamResumptionModule.InstantStreamResumptionState constructState(ModularXmppClientToServerConnectionInternal connectionInternal) {
047            // This is the trick: the module is constructed prior the states, so we get the actual state out of the module by fetching the module from the connection.
048            InstantStreamResumptionModule isrModule = connectionInternal.connection.getConnectionModuleFor(InstantStreamResumptionModuleDescriptor.class);
049            return isrModule.constructInstantStreamResumptionState(this, connectionInternal);
050        }
051    }
052
053    private boolean useIsr = true;
054
055    private final class InstantStreamResumptionState extends State {
056        private InstantStreamResumptionState(InstantStreamResumptionStateDescriptor instantStreamResumptionStateDescriptor,
057                        ModularXmppClientToServerConnectionInternal connectionInternal) {
058            super(instantStreamResumptionStateDescriptor, connectionInternal);
059        }
060
061        @Override
062        public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext) {
063            if (!useIsr) {
064                return new StateTransitionResult.TransitionImpossibleReason("Instant stream resumption not enabled nor implemented");
065            }
066
067            return new StateTransitionResult.TransitionImpossibleBecauseNotImplemented(stateDescriptor);
068        }
069
070        @Override
071        public StateTransitionResult.AttemptResult transitionInto(WalkStateGraphContext walkStateGraphContext) {
072            throw new IllegalStateException("Instant stream resumption not implemented");
073        }
074    }
075
076    public void setInstantStreamResumptionEnabled(boolean useIsr) {
077        this.useIsr = useIsr;
078    }
079
080    public InstantStreamResumptionState constructInstantStreamResumptionState(
081                    InstantStreamResumptionStateDescriptor instantStreamResumptionStateDescriptor,
082                    ModularXmppClientToServerConnectionInternal connectionInternal) {
083        return new InstantStreamResumptionState(instantStreamResumptionStateDescriptor, connectionInternal);
084    }
085}