Package net.sf.xbus.technical

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

package net.sf.xbus.technical;

import java.lang.management.ManagementFactory;
import java.util.Iterator;
import java.util.List;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

import net.sf.xbus.admin.jmx.Administrator;
import net.sf.xbus.application.PreProcessor;
import net.sf.xbus.base.core.Constants;
import net.sf.xbus.base.core.TAManager;
import net.sf.xbus.base.core.XException;
import net.sf.xbus.base.core.config.Configuration;
import net.sf.xbus.base.core.trace.Trace;

/**
* <code>ReceiverService</code> runs as a background service and waits for
* incoming messages to process.
* <p>
* At startup, <code>ReceiverService</code> searches for systems, which receiver
* ends with <code>"Thread"</code>. For every found system, a thread is started
* to process the messages. The used receivers must extend the
* {@link net.sf.xbus.technical.ReceiverThreadBase}.
* <p>
*/

public class ReceiverService {
  /**
   * Reference to the Singleton object
   */
  static private ReceiverService mReceiverService = null;

  /**
   * Used for locking during <code>getInstance</code>
   */
  static private final Object classLock = ReceiverService.class;

  /**
   * Indicates if the JMX administration shall be started
   */
  private boolean mStartJMX = false;

  /**
   * Indicates if the systems for processing incoming messages are already
   * started
   */
  private boolean mSystemsStarted = false;

  /**
   * The Watchdog is a thread that checks every few seconds, if all
   * ReceiverThreads are still running.
   */
  private ReceiverServiceWatchdog mWatchdog = null;
  private Thread mWatchdogThread = null;

  /**
   * The constructor should be private to implement the <code>Singleton</code>
   * pattern. But the bootstrapping mechanism needs a public constructor.
   */
  public ReceiverService() {
  }

  /**
   * Returns the one and only instance of the <code>ReceiverService</code>,
   * which implements the <b>Singleton </b> pattern. If the object doesn't
   * exist, it is created.
   *
   * @return the one and only instance of the <code>ReceiverService</code>
   */
  public static ReceiverService getInstance() {
    synchronized (classLock) {
      if (mReceiverService == null) {
        mReceiverService = new ReceiverService();
      }

      return mReceiverService;
    }
  }

  /**
   * Starts all threads to receive messages and for administration.
   *
   * @param insideServletEngine
   *            if true, the ReceiverService is running inside a servlet
   *            engine
   */
  public synchronized void start(boolean insideServletEngine)
      throws XException {
    Trace.always("Entering ReceiverService.start");

    /*
     * The class variable must be set here because an issue with the
     * classloader. Do not remove!
     */
    mReceiverService = this;

    /*
     * Register MBeans
     */
    try {
      MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
      ObjectName name = new ObjectName("xBus:mbean=Administrator");
      Administrator mbean = new Administrator();
      mbs.registerMBean(mbean, name);
    } catch (Exception e) {
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_ADMIN, Constants.PACKAGE_ADMIN_JMX, "0", e);
    }

    startAllSystems();
    ReceiverThreadManager.getInstance().setIsServletEngine(
        insideServletEngine);
    startWatchdog();

    Trace.always("Leaving ReceiverService.start");
  }

  /**
   * Starts all threads to receive messages and for administration. The
   * <code>ReceiverService</code> is running inside a servlet engine.
   */
  public synchronized void startInsideServletEngine() throws XException {
    start(true);
  }

  /**
   * Starts all threads to receive messages and for administration. The
   * <code>ReceiverService</code> is not running inside a servlet engine.
   */
  public synchronized void startWithoutServletEngine() throws XException {
    start(false);
  }

  /**
   * Stops all threads, including the administration threads.
   *
   * @return true if ReceiverService has been stopped
   */
  public synchronized boolean stop() throws XException {
    Trace.always("Stopping ReceiverService...");

    stopWatchdog();
    stopAllSystems();
    TAManager.getInstance().close();
    // if (mStartJMX)
    // {
    // AdministratorJMXServer.stop();
    // }

    Trace.always("ReceiverService stopped");
    return true;
  }

  /**
   * Starts all configured threads to process message for different systems.
   */
  public synchronized void startAllSystems() throws XException {
    Configuration config = Configuration.getInstance();

    PreProcessor.process(PreProcessor.RECEIVER_SERVICE);

    List sections = config.getSections(Constants.CHAPTER_SYSTEM);
    String system = null;
    String receiver = null;
    for (Iterator it = sections.iterator(); it.hasNext();) {
      system = (String) it.next();
      receiver = config.getValueOptional(Constants.CHAPTER_SYSTEM,
          system, "Receiver");
      if ((receiver != null) && (receiver.endsWith("Thread"))) {
        ReceiverThreadManager.getInstance().startReceiverThread(system);
      }
    }

    mSystemsStarted = true;
  }

  /**
   * Stops all threads after processing their current message.
   */
  public synchronized void stopAllSystems() throws XException {
    if (!mSystemsStarted) {
      return;
    }

    ReceiverThreadManager receiverThreadManager = ReceiverThreadManager
        .getInstance();
    /*
     * Demand to stop all running systems
     */
    String systemname;
    for (Iterator i = receiverThreadManager.getRunningReceiverThreads()
        .iterator(); i.hasNext();) {
      systemname = (String) i.next();
      receiverThreadManager.demandStopReceiverThread(systemname);
    }

    /*
     * Wait until all systems have been stopped
     */
    boolean completed = receiverThreadManager.getRunningReceiverThreads()
        .isEmpty();
    while (!completed) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
      }
      completed = receiverThreadManager.getRunningReceiverThreads()
          .isEmpty();
    }

    mSystemsStarted = false;
  }

  public boolean isWatchdogRunning() {
    return ((mWatchdogThread != null) && (mWatchdogThread.isAlive()));
  }

  /**
   * TODO Kommentierung
   */
  private void startWatchdog() {
    mWatchdog = new ReceiverServiceWatchdog();
    mWatchdogThread = new Thread(mWatchdog, "ReceiverServiceWatchdog");
    mWatchdogThread.start();
  }

  /**
   * TODO Kommentierung
   */
  private void stopWatchdog() {
    mWatchdog.stopWatchdog();
  }

}
TOP

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

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.