Package net.sf.xbus.technical

Source Code of net.sf.xbus.technical.ReceiverThreadManager

package net.sf.xbus.technical;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import net.sf.xbus.base.core.Constants;
import net.sf.xbus.base.core.XException;
import net.sf.xbus.base.core.config.Configuration;
import net.sf.xbus.base.core.reflection.XBUSClassLoader;
import net.sf.xbus.base.core.trace.Trace;

/**
* Manages the state of all receivers running in the background. This class
* implements the Singleton design pattern.
*/
public class ReceiverThreadManager {
  /**
   * Default for the amount of errors, after them a receiver will be stopped.
   */
  static protected final int DEFAULT_STOP_AFTER_ERRORS = -1; // times

  private static ReceiverThreadManager mReceiverThreadManager = null;
  private static final Object classLock = ReceiverThreadManager.class;

  /**
   * Contains all ReceiverThreads that has been started by the
   * ReceiverService. Key: name of the system Entry: the ReceiverServiceThread
   * object
   */
  private SortedMap mAllThreads = Collections
      .synchronizedSortedMap(new TreeMap());
  private SortedSet mStoppedThreads = Collections
      .synchronizedSortedSet(new TreeSet());
  private SortedSet mStoppedHTTPReceivers = Collections
      .synchronizedSortedSet(new TreeSet());
  private boolean mIsServletEngine = false;

  /**
   * All threads for the systems will run in one ThreadGroup. This makes
   * administration easier.
   */
  private ThreadGroup mThreadGroup = new ThreadGroup("ReceiverService");

  /**
   * The default constructor is private because this is a singleton
   */
  private ReceiverThreadManager() {
  }

  /**
   * Returns the one and only object of class
   * <code>ReceiverThreadManager</code>.
   *
   * @return the one and only object of class
   *         <code>ReceiverThreadManager</code>
   */
  static public ReceiverThreadManager getInstance() {
    synchronized (classLock) {
      if (mReceiverThreadManager == null) {
        mReceiverThreadManager = new ReceiverThreadManager();
      }
      return mReceiverThreadManager;
    }
  }

  /**
   * Starts a ReceiverThread for the given system.
   *
   * @param system
   *            the name of the system to start the receiver for
   * @throws XException
   *             if something goes wrong
   */
  public void startReceiverThread(String system) throws XException {
    /*
     * Check if System is configured with ReceiverThread
     */
    String receiver = Configuration.getInstance().getValueOptional(
        Constants.CHAPTER_SYSTEM, system, "Receiver");
    if ((receiver != null) && (receiver.endsWith("Thread"))) {
      /*
       * Check if ReceiverThread isn't already running
       */
      if (getRunningReceiverThreads().contains(system)) {
        Vector params = new Vector(1);
        params.add(system);
        throw new XException(Constants.LOCATION_INTERN,
            Constants.LAYER_TECHNICAL,
            Constants.PACKAGE_TECHNICAL_TECHNICAL, "7", params);
      }

      /*
       * Start receiver
       */
      ReceiverThreadBase receiverThreadImpl = ReceiverFactory
          .createReceiverThread(receiver, system);

      Thread receiverThread = new Thread(mThreadGroup,
          receiverThreadImpl, system);
      receiverThread.setDaemon(false);
      receiverThread
          .setContextClassLoader(XBUSClassLoader.getInstance(Thread
              .currentThread().getContextClassLoader()));
      receiverThread.start();

      /*
       * Put system and thread in list of all systems and remove it from
       * stoppedThreads
       */
      mAllThreads.put(system, receiverThreadImpl);
      mStoppedThreads.remove(system);
    } else if (isHTTPReceiver(system)) {
      if (mStoppedHTTPReceivers.contains(system)) {
        mStoppedHTTPReceivers.remove(system);
        Trace.always("Starting HTTPReceiver for " + system);
      }
    } else {
      Vector params = new Vector(1);
      params.add(system);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_TECHNICAL,
          Constants.PACKAGE_TECHNICAL_TECHNICAL, "6", params);
    }

  }

  /**
   * Demands the stop of the ReceiverThread for the given <code>system</code>.
   *
   * @param system
   *            the name of the system to stop the receiver for
   * @throws XException
   *             if something goes wrong
   */
  public void demandStopReceiverThread(String system) throws XException {
    Trace.always("Demanding stop for " + system);

    if (getRunningReceiverThreads().contains(system)) {

      ReceiverThreadBase startedThread = (ReceiverThreadBase) mAllThreads
          .get(system);

      if (startedThread == null) {
        Trace.warn(system + " is not a started receiver");
        return;
      }

      startedThread.interruptThread();
      mStoppedThreads.add(system);
    } else if (getRunningHTTPReceivers().contains(system)) {
      mStoppedHTTPReceivers.add(system);
      Trace.always("HTTPReceiver for " + system + " stopped");
    } else {
      Trace.warn(system + " is not a started receiver");
      return;
    }
  }

  /**
   * Returns a set with the names of all ReceiverThreads found in the
   * <code>Configuration</code>.
   *
   * @return the names of all ReceiverThreads found in the
   *         <code>Configuration</code>
   */
  public Set getAllReceiverThreads() {
    Set returnSet = new TreeSet();
    returnSet.addAll(mAllThreads.keySet());
    return returnSet;
  }

  /**
   * Returns a set with the names of all background receivers (ReceiverThreads
   * and HTTPReceivers) found in the <code>Configuration</code>.
   *
   * @return the names of all background receivers found in the
   *         <code>Configuration</code>
   * @throws XException
   *             if something goes wrong
   */
  public Set getAllSystems() throws XException {
    Set returnSet = getAllReceiverThreads();
    returnSet.addAll(getAllHTTPReceivers());
    return returnSet;
  }

  /**
   * Returns a set with the names of all running background receivers
   * (ReceiverThreads and HTTPReceivers).
   *
   * @return the names of all running background receivers
   * @throws XException
   *             if something goes wrong
   */
  public Set getRunningSystems() throws XException {
    Set retSet = getRunningReceiverThreads();
    retSet.addAll(getRunningHTTPReceivers());
    return retSet;
  }

  /**
   * Returns a set with the names of all running ReceiverThreads.
   *
   * @return the names of all running ReceiverThreads
   */
  public Set getRunningReceiverThreads() {
    int threadCount = mThreadGroup.activeCount();
    TreeSet retSet = new TreeSet();

    Thread[] startedThreads = new Thread[threadCount];
    mThreadGroup.enumerate(startedThreads);

    for (int i = 0; i < threadCount; i++) {
      if ((startedThreads[i] != null)
          && (mAllThreads.containsKey(startedThreads[i].getName()))) {
        retSet.add(startedThreads[i].getName());
      }
    }
    return retSet;
  }

  /**
   * Returns a set with the names of all running HTTPReceivers.
   *
   * @return the names of all running HTTPReceivers
   * @throws XException
   *             if something goes wrong
   */
  protected Set getRunningHTTPReceivers() throws XException {
    TreeSet returnSet = new TreeSet();

    for (Iterator it = getAllHTTPReceivers().iterator(); it.hasNext();) {
      Object stoppedHTTPReceiver = it.next();
      if (!mStoppedHTTPReceivers.contains(stoppedHTTPReceiver)) {
        returnSet.add(stoppedHTTPReceiver);
      }
    }

    return returnSet;
  }

  /**
   * Returns a set with the names of all stopped background receivers
   * (ReceiverThreads and HTTPReceivers).
   *
   * @return the names of all stopped background receivers
   */
  public Set getStoppedSystems() {
    TreeSet returnSet = new TreeSet();

    returnSet.addAll(mStoppedThreads);
    returnSet.addAll(mStoppedHTTPReceivers);

    return returnSet;
  }

  /**
   * Indicates whether the ReceiverService is started inside a servlet engine.
   *
   * @param isServletEngine
   *            true if the ReceiverService is running in a servlet engine
   */
  protected void setIsServletEngine(boolean isServletEngine) {
    mIsServletEngine = isServletEngine;
  }

  /**
   * Clears the list of all stopped HTTPReceivers.
   */
  public void clearStoppedHTTPReceivers() {
    mStoppedHTTPReceivers.clear();
  }

  /**
   * Returns a list of all HTTPReceivers found in the
   * <code>Configuration</code>.
   *
   * @return a list of all HTTPReceivers found in the
   *         <code>Configuration</code>
   * @throws XException
   *             if something goes wrong
   */
  private List getAllHTTPReceivers() throws XException {
    List returnSet = new Vector();
    if (mIsServletEngine) {
      List systems;
      Configuration config;
      try {
        config = Configuration.getInstance();
        systems = config.getSections(Constants.CHAPTER_SYSTEM);
      } catch (XException e) {
        return null;
      }

      String system = null;
      for (Iterator it = systems.iterator(); it.hasNext();) {
        system = (String) it.next();
        if (isHTTPReceiver(system)) {
          returnSet.add(system);
        }
      }
    }
    return returnSet;
  }

  private boolean isHTTPReceiver(String system) throws XException {
    String receiver = Configuration.getInstance().getValueOptional(
        Constants.CHAPTER_SYSTEM, system, "Receiver");
    if ((receiver != null) && (receiver.startsWith("HTTP"))) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * Indicates whether a HTTPReceiver is stopped
   *
   * @param system
   *            the name of the system
   * @return true if the HTTPReceiver is stopped, false otherwise
   */
  public boolean isHTTPReceiverStopped(String system) {
    return mStoppedHTTPReceivers.contains(system);
  }

  /**
   * Returns the amount of errors, after them a receiver will be stopped The
   * value is read out of the configuration, either a default for the receiver
   * class or a value specific for the current source. If no value is
   * specified in the configuration, a hard coded default is used.
   *
   * @return the amount of errors, after them a receiver will be stopped
   * @param system
   *            the name of the system
   * @param receiverClassName
   *            the name of the receiver class
   */
  public static int getStopAfterErrors(String system, String receiverClassName) {
    int stopAfterErrors = DEFAULT_STOP_AFTER_ERRORS;
    try {
      Configuration config = Configuration.getInstance();
      stopAfterErrors = config.getValueAsIntOptional("System", system,
          "StopAfterErrors");
      if (stopAfterErrors == 0) {
        stopAfterErrors = config.getValueAsInt("Base",
            receiverClassName, "StopAfterErrors");
      }
    } catch (XException e) {
      Trace.warn("Using default for StopAfterErrors: "
          + DEFAULT_STOP_AFTER_ERRORS);
    }

    return stopAfterErrors;
  }
}
TOP

Related Classes of net.sf.xbus.technical.ReceiverThreadManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.