content: package org.littleshoot.proxy.impl;
  
  import io.netty.util.concurrent.Future;
  
  /**
   * Represents a phase in a {@link ConnectionFlow}.
   */
  abstract class ConnectionFlowStep {
      private final ProxyConnectionLogger LOG;
      private final ProxyConnection connection;
      private final ConnectionState state;
  
      /**
       * Construct a new step in a connection flow.
       * 
       * @param connection
       *            the connection that we're working on
       * @param state
       *            the state that the connection will show while we're processing
       *            this step
       */
      ConnectionFlowStep(ProxyConnection connection,
              ConnectionState state) {
          super();
          this.connection = connection;
          this.state = state;
          this.LOG = connection.getLOG();
      }
  
      ProxyConnection getConnection() {
          return connection;
      }
  
      ConnectionState getState() {
          return state;
      }
  
      /**
       * Indicates whether or not to suppress the initial request. Defaults to
       * false, can be overridden.
       * 
       * @return
       */
      boolean shouldSuppressInitialRequest() {
          return false;
      }
  
      /**
       * <p>
       * Indicates whether or not this step should be executed on the channel's
       * event loop. Defaults to true, can be overridden.
       * </p>
       * 
       * <p>
       * If this step modifies the pipeline, for example by adding/removing
       * handlers, it's best to make it execute on the event loop.
       * </p>
       * 
       * 
       * @return
       */
      boolean shouldExecuteOnEventLoop() {
          return true;
      }
  
      /**
       * Implement this method to actually do the work involved in this step of
       * the flow.
       * 
       * @return
       */
      protected abstract Future execute();
  
      /**
       * When the flow determines that this step was successful, it calls into
       * this method. The default implementation simply continues with the flow.
       * Other implementations may choose to not continue and instead wait for a
       * message or something like that.
       * 
       * @param flow
       */
      void onSuccess(ConnectionFlow flow) {
          flow.advance();
      }
  
      /**
       * <p>
       * Any messages that are read from the underlying connection while we're at
       * this step of the connection flow are passed to this method.
       * </p>
       * 
       * <p>
       * The default implementation ignores the message and logs this, since we
       * weren't really expecting a message here.
       * </p>
       * 
       * <p>
       * Some {@link ConnectionFlowStep}s do need to read the messages, so they
       * override this method as appropriate.
       * </p>
       * 
       * @param flow
       *            our {@link ConnectionFlow}
       * @param msg
       *            the message read from the underlying connection
       */
      void read(ConnectionFlow flow, Object msg) {
          LOG.debug("Received message while in the middle of connecting: {}", msg);
      }
  
      @Override
      public String toString() {
          return state.toString();
      }
  
  }
  