All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xins.server.EngineStateMachine Maven / Gradle / Ivy

The newest version!
/*
 * $Id: EngineStateMachine.java,v 1.14 2010/09/29 17:21:48 agoubard Exp $
 *
 * See the COPYRIGHT file for redistribution and use restrictions.
 */
package org.xins.server;

import org.xins.common.MandatoryArgumentChecker;

/**
 * State machine for the XINS server engine.
 *
 * @version $Revision: 1.14 $ $Date: 2010/09/29 17:21:48 $
 * @author Ernst de Haan
 */
final class EngineStateMachine {

   /**
    * Lock for the _state field. This object must be locked on
    * before _state may be read or changed.
    */
   private final Object _stateLock;

   /**
    * The current state.
    */
   private EngineState _state;

   /**
    * Constructs a new EngineStateMachine object. Initially the
    * state will be {@link EngineState#INITIAL}.
    */
   EngineStateMachine() {
      _stateLock = new Object();
      _state     = EngineState.INITIAL;
   }

   /**
    * Gets the current state.
    *
    * @return
    *    the current state, cannot be null.
    */
   EngineState getState() {
      synchronized (_stateLock) {
         return _state;
      }
   }

   /**
    * Changes the current state.
    *
    * 

If the state change is considered invalid, then an * {@link IllegalStateException} is thrown. * * @param newState * the new state, cannot be null. * * @throws IllegalArgumentException * if newState == null. * * @throws IllegalStateException * if the state change is considered invalid. */ void setState(EngineState newState) throws IllegalArgumentException, IllegalStateException { // Check preconditions MandatoryArgumentChecker.check("newState", newState); synchronized (_stateLock) { // Remember the current state EngineState oldState = _state; // Determine name of current and new state String oldStateName = (oldState == null) ? null : oldState.getName(); String newStateName = newState.getName(); // Short-circuit if the current equals the new state if (oldState == newState) { return; // Always allow changing state to DISPOSING } else if (oldState != EngineState.DISPOSING && newState == EngineState.DISPOSING) { // The first state change should be to bootstrap the framework } else if (oldState == EngineState.INITIAL && newState == EngineState.BOOTSTRAPPING_FRAMEWORK) { // Bootstrapping the framework may fail } else if (oldState == EngineState.BOOTSTRAPPING_FRAMEWORK && newState == EngineState.FRAMEWORK_BOOTSTRAP_FAILED) { // Bootstrapping the framework can be retried } else if (oldState == EngineState.FRAMEWORK_BOOTSTRAP_FAILED && newState == EngineState.BOOTSTRAPPING_FRAMEWORK) { // Bootstrapping the framework may succeed, in which case the API // will be constructed } else if (oldState == EngineState.BOOTSTRAPPING_FRAMEWORK && newState == EngineState.CONSTRUCTING_API) { // Construction of API may fail } else if (oldState == EngineState.CONSTRUCTING_API && newState == EngineState.API_CONSTRUCTION_FAILED) { // API construction can be retried } else if (oldState == EngineState.API_CONSTRUCTION_FAILED && newState == EngineState.CONSTRUCTING_API) { // Construction of API may succeed, in which case the API is // bootstrapped } else if (oldState == EngineState.CONSTRUCTING_API && newState == EngineState.BOOTSTRAPPING_API) { // Bootstrapping the API may fail } else if (oldState == EngineState.BOOTSTRAPPING_API && newState == EngineState.API_BOOTSTRAP_FAILED) { // Bootstrapping the API can be retried } else if (oldState == EngineState.API_BOOTSTRAP_FAILED && newState == EngineState.BOOTSTRAPPING_API) { // If bootstrapping the API succeeds, then the next step is either to // determine the watch interval... } else if (oldState == EngineState.BOOTSTRAPPING_API && newState == EngineState.INITIALIZING_API) { // ...or to skip that and start initializing the API } else if (oldState == EngineState.BOOTSTRAPPING_API && newState == EngineState.INITIALIZING_API) { // API initialization may fail } else if (oldState == EngineState.INITIALIZING_API && newState == EngineState.API_INITIALIZATION_FAILED) { // API initialization may be retried, but then the interval is // determined first } else if (oldState == EngineState.API_INITIALIZATION_FAILED && newState == EngineState.INITIALIZING_API) { // API initialization may succeed, in which case the engine is ready } else if (oldState == EngineState.INITIALIZING_API && newState == EngineState.READY) { // While the servet is ready, the watch interval may be redetermined, // which is the first step in reinitialization } else if (oldState == EngineState.READY && newState == EngineState.INITIALIZING_API) { // After disposal the state changes to the final disposed state } else if (oldState == EngineState.DISPOSING && newState == EngineState.DISPOSED) { // Otherwise the state change is not allowed, fail! } else { // Log error Log.log_3101(oldStateName, newStateName); // Throw exception String error = "The state " + oldStateName + " cannot be followed by the state " + newStateName + '.'; throw new IllegalStateException(error); } // Perform the state change _state = newState; Log.log_3100(oldStateName, newStateName); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy