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

com.fredhopper.lifecycle.AbstractLifeCycle Maven / Gradle / Ivy

The newest version!
package com.fredhopper.lifecycle;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;

/**
 * A base implementation structure for {@link LifeCycle}.
 */
public abstract class AbstractLifeCycle implements LifeCycle {

  private final AtomicReference state = new AtomicReference(State.STOPPED);
  private final Collection stateListeners = new CopyOnWriteArrayList<>();

  @Override
  public State getState() {
    return state.get();
  }

  @Override
  public Collection getStateListeners() {
    return this.stateListeners;
  }

  @Override
  public void initLifeCycle() throws Exception {
    doInitLifeCycle();
    changeState(State.STOPPED, State.INITIALIZED);
  }


  @Override
  public void startLifeCycle() throws Exception {
    changeState(State.INITIALIZED, State.STARTING);
    doStartLifeCycle();
    changeState(State.STARTING, State.RUNNING);
  }

  @Override
  public void pause() throws Exception {
    doPause();
    changeState(State.RUNNING, State.PAUSED);
  }

  @Override
  public void resume() throws Exception {
    doResume();
    changeState(State.PAUSED, State.RUNNING);
  }

  @Override
  public void stopLifeCycle() throws Exception {
    changeState(State.RUNNING, State.STOPPING);
    doStopLifeCycle();
    changeState(State.STOPPING, State.STOPPED);
  }

  /**
   * Add a new {@link StateListener}
   * 
   * @param listener the {@link StateListener} to add
   */
  public void addStateListener(StateListener listener) {
    this.stateListeners.add(listener);
  }

  /**
   * Remove a registered {@link StateListener}
   * 
   * @param listener the {@link StateListener} to remove
   */
  public void removeStateListener(StateListener listener) {
    this.stateListeners.remove(listener);
  }

  @Override
  public String toString() {
    return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
  }

  /**
   * First changes the state from a current value to a target
   * value. Second, publishes the change of state to all the
   * listeners through {@link #getStateListeners()}.
   * 
   * @param from the current state
   * @param to the new state
   * @throws Exception if the state cannot be changed or some
   *         {@link StateListener}failed to apply the same
   *         change.
   */
  protected void changeState(State from, State to) throws Exception {
    if (!this.state.compareAndSet(from, to)) {
      throw new Exception("Cannot change state from " + from + " to " + to + " for " + this);
    }
    publishState(from, to);
  }

  /**
   * Propagates a change of {@link State} to all the
   * {@link StateListener}registered with this life cycle
   * object.
   * 
   * @see #changeState(State, State)
   * 
   * @param from the old state
   * @param to the new state
   * @throws Exception if a listener fails to accept the change
   */
  protected void publishState(State from, State to) throws Exception {
    final Collection listeners = getStateListeners();
    synchronized (listeners) {
      for (StateListener listener : listeners) {
        listener.stateChanged(from, to);
      }
    }
  }

  /**
   * Similar to {@link #initLifeCycle()} for inherited classes.
   * 
   * @see LifeCycle#initLifeCycle()
   * @throws Exception See {@link #initLifeCycle()}
   */
  protected abstract void doInitLifeCycle() throws Exception;

  /**
   * Similar to {@link #startLifeCycle()} for inherited classes.
   * 
   * @see LifeCycle#startLifeCycle()
   * @throws Exception See {@link #startLifeCycle()}
   */
  protected abstract void doStartLifeCycle() throws Exception;

  /**
   * Similar to {@link #pause()} for inherited classes.
   * 
   * @see Resumable#pause()
   * @throws Exception See {@link #pause()}
   */
  protected void doPause() throws Exception {}

  /**
   * Similar to {@link #resume()} for inherited classes.
   * 
   * @see Resumable#resume()
   * @throws Exception See {@link #resume()}
   */
  protected void doResume() throws Exception {}

  /**
   * Similar to {@link #stopLifeCycle()} for inherited classes.
   * 
   * @see LifeCycle#stopLifeCycle()
   * @throws Exception See {@link #stopLifeCycle()}
   */
  protected abstract void doStopLifeCycle() throws Exception;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy