StreamManagementModule.java

  1. /**
  2.  *
  3.  * Copyright 2019-2020 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.sm;

  18. import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.AuthenticatedAndResourceBoundStateDescriptor;
  19. import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.AuthenticatedButUnboundStateDescriptor;
  20. import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.ResourceBindingStateDescriptor;
  21. import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionModule;
  22. import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
  23. import org.jivesoftware.smack.c2s.internal.WalkStateGraphContext;
  24. import org.jivesoftware.smack.compression.CompressionModule.CompressionStateDescriptor;
  25. import org.jivesoftware.smack.fsm.State;
  26. import org.jivesoftware.smack.fsm.StateDescriptor;
  27. import org.jivesoftware.smack.fsm.StateTransitionResult;

  28. public class StreamManagementModule extends ModularXmppClientToServerConnectionModule<StreamManagementModuleDescriptor> {

  29.     protected StreamManagementModule(StreamManagementModuleDescriptor moduleDescriptor,
  30.                     ModularXmppClientToServerConnectionInternal connectionInternal) {
  31.         super(moduleDescriptor, connectionInternal);
  32.     }

  33.     private boolean useSm = true;

  34.     private boolean useSmResumption = true;

  35.     public static final class EnableStreamManagementStateDescriptor extends StateDescriptor {

  36.         private EnableStreamManagementStateDescriptor() {
  37.             super(StreamManagementModule.EnableStreamManagementState.class, 198, StateDescriptor.Property.notImplemented);

  38.             addPredeccessor(ResourceBindingStateDescriptor.class);
  39.             addSuccessor(AuthenticatedAndResourceBoundStateDescriptor.class);
  40.             declarePrecedenceOver(AuthenticatedAndResourceBoundStateDescriptor.class);
  41.         }

  42.         @Override
  43.         protected StreamManagementModule.EnableStreamManagementState constructState(ModularXmppClientToServerConnectionInternal connectionInternal) {
  44.             // 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.
  45.             StreamManagementModule smModule = connectionInternal.connection.getConnectionModuleFor(StreamManagementModuleDescriptor.class);
  46.             return smModule.constructEnableStreamMangementState(this, connectionInternal);
  47.         }

  48.     }

  49.     private EnableStreamManagementState constructEnableStreamMangementState(
  50.                     EnableStreamManagementStateDescriptor enableStreamManagementStateDescriptor,
  51.                     ModularXmppClientToServerConnectionInternal connectionInternal) {
  52.         return new EnableStreamManagementState(enableStreamManagementStateDescriptor, connectionInternal);
  53.     }

  54.     private final class EnableStreamManagementState extends State {
  55.         private EnableStreamManagementState(EnableStreamManagementStateDescriptor stateDescriptor,
  56.                         ModularXmppClientToServerConnectionInternal connectionInternal) {
  57.             super(stateDescriptor, connectionInternal);
  58.         }

  59.         @Override
  60.         public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext) {
  61.             if (!useSm) {
  62.                 return new StateTransitionResult.TransitionImpossibleReason("Stream management not enabled");
  63.             }

  64.             return new StateTransitionResult.TransitionImpossibleBecauseNotImplemented(stateDescriptor);
  65.         }

  66.         @Override
  67.         public StateTransitionResult.AttemptResult transitionInto(WalkStateGraphContext walkStateGraphContext) {
  68.             throw new IllegalStateException("SM not implemented");
  69.         }
  70.     }

  71.     public static final class ResumeStreamStateDescriptor extends StateDescriptor {
  72.         private ResumeStreamStateDescriptor() {
  73.             super(StreamManagementModule.ResumeStreamState.class, 198, StateDescriptor.Property.notImplemented);

  74.             addPredeccessor(AuthenticatedButUnboundStateDescriptor.class);
  75.             addSuccessor(AuthenticatedAndResourceBoundStateDescriptor.class);
  76.             declarePrecedenceOver(ResourceBindingStateDescriptor.class);
  77.             declareInferiorityTo(CompressionStateDescriptor.class);
  78.         }

  79.         @Override
  80.         protected StreamManagementModule.ResumeStreamState constructState(ModularXmppClientToServerConnectionInternal connectionInternal) {
  81.             StreamManagementModule smModule = connectionInternal.connection.getConnectionModuleFor(StreamManagementModuleDescriptor.class);
  82.             return smModule.constructResumeStreamState(this, connectionInternal);
  83.         }

  84.     }

  85.     private ResumeStreamState constructResumeStreamState(
  86.                     ResumeStreamStateDescriptor resumeStreamStateDescriptor,
  87.                     ModularXmppClientToServerConnectionInternal connectionInternal) {
  88.         return new ResumeStreamState(resumeStreamStateDescriptor, connectionInternal);
  89.     }

  90.     private final class ResumeStreamState extends State {
  91.         private ResumeStreamState(ResumeStreamStateDescriptor stateDescriptor,
  92.                         ModularXmppClientToServerConnectionInternal connectionInternal) {
  93.             super(stateDescriptor, connectionInternal);
  94.         }


  95.         @Override
  96.         public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext) {
  97.             if (!useSmResumption) {
  98.                 return new StateTransitionResult.TransitionImpossibleReason("Stream resumption not enabled");
  99.             }

  100.             return new StateTransitionResult.TransitionImpossibleBecauseNotImplemented(stateDescriptor);
  101.         }

  102.         @Override
  103.         public StateTransitionResult.AttemptResult transitionInto(WalkStateGraphContext walkStateGraphContext) {
  104.             throw new IllegalStateException("Stream resumption not implemented");
  105.         }
  106.     }

  107.     public void setStreamManagementEnabled(boolean useSm) {
  108.         this.useSm = useSm;
  109.     }

  110.     public void setStreamResumptionEnabled(boolean useSmResumption) {
  111.         this.useSmResumption = useSmResumption;
  112.     }

  113. }