Package org.huihoo.willow.core

Source Code of org.huihoo.willow.core.StandardContext$ContextBackgroundProcessor

//----------------------------BEGIN LICENSE----------------------------
/*
* Willow : the Open Source WorkFlow Project
* Distributable under GNU LGPL license by gun.org
*
* Copyright (C) 2004-2010 huihoo.org
* Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com>
*
* ====================================================================
* Project Homepage : http://www.huihoo.org/willow
* Source Forge     : http://sourceforge.net/projects/huihoo
* Mailing list     : willow@lists.sourceforge.net
*/
//----------------------------END  LICENSE-----------------------------
package org.huihoo.willow.core;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.Container;
import org.huihoo.willow.Context;
import org.huihoo.willow.ContextDeployer;
import org.huihoo.willow.Engine;
import org.huihoo.willow.Globals;
import org.huihoo.willow.Lifecycle;
import org.huihoo.willow.LifecycleException;
import org.huihoo.willow.Loader;
import org.huihoo.willow.loader.WorkflowLoader;
import org.huihoo.workflow.WorkflowException;
import org.huihoo.workflow.runtime.WorkflowContext;
import org.huihoo.workflow.rules.ScriptContext;
import org.huihoo.workflow.xpdl.WorkflowPackage;

import org.huihoo.workflow.impl.monitor.EventMonitorThread;
import org.huihoo.workflow.impl.monitor.LitterCleaner;
import com.zosatapo.commons.store.Store;

/**
* @author reic
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class StandardContext extends WorkflowServiceBase implements ContextDeployer, Context, Serializable
{
  private transient Log log = LogFactory.getLog(StandardContext.class);

  // ----------------------------------------------------------- Constructors

  /**
   * Create a new StandardContext component with the default basic Valve.
   */
  public StandardContext()
  {
    super();
  }

  // ----------------------------------------------------- Instance Variables

  /**
   * The  Engine to which this Context is a child.
   */
  protected Engine engine = null;

  /**
   * The ScriptContext implementation associated with this Context.
   */
  private transient ApplicationContext scriptContext = null;

  /**
   * Compiler classpath to use.
   */
  private String compilerClasspath = null;

  /**
   * The "follow standard delegation model" flag that will be used to
   * configure our ClassLoader.
   */
  private boolean delegate = false;

  /**
    * The auto deploy flag for this Context.
    */
  private boolean autoDeploy = true;

  /**
  * The display name of this context.
  */
  private String displayName = null;

  /**
   * The document root for this context.
   */
  private String appBase = null;

  /**
   * The descriptive information string for this implementation.
   */
  private static final String info = "org.huohoo.core.StandardContext/1.0";

  /**
   * The reloadable flag for this context.
   */
  private boolean reloadable = false;

  /**
   * The pathname to the work directory for this context (relative to
   * the server's home if not absolute).
   */
  private String workDir = null;

  /**
   * The <code>EngineDeployer</code> to whom we delegate application
   * deployment requests.
   */
  private ContextDeployer deployer = null;

  /**
   * The context initialization parameters for this context,
   * keyed by name.
   */
  private HashMap parameters = new HashMap();

  /**
   * The context initialization stores for this context,
   * keyed by store-key.
   */
  private HashMap stores = new HashMap();

  /**
   * The context initialization factory for this context,
   * keyed by factory-key.
   */
  private HashMap factories = new HashMap();

  /**
   * The application available flag for this org.huihoo.workflow context.
   */
  private boolean available = false;

  /**
   * The request processing pause flag (while reloading occurs)
   */
  private boolean paused = false;

  // ----------------------------------------------------- org.huihoo.workflow context Properties

  /**
   * Return the "follow standard delegation model" flag used to configure
   * our ClassLoader.
   */
  public boolean getDelegate()
  {

    return (this.delegate);

  }

  /**
   * Set the "follow standard delegation model" flag used to configure
   * our ClassLoader.
   *
   * @param delegate The new flag
   */
  public void setDelegate(boolean delegate)
  {

    boolean oldDelegate = this.delegate;
    this.delegate = delegate;
    support.firePropertyChange("delegate", new Boolean(oldDelegate), new Boolean(this.delegate));

  }

  /**
   * Return the <code>Engine</code> with which we are associated (if any).
   */
  public Engine getEngine()
  {
    return (engine);
  }

  /**
   * Set the <code>Engine</code> with which we are associated (if any).
   *
   * @param engine The engine that owns this Context
   */
  public void setEngine(Engine engine)
  {
    super.setParent(engine);

    Engine oldEngine = this.engine;
    this.engine = engine;
    support.firePropertyChange("engine", oldEngine, this.engine);
  }

  /**
   * Return the display name of this context.
   */
  public String getDisplayName()
  {

    return (this.displayName);

  }

  /**
   * Return the compiler classpath.
   */
  public String getCompilerClasspath()
  {
    return compilerClasspath;
  }

  /**
   * Set the compiler classpath.
   */
  public void setCompilerClasspath(String compilerClasspath)
  {
    this.compilerClasspath = compilerClasspath;
  }

  /**
   * Set the display name of this context.
   *
   * @param displayName The new display name
   */
  public void setDisplayName(String displayName)
  {

    String oldDisplayName = this.displayName;
    this.displayName = displayName;
    support.firePropertyChange("displayName", oldDisplayName, this.displayName);
  }

  /**
   * Return the document root for this Context.  This can be an absolute
   * pathname, a relative pathname
   */
  public String getAppBase()
  {
    return (this.appBase);
  }

  /**
   * Return the document root for this Context.
   */
  public File getAbsoluteAppBase()
  {
    String absolute_appBase = getAppBase();
    File absolute_appBaseFile = new File(absolute_appBase);

    if (!absolute_appBaseFile.isAbsolute())
    {
      Engine parent = (Engine) this.getParent();
      absolute_appBaseFile = new File(parent.getAbsoluteEngineBase(), absolute_appBase);
    }

    return (absolute_appBaseFile);
  }

  /**
   * Set the document root for this org.huihoo.workflow context.  This can be an absolute
   * pathname, a relative pathname
   *
   * @param docBase The new document root
   */
  public void setAppBase(String appBase)
  {

    this.appBase = appBase;

  }

  /**
   * Return descriptive information about this Container implementation and
   * the corresponding version number, in the format
   * <code>&lt;description&gt;/&lt;version&gt;</code>.
   */
  public String getInfo()
  {

    return (info);

  }

  /**
   * Set the Loader with which this org.huihoo.workflow context is associated.
   *
   * @param loader The newly associated loader
   */
  public synchronized void setLoader(Loader loader)
  {

    super.setLoader(loader);

  }

  /**
   * Return the reloadable flag for this context.
   */
  public boolean getReloadable()
  {

    return (this.reloadable);

  }

  /**
   * Set the reloadable flag for this context.
   *
   * @param reloadable The new reloadable flag
   */
  public void setReloadable(boolean reloadable)
  {

    boolean oldReloadable = this.reloadable;
    this.reloadable = reloadable;
    support.firePropertyChange("reloadable", new Boolean(oldReloadable), new Boolean(this.reloadable));

  }

  /**
   * Return the value of the auto deploy flag.  If true, it indicates that
   * this xpdl will be dynamically deployed.
   */
  public boolean getAutoDeploy()
  {

    return (this.autoDeploy);

  }

  /**
   * Set the auto deploy flag value for this Context.
   *
   * @param autoDeploy The new auto deploy flag
   */
  public void setAutoDeploy(boolean autoDeploy)
  {

    boolean oldAutoDeploy = this.autoDeploy;
    this.autoDeploy = autoDeploy;
    support.firePropertyChange("autoDeploy", oldAutoDeploy, this.autoDeploy);

  }

  /**
   * Return the servlet context for which this Context is a facade.
   */
  public ScriptContext getScriptContext()
  {

    if (scriptContext == null)
    {
      scriptContext = new ApplicationContext(getBasePath(), this);
    }
    return (scriptContext);

  }

  // ------------------------------------------------------ Public Properties

  /** Get the absolute path to the work dir.
   *  To avoid duplication.
   *
   * @return
   */
  public String getWorkPath()
  {
    File workDir = new File(getWorkDir());
    if (!workDir.isAbsolute())
    {
      File willowHome = new File(System.getProperty(Globals.PROPS_WILLOW_HOME));
      String willowHomePath = null;
      try
      {
        willowHomePath = willowHome.getCanonicalPath();
        workDir = new File(willowHomePath, getWorkDir());
      }
      catch (IOException e)
      {
      }
    }
    return workDir.getAbsolutePath();
  }

  /**
   * Return the work directory for this org.huihoo.workflow context.
   */
  public String getWorkDir()
  {

    return (this.workDir);

  }

  /**
   * Set the work directory for this org.huihoo.workflow context.
   *
   * @param workDir The new work directory
   */
  public void setWorkDir(String workDir)
  {

    this.workDir = workDir;

    if (started)
    {
      postWorkDirectory();
    }

  }

  /**
   * Return the application available flag for this org.huihoo.workflow context.
   */
  public boolean getAvailable()
  {

    return (this.available);

  }

  /**
   * Set the application available flag for this org.huihoo.workflow context.
   *
   * @param available The new application available flag
   */
  public void setAvailable(boolean available)
  {

    boolean oldAvailable = this.available;
    this.available = available;
    support.firePropertyChange("available", new Boolean(oldAvailable), new Boolean(this.available));

  }

  /**
     * Add a new context initialization parameter.
     *
     * @param name Name of the new parameter
     * @param value Value of the new  parameter
     *
     * @exception IllegalArgumentException if the name or value is missing,
     *  or if this context initialization parameter has already been
     *  registered
     */
  public void addInitParameter(String name, String value)
  {
    // Validate the proposed context initialization parameter
    if ((name == null) || (value == null))
      throw new IllegalArgumentException(sm.getString("standardContext.parameter.required"));
    if (parameters.get(name) != null)
      throw new IllegalArgumentException(sm.getString("standardContext.parameter.duplicate", name));

    // Add this parameter to our defined set
    synchronized (parameters)
    {
      parameters.put(name, value);
    }

  }

  /**
   * Return the value for the specified context initialization
   * parameter name, if any; otherwise return <code>null</code>.
   *
   * @param name Name of the parameter to return
   */
  public String findInitParameter(String name)
  {

    synchronized (parameters)
    {
      return ((String) parameters.get(name));
    }

  }

  /**
   * Return the names of all defined context initialization parameters
   * for this Context.  If no parameters are defined, a zero-length
   * array is returned.
   */
  public String[] findInitParameters()
  {

    synchronized (parameters)
    {
      String results[] = new String[parameters.size()];
      return ((String[]) parameters.keySet().toArray(results));
    }

  }
  public void removeInitParameter(String name)
  {

    synchronized (parameters)
    {
      parameters.remove(name);
    }

  }

  public void addFactoryClass(String name, String value)
  {
    // Validate the proposed context initialization parameter
    if ((name == null) || (value == null))
      throw new IllegalArgumentException(sm.getString("standardContext.factory.required"));
    if (factories.get(name) != null)
      throw new IllegalArgumentException(sm.getString("standardContext.factory.duplicate", name));

    // Add this parameter to our defined set
    synchronized (factories)
    {
      factories.put(name, value);
    }

  }

  public String findFactoryClass(String name)
  {

    synchronized (factories)
    {
      return ((String) factories.get(name));
    }

  }

  public String[] findFactoryClasses()
  {

    synchronized (factories)
    {
      String results[] = new String[factories.size()];
      return ((String[]) factories.keySet().toArray(results));
    }

  }
  public void removeFactoryClass(String name)
  {

    synchronized (factories)
    {
      factories.remove(name);
    }

  }

  public void addStore(String name, Store value)
  {
    // Validate the proposed context initialization parameter
    if ((name == null) || (value == null))
      throw new IllegalArgumentException(sm.getString("standardContext.store.required"));
    if (stores.get(name) != null)
      throw new IllegalArgumentException(sm.getString("standardContext.store.duplicate", name));

    // Add this parameter to our defined set
    synchronized (stores)
    {
      stores.put(name, value);
    }
  }

  public Store findStore(String name)
  {

    synchronized (stores)
    {
      return ((Store) stores.get(name));
    }

  }

  public String[] findStores()
  {

    synchronized (stores)
    {
      String results[] = new String[stores.size()];
      return ((String[]) stores.keySet().toArray(results));
    }

  }

  public void removeStore(String name)
  {

    synchronized (stores)
    {
      stores.remove(name);
    }
  }

  /**
   * Reload this context, if reloading is supported.
   * <p>
   * <b>IMPLEMENTATION NOTE</b>:  This method is designed to deal with
   * reloads required by changes to classes in the underlying repositories
   * of our class loader.  It does not handle changes to the context
   * deployment descriptor.  If that has occurred, you should stop this
   * org.huihoo.workflow context and create (and start) a new org.huihoo.workflow context instance instead.
   *
   * @exception IllegalStateException if the <code>reloadable</code>
   *  property is set to <code>false</code>.
   */
  public synchronized void reload()
  {

    // Validate our current component state
    if (!started)
    {
      throw new IllegalStateException(sm.getString("containerBase.notStarted", logName()));
    }

    // Make sure reloading is enabled
    if (!reloadable)
    {
      throw new IllegalStateException(sm.getString("standardContext.notReloadable"));
    }

    log.info(sm.getString("standardContext.reloadingStarted"));

    // Stop accepting requests temporarily
    setPaused(true);

    try
    {
      stop();
    }
    catch (LifecycleException e)
    {
      log.error(sm.getString("standardContext.stoppingContext"), e);
    }

    try
    {
      start();
    }
    catch (LifecycleException e)
    {
      log.error(sm.getString("standardContext.startingContext"), e);
    }

    setPaused(false);

  }

  // --------------------------------------------------------- Public Methods

  /**
   * Start this org.huihoo.workflow context component.
   *
   * @exception LifecycleException if a startup error occurs
   */
  public synchronized void start() throws LifecycleException
  {
    if (started)
    {
      log.info(sm.getString("standardContext.alreadyStarted", logName()));
      return;
    }

    String logName = "willow." + getParent().getName() + "." + getName() + ".Context";
    log = LogFactory.getLog(logName);

    log.debug("Starting " + logName);

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

    setAvailable(false);

    boolean ok = true;

    if (getLoader() == null)
    {
      ClassLoader parent = null;
      log.debug("Configuring non-privileged default Loader");
      parent = getParentClassLoader();
      WorkflowLoader webappLoader = new WorkflowLoader(parent);
      webappLoader.setDelegate(getDelegate());
      setLoader(webappLoader);
    }

    // Post work directory
    postWorkDirectory();

    // Standard container startup
    log.debug("Processing standard container startup");

    if (ok)
    {
      started = true;

      // Start our subordinate components, if any
      if ((loader != null) && (loader instanceof Lifecycle))
      {
        ((Lifecycle) loader).start();
      }
      if ((logger != null) && (logger instanceof Lifecycle))
      {
        ((Lifecycle) logger).start();
      }

      //MUST be called before lifecycle.fireLifecycleEvent(START_EVENT, null);
      scriptContext.setAttribute(Globals.ATTR_CLASS_LOADER, getLoader().getClassLoader());

      // Notify our interested LifecycleListeners
      lifecycle.fireLifecycleEvent(START_EVENT, null);

      // Start ContainerBackgroundProcessor thread
      threadStart();
    }

    // Set available status depending upon startup success
    if (ok)
    {
      log.debug("Starting completed");
      setAvailable(true);
    }
    else
    {
      log.error(sm.getString("standardContext.startFailed"));
      try
      {
        stop();
      }
      catch (Throwable t)
      {
        log.error(sm.getString("standardContext.startCleanup"), t);
      }
      setAvailable(false);
    }

    if (ok)
    {
      // Notify our interested LifecycleListeners
      lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
    }

    // Close all JARs right away to avoid always opening a peak number
    // of files on startup
    if (getLoader() instanceof WorkflowLoader)
    {
      ((WorkflowLoader) getLoader()).closeJARs(true);
    }

    // Reinitializing if something went wrong
    if (!ok && started)
    {
      stop();
    }

  }

  /**
   * Stop this org.huihoo.workflow context component.
   *
   * @exception LifecycleException if a shutdown error occurs
   */
  public synchronized void stop() throws LifecycleException
  {

    // Validate and update our current component state
    if (!started)
    {
      throw new LifecycleException(sm.getString("containerBase.notStarted", logName()));
    }

    log.debug("Stopping");

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);

    // Mark this application as unavailable while we shut down
    setAvailable(false);

    // Stop ContainerBackgroundProcessor thread
    threadStop();

    // Normal container shutdown processing
    log.debug("Processing standard container shutdown");

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    started = false;

    try
    {
      if ((logger != null) && (logger instanceof Lifecycle))
      {
        ((Lifecycle) logger).stop();
      }
      if ((loader != null) && (loader instanceof Lifecycle))
      {
        ((Lifecycle) loader).stop();
      }
    }
    finally
    {
    }

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
    log.debug("Stopping complete");
  }

  /**
   * Return a String representation of this component.
   */
  public String toString()
  {

    StringBuffer sb = new StringBuffer();
    if (getParent() != null)
    {
      sb.append(getParent().toString());
      sb.append(".");
    }
    sb.append("StandardContext[");
    sb.append(getName());
    sb.append("]");
    return (sb.toString());

  }

  /**
   * Execute a periodic task, such as reloading, etc. This method will be
   * invoked inside the classloading context of this container. Unexpected
   * throwables will be caught and logged.
   */
  public void backgroundProcess()
  {

    if (!started)
    {
      return;
    }

    if (getLoader() != null)
    {
      if (reloadable && (getLoader().modified()))
      {
        try
        {
          Thread.currentThread().setContextClassLoader(StandardContext.class.getClassLoader());
          reload();
        }
        finally
        {
          if (getLoader() != null)
          {
            Thread.currentThread().setContextClassLoader(getLoader().getClassLoader());
          }
        }
      }
      if (getLoader() instanceof WorkflowLoader)
      {
        ((WorkflowLoader) getLoader()).closeJARs(false);
      }
    }

    LitterCleaner.clear(this);

    lifecycle.fireLifecycleEvent("check", null);
  }

  // ------------------------------------------------------ Protected Methods

  /**
   * Return a File object representing the base directory for the
   * entire servlet container (i.e. the Engine container if present).
   */
  protected File engineBaseFile()
  {
    StandardEngine eng = (StandardEngine) this.getParent();
    String engineBase = eng.getEngineBase();

    File baseFile = new File(engineBase);

    if (!baseFile.isAbsolute())
    {
      baseFile = new File(System.getProperty(Globals.PROPS_WILLOW_HOME), engineBase);
    }

    return (baseFile);
  }

  /**
   * Return the request processing paused flag for this org.huihoo.workflow context.
   */
  public boolean getPaused()
  {

    return (this.paused);

  }

  /**
   * Set the appropriate context attribute for our work directory.
   */
  private void postWorkDirectory()
  {

    // Acquire (or calculate) the work directory path
    String workDir = getWorkDir();
    if (workDir == null)
    {
      // Retrieve our parent (normally a engine) name
      String engineName = null;
      String engineWorkDir = null;

      Container parentEngine = getParent();
      if (parentEngine != null)
      {
        engineName = parentEngine.getName();
        engineWorkDir = ((StandardEngine) parentEngine).getWorkDir();
      }

      if ((engineName == null) || (engineName.length() < 1))
      {
        engineName = "_";
      }

      String temp = getName();
      if (temp.startsWith("/"))
      {
        temp = temp.substring(1);
      }

      temp = temp.replace('/', '_');
      temp = temp.replace('\\', '_');
      if (temp.length() < 1)
      {
        temp = "_";
      }

      if (engineWorkDir != null)
      {
        workDir = engineWorkDir + File.separator + temp;
      }
      else
      {
        workDir =
          org.huihoo.willow.startup.Constants.WORK_DIRECTORY + File.separator + engineName + File.separator + temp;
      }
      setWorkDir(workDir);
    }

    // Create this directory if necessary
    File dir = new File(workDir);
    if (!dir.isAbsolute())
    {
      File willowHome = new File(System.getProperty(Globals.PROPS_WILLOW_HOME));
      String willowHomePath = null;
      try
      {
        willowHomePath = willowHome.getCanonicalPath();
        dir = new File(willowHomePath, workDir);
      }
      catch (IOException e)
      {
      }
    }
    dir.mkdirs();

    getScriptContext().setAttribute(Globals.ATTR_WORK_DIR, dir);
    if (getScriptContext() instanceof ApplicationContext)
    {
      ((ApplicationContext) getScriptContext()).setAttributeReadOnly(Globals.ATTR_WORK_DIR);
    }
  }

  /**
   * Set the request processing paused flag for this org.huihoo.workflow context.
   *
   * @param paused The new request processing paused flag
   */
  private void setPaused(boolean paused)
  {

    this.paused = paused;

  }

  /**
   * Get base path (full path name).
   */
  private String getBasePath()
  {
    String appBase = null;

    File file = new File(getAppBase());
    if (!file.isAbsolute())
    {
      appBase = new File(engineBaseFile(), getAppBase()).getPath();
    }
    else
    {
      appBase = file.getPath();
    }
    return appBase;
  }

  // ------------------------------------------------------- ContextDeployer Methods

  public void install(String xpdlFileName, URL xpdlFileURL) throws WorkflowException
  {
    getDeployer().install(xpdlFileName, xpdlFileURL);
  }

  public WorkflowPackage findDeployedPackage(String xpdlFileName)
  {

    return (getDeployer().findDeployedPackage(xpdlFileName));

  }

  public String[] findDeployedPackages()
  {

    return (getDeployer().findDeployedPackages());

  }

  public void remove(String xpdlFileName) throws WorkflowException
  {

    getDeployer().remove(xpdlFileName);

  }
  // ------------------------------------------------------ Protected Methods

  static String STANDARD_CONTEXT_DEPLOYER = "org.huihoo.willow.core.StandardContextDeployer";

  public ContextDeployer getDeployer()
  {
    if (deployer != null)
    {
      return deployer;
    }

    log.info("Create Context deployer for direct deployment ");

    try
    {
      Class c = Class.forName(STANDARD_CONTEXT_DEPLOYER);
      deployer = (ContextDeployer) c.newInstance();
      Method m = c.getMethod("setContext", new Class[] { Context.class });
      m.invoke(deployer, new Object[] { this });
    }
    catch (Throwable t)
    {
      log.error("Error creating deployer ", t);
    }
    return deployer;
  }

  public void setDeployer(ContextDeployer d)
  {
    this.deployer = d;
  }

  //-------------------------------------------------------------
  // WorkflowService  Implementation
  //-------------------------------------------------------------
  public WorkflowContext getWorkflowContext()
  {
    if (scriptContext == null)
    {
      scriptContext = new ApplicationContext(getBasePath(), this);
    }
    return (scriptContext);
  }

  protected void threadStart()
  {
    if (thread == null && backgroundProcessorDelay > 0)
    {
      threadDone = false;
      String threadName = "ContextBackgroundProcessor[" + toString() + "]";
      thread = new Thread(new ContextBackgroundProcessor(), threadName);
      thread.setDaemon(true);
      thread.start();
    }

    if (envent_threads.size() > 0)
    {
      String[] xpdlFileNames = findDeployedPackages();
      if (xpdlFileNames != null && xpdlFileNames.length > 0)
      {
        for (int i = 0; i < xpdlFileNames.length; ++i)
        {
          WorkflowPackage workflowPackage = findDeployedPackage(xpdlFileNames[i]);
          EventMonitorThread eventMonitorThread = this.getEventMonitorThread(workflowPackage);
          eventMonitorThread.start();
        }
      }
    }
    else
    {
      //has been stopped

      String[] xpdlFileNames = findDeployedPackages();
      if (xpdlFileNames != null && xpdlFileNames.length > 0)
      {
        for (int i = 0; i < xpdlFileNames.length; ++i)
        {
          WorkflowPackage workflowPackage = findDeployedPackage(xpdlFileNames[i]);
          String threadName = "EventMonitorThread[" + toString() + " - " + workflowPackage.getName() + "]";
          EventMonitorThread eventMonitorThread = new EventMonitorThread(threadName);
          eventMonitorThread.setDaemon(true);
          eventMonitorThread.start();
          this.putEventMonitorThread(workflowPackage, eventMonitorThread);
        }
      }

    }
  }

  protected void threadStop()
  {
    if (thread != null)
    {
      threadDone = true;
      thread.interrupt();
      thread = null;
    }

    if (envent_threads.size() > 0)
    {
      String[] xpdlFileNames = findDeployedPackages();
      if (xpdlFileNames != null && xpdlFileNames.length > 0)
      {
        for (int i = 0; i < xpdlFileNames.length; ++i)
        {
          WorkflowPackage workflowPackage = findDeployedPackage(xpdlFileNames[i]);

          EventMonitorThread eventMonitorThread = this.getEventMonitorThread(workflowPackage);
          eventMonitorThread.interrupt();
          try
          {
            eventMonitorThread.join();
          }
          catch (InterruptedException e)
          {
            ;
          }
          this.removeEventMonitorThread(workflowPackage);
          eventMonitorThread = null;
        }
      }
    }
  }
  // -------------------------------------- ContextrExecuteDelay Inner Class
  /**
   * Private thread class to invoke the backgroundProcess method
   * of this container and its children after a fixed delay.
   */
  protected class ContextBackgroundProcessor implements Runnable
  {
    public void run()
    {
      while (!threadDone)
      {
        try
        {
          Thread.sleep(backgroundProcessorDelay * 1000L);
        }
        catch (InterruptedException e)
        {
          ;
        }
        if (!threadDone)
        {
          Container container = StandardContext.this;
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          if (parent.getLoader() != null)
          {
            cl = container.getLoader().getClassLoader();
          }
          try
          {
            if (container.getLoader() != null)
            {
              Thread.currentThread().setContextClassLoader(container.getLoader().getClassLoader());
            }
            container.backgroundProcess();
          }
          catch (Throwable t)
          {
            log.error("Exception invoking periodic operation: ", t);
          }
          finally
          {
            Thread.currentThread().setContextClassLoader(cl);
          }
        }
      }
    }
  }
}
TOP

Related Classes of org.huihoo.willow.core.StandardContext$ContextBackgroundProcessor

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.