State.java

  1. /**
  2.  *
  3.  * Copyright 2018-2021 Florian Schmaus
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smack.fsm;

  18. import java.io.IOException;

  19. import org.jivesoftware.smack.SmackException;
  20. import org.jivesoftware.smack.XMPPException;
  21. import org.jivesoftware.smack.c2s.XmppClientToServerTransport;
  22. import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
  23. import org.jivesoftware.smack.c2s.internal.WalkStateGraphContext;

  24. /**
  25.  * Note that this is an non-static inner class of XmppClientToServerConnection so that states can inspect and modify
  26.  * the connection.
  27.  */
  28. public abstract class State {

  29.     protected final StateDescriptor stateDescriptor;

  30.     protected final ModularXmppClientToServerConnectionInternal connectionInternal;

  31.     protected State(StateDescriptor stateDescriptor, ModularXmppClientToServerConnectionInternal connectionInternal) {
  32.         this.stateDescriptor = stateDescriptor;
  33.         this.connectionInternal = connectionInternal;
  34.     }

  35.     /**
  36.      * Check if the state should be activated.
  37.      *
  38.      * @param walkStateGraphContext the context of the current state graph walk.
  39.      * @return <code>null</code> if the state should be activated.
  40.      * @throws SmackException in case a Smack exception occurs.
  41.      */
  42.     public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext)
  43.                     throws SmackException {
  44.         return null;
  45.     }

  46.     public abstract StateTransitionResult.AttemptResult transitionInto(WalkStateGraphContext walkStateGraphContext)
  47.                     throws IOException, SmackException, InterruptedException, XMPPException;

  48.     public StateDescriptor getStateDescriptor() {
  49.         return stateDescriptor;
  50.     }

  51.     public void resetState() {
  52.     }

  53.     @Override
  54.     public String toString() {
  55.         return "State " + stateDescriptor + ' ' + connectionInternal.connection;
  56.     }

  57.     protected final void ensureNotOnOurWayToAuthenticatedAndResourceBound(
  58.                     WalkStateGraphContext walkStateGraphContext) {
  59.         if (walkStateGraphContext.isFinalStateAuthenticatedAndResourceBound()) {
  60.             throw new IllegalStateException(
  61.                             "Smack should never attempt to reach the authenticated and resource bound state over "
  62.                                             + this
  63.                                             + ". This is probably a programming error within Smack, please report it to the develoeprs.");
  64.         }
  65.     }

  66.     public abstract static class AbstractTransport extends State {

  67.         private final XmppClientToServerTransport transport;

  68.         protected AbstractTransport(XmppClientToServerTransport transport, StateDescriptor stateDescriptor,
  69.                         ModularXmppClientToServerConnectionInternal connectionInternal) {
  70.             super(stateDescriptor, connectionInternal);
  71.             this.transport = transport;
  72.         }

  73.         @Override
  74.         public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext)
  75.                         throws SmackException {
  76.             if (!transport.hasUseableConnectionEndpoints()) {
  77.                 return new StateTransitionResult.TransitionImpossibleBecauseNoEndpointsDiscovered(transport);
  78.             }

  79.             return super.isTransitionToPossible(walkStateGraphContext);
  80.         }
  81.     }
  82. }