Package org.huihoo.willow.startup

Source Code of org.huihoo.willow.startup.ContextConfig

//----------------------------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.startup;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;

import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.Container;
import org.huihoo.willow.ContextDeployer;
import org.huihoo.willow.Globals;
import org.huihoo.willow.Lifecycle;
import org.huihoo.willow.LifecycleEvent;
import org.huihoo.willow.LifecycleListener;
import org.huihoo.willow.Logger;
import org.huihoo.willow.core.StandardContext;
import org.huihoo.willow.core.StandardEngine;
import org.huihoo.willow.util.StringManager;
import org.huihoo.workflow.factory.DatabaseFactory;
import org.huihoo.workflow.rules.ScriptContext;
import org.huihoo.workflow.rules.interpretor.JavaInterpretor;
import org.huihoo.workflow.rules.interpretor.ScriptInterpretor;
import org.huihoo.workflow.store.CaseDatabase;
import org.huihoo.workflow.store.SchemaContext;
import org.huihoo.workflow.store.UserDatabase;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;

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 final class ContextConfig implements LifecycleListener
{
  private static Log log = LogFactory.getLog(ContextConfig.class);
  // ----------------------------------------------------- Instance Variables
  /**
   * The Context we are associated with.
   */
  private StandardContext context = null;
  /**
   * The debugging detail level for this component.
   */
  private int debug = 0;
  /**
   * Track any fatal errors during startup configuration processing.
   */
  private boolean ok = false;
  /**
   * The names of applications that we have auto-deployed (to avoid
   * double deployment attempts).
   */
  protected ArrayList deployed = new ArrayList();
  /**
   * Last modified dates of the XPDL's xml files of the XPDLs, keyed by
   * xpdl file name.
   */
  private HashMap xpdlXmlLastModified = new HashMap();
  /**
   * The string resources for this package.
   */
  private static final StringManager sm = StringManager.getManager(Constants.PACKAGE);
  /**
   * The <code>Digester</code> we will use to process org.huihoo.workflow application
   * deployment descriptor files.
   */
  private Digester workflowDigester = null;
  /**
   * The <code>Rule</code> used to parse the org.huihoo.workflow.xml
   */
  private WorkflowRuleSet workflowRuleSet = new WorkflowRuleSet();
  /**
   * Attribute value used to turn on/off XML validation
   */
  private boolean xmlValidation = false;
  /**
   * Attribute value used to turn on/off XML namespace awarenes.
   */
  private boolean xmlNamespaceAware = false;
  // ------------------------------------------------------------- Properties
  /**
   * Return the debugging detail level for this component.
   */
  public int getDebug()
  {
    return (this.debug);
  }
  /**
   * Set the debugging detail level for this component.
   *
   * @param debug The new debugging detail level
   */
  public void setDebug(int debug)
  {
    this.debug = debug;
  }
  // --------------------------------------------------------- Public Methods
  /**
   * Process the START event for an associated Context.
   *
   * @param event The lifecycle event that has occurred
   */
  public void lifecycleEvent(LifecycleEvent event)
  {
    if (event.getType().equals("check"))
    {
      check();
    }
    // Identify the context we are associated with
    try
    {
      context = (StandardContext) event.getLifecycle();
      if (context instanceof StandardContext)
      {
        int contextDebug = ((StandardContext) context).getDebug();
        if (contextDebug > this.debug)
        {
          this.debug = contextDebug;
        }
      }
    }
    catch (ClassCastException e)
    {
      log.error(sm.getString("contextConfig.cce", event.getLifecycle()), e);
      return;
    }
    // Called from ContainerBase.addChild() -> StandardContext.start()
    // Process the event that has occurred
    if (event.getType().equals(Lifecycle.START_EVENT))
    {
      start();
    }
    else
      if (event.getType().equals(Lifecycle.STOP_EVENT))
      {
        stop();
      }
  }
  // -------------------------------------------------------- Private Methods
  /**
   * Process the application configuration file, if it exists.
   */
  private void applicationConfig()
  {
    // Open the application workflow.xml file, if it exists
    ScriptContext servletContext = context.getScriptContext();
    InputStream stream = null;
    InputStream stream_config = null;
    if (servletContext != null)
    {
      stream = servletContext.getResourceAsStream(Constants.ApplicationWorkflowXml);
      stream_config = servletContext.getResourceAsStream(Constants.ApplicationWorkflowXml);
      if (stream == null)
      {
        log.info(sm.getString("contextConfig.applicationMissing") + " " + context);
      }
    }
    if (workflowDigester == null)
    {
      workflowDigester = createWorkflowDigester();
    }
    // Process the application org.huihoo.workflow.xml file
    synchronized (workflowDigester)
    {
      try
      {
        URL workflowURL = servletContext.getResource(Constants.ApplicationWorkflowXml);
        if (workflowURL != null)
        {
          //--------------------entire workflow application-----------------
          InputSource is = new InputSource(workflowURL.toExternalForm());
          is.setByteStream(stream);
          workflowDigester.clear();
          workflowDigester.setDebug(getDebug());
          workflowDigester.setUseContextClassLoader(false);
          workflowDigester.push(context);
          workflowDigester.parse(is);
          //--------------------script config of  workflow application ----------------- 
          Digester configDigester = createConfigDigester();
          is = new InputSource(workflowURL.toExternalForm());
          is.setByteStream(stream_config);
          configDigester.setDebug(getDebug());
          configDigester.setUseContextClassLoader(false);
          configDigester.addCallMethod("workflow-app/script-config/init-param", "addInitParameter", 2);
          configDigester.addCallParam("workflow-app/script-config/init-param/param-name", 0);
          configDigester.addCallParam("workflow-app/script-config/init-param/param-value", 1);
          configDigester.push(servletContext.getScriptConfig());
          configDigester.parse(is);
        }
        //--------------------create database
        UserDatabase userDatabase = null;
        CaseDatabase caseDatabase = null;
        String schemaConextBase = context.findInitParameter(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_SCHEMA_CONTEXT);
        if (schemaConextBase == null)
        {
          schemaConextBase = WorkflowProperties.getSchemaContextFile();
        }
        Hashtable env = new Hashtable();
        String storeFactoryClass = context.findFactoryClass(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_FACTORY_STORE);
        if (storeFactoryClass != null)
        {
          env.put(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_FACTORY_STORE, storeFactoryClass);
        }
        DatabaseFactory dbFactory = DatabaseFactory.newInstance(env);
        env.clear();
       
        Store userStore = context.findStore(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_STORE_USER);
        if (userStore == null)
        {
          userStore = WorkflowProperties.getUserStore();
        }
        env.put(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_STORE_USER, userStore);
        userDatabase = dbFactory.newUserDatabase(env);
        env.clear();
        userDatabase.setWorkflowService(context);
        Store caseStore = context.findStore(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_STORE_CASE);
        if (caseStore == null)
        {
          caseStore = WorkflowProperties.getCaseStore();
        }
        env.put(org.huihoo.workflow.xpdl.parser.Constants.WORKFLOW_STORE_CASE, caseStore);
        caseDatabase = dbFactory.newCaseDatabase(env);
        caseDatabase.setWorkflowService(context);
        SchemaContext schemaContext = new SchemaContext(schemaConextBase);
        if (userDatabase.getSchemaContext() == null)
        {
          userDatabase.setSchemaContext(schemaContext);
        }
        if (caseDatabase.getSchemaContext() == null)
        {
          caseDatabase.setSchemaContext(schemaContext);
        }
        ScriptInterpretor scriptInterpretor = new JavaInterpretor();
        scriptInterpretor.initialize(context.getScriptContext());
        context.setCaseDatabase(caseDatabase);
        context.setUserDatabase(userDatabase);
        context.setScriptInterpretor(scriptInterpretor);
       
        if (context.getEngine().getService().getNamingServer() != null)
        {
          context.getEngine().getService().getNamingServer().addWorkflowService(context);
        }
      }
      catch (SAXParseException e)
      {
        log(sm.getString("contextConfig.applicationParse"), e);
        log(sm.getString("contextConfig.applicationPosition", "" + e.getLineNumber(), "" + e.getColumnNumber()));
        ok = false;
      }
      catch (Exception e)
      {
        log(sm.getString("contextConfig.applicationParse"), e);
        ok = false;
      }
      finally
      {
        try
        {
          if (stream != null)
          {
            stream.close();
          }
          if (stream_config != null)
          {
            stream_config.close();
          }
        }
        catch (IOException e)
        {
          log.error(sm.getString("contextConfig.applicationClose"), e);
        }
        workflowDigester.push(null);
      }
    }
  }
  /**
   * Create (if necessary) and return a Digester configured to process the
   * org.huihoo.workflow application deployment descriptor (org.huihoo.workflow.xml).
   */
  private Digester createWorkflowDigester()
  {
    Digester workflowDigester = DigesterFactory.newDigester(xmlValidation, xmlNamespaceAware, workflowRuleSet);
    return workflowDigester;
  }
  /**
   * Create (if necessary) and return a Digester configured to process the
   * org.huihoo.workflow application deployment descriptor (org.huihoo.workflow.xml).
   */
  private Digester createConfigDigester()
  {
    Digester workflowDigester = DigesterFactory.newDigester(xmlValidation, xmlNamespaceAware, null);
    return workflowDigester;
  }
  private String getEngineBase()
  {
    Container engineC = context.getParent();
    if (engineC instanceof StandardEngine)
    {
      return ((StandardEngine) engineC).getEngineBase();
    }
    return System.getProperty(Globals.PROPS_WILLOW_HOME);
  }
  /**
   * Log a message on the Logger associated with our ServletContext (if any)
   *
   * @param message Message to be logged
   */
  private void log(String message)
  {
    Logger logger = null;
    if (context != null)
    {
      logger = context.getLogger();
    }
    if (logger != null)
    {
      logger.log("ContextConfig[" + context.getName() + "]: " + message);
    }
    else
    {
      log.info(message);
    }
  }
  /**
   * Log a message on the Logger associated with our ServletContext (if any)
   *
   * @param message Message to be logged
   * @param throwable Associated exception
   */
  private void log(String message, Throwable throwable)
  {
    Logger logger = null;
    if (context != null)
    {
      logger = context.getLogger();
    }
    if (logger != null)
    {
      logger.log("ContextConfig[" + context.getName() + "] " + message, throwable);
    }
    else
    {
      log.error(message, throwable);
    }
  }
  private void startNew()
  {
    try
    {
      if (context.getUserDatabase() != null)
      {
        context.getUserDatabase().start();
      }
      if (context.getCaseDatabase() != null)
      {
        context.getCaseDatabase().start();
      }
      if (context.getScriptInterpretor() != null)
      {
        context.getScriptInterpretor().start();
      }
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
  private void stopNew()
  {
    try
    {
      if (context.getUserDatabase() != null)
      {
        context.getUserDatabase().stop();
      }
      if (context.getCaseDatabase() != null)
      {
        context.getCaseDatabase().stop();
      }
      if (context.getScriptInterpretor() != null)
      {
        context.getScriptInterpretor().stop();
      }
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
  /**
   * Process a "start" event for this ServletContext - in background
   */
  private synchronized void start()
  {
    // Called from StandardContext.start()
    log.debug(sm.getString("contextConfig.start"));
    // Process the application org.huihoo.workflow.xml files
    applicationConfig();   
    deployApps();
    startNew();
    ok = true;
  }
  /**
   * Process a "stop" event for this Context.
   */
  private synchronized void stop()
  {
    log.debug(sm.getString("contextConfig.stop"));
    try
    {
      if (context.getEngine().getService().getNamingServer() != null)
      {
        context.getEngine().getService().getNamingServer().removeWorkflowService(context);
      }
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    int i;
    //Removing parameters
    String[] parameters = context.findInitParameters();
    for (i = 0; i < parameters.length; i++)
    {
      context.removeInitParameter(parameters[i]);
    }
    //Removing Store
    String[] stores = context.findStores();
    for (i = 0; i < stores.length; i++)
    {
      context.removeStore(stores[i]);
    }
    //Removing Factory
    String[] factories = context.findFactoryClasses();
    for (i = 0; i < factories.length; i++)
    {
      context.removeFactoryClass(factories[i]);
    }
    stopNew();
    undeployApps();
  }
  /**
   * Undeploy all deployed applications.
   */
  protected void undeployApps()
  {
    if (!(context instanceof ContextDeployer))
    {
      return;
    }
    log.debug(sm.getString("contextConfig.undeploying"));
    ContextDeployer deployer = (ContextDeployer) context;
    String xpdlFiles[] = deployer.findDeployedPackages();
    for (int i = 0; i < xpdlFiles.length; i++)
    {
      log.debug(sm.getString("contextConfig.undeploy", xpdlFiles[i]));
      try
      {
        ((ContextDeployer) context).remove(xpdlFiles[i]);
      }
      catch (Throwable t)
      {
        log.error(sm.getString("contextConfig.undeploy.error", xpdlFiles[i]), t);
      }
    }
    xpdlXmlLastModified.clear();
    deployed.clear();
  }
  /**
     * Deploy applications for any directories or WAR files that are found
     * in our "application root" directory.
     */
  protected void deployApps()
  {
    if (!(context instanceof ContextDeployer))
    {
      return;
    }
    File contextBase = context.getAbsoluteAppBase();
    if (!contextBase.exists() || !contextBase.isDirectory())
    {
      return;
    }
    File xpdlBase = new File(contextBase, "WEB-INF/xpdl");
    String files[] = xpdlBase.list();
    deployXpdls(xpdlBase, files);
  }
  /**
   * Deploy directories.
   */
  protected void deployXpdls(File xpdlBase, String[] files)
  {
    ContextDeployer deployer = (ContextDeployer) context;
    for (int i = 0; i < files.length; i++)
    {
      if (deployed.contains(files[i]))
      {
        continue;
      }
      File xpdl = new File(xpdlBase, files[i]);
      if (xpdl.isFile() && xpdl.getName().endsWith(".xpdl"))
      {
        deployed.add(files[i]);
        // Deploy the application in this directory
        log.debug(sm.getString("contextConfig.deployXPDL", files[i]));
        long t1 = System.currentTimeMillis();
        try
        {
          URL url = new URL("file", null, xpdl.getCanonicalPath());
          deployer.install(xpdl.getName(), url);
        }
        catch (Throwable t)
        {
          log(sm.getString("contextConfig.deployXPDL.error", files[i]), t);
        }
        long t2 = System.currentTimeMillis();
        if ((t2 - t1) > 200)
        {
          log.debug("Deployed " + files[i] + " " + (t2 - t1));
        }
      }
    }
  }
  /**
      * Check deployment descriptors last modified date.
      */
  protected void checkXpdlLastModified()
  {
    if (!(context instanceof ContextDeployer))
    {
      return;
    }
    File contextBase = context.getAbsoluteAppBase();
    if (!contextBase.exists() || !contextBase.isDirectory())
    {
      return;
    }
    ContextDeployer deployer = (ContextDeployer) context;
    String xpdlFiles[] = deployer.findDeployedPackages();
    for (int i = 0; i < xpdlFiles.length; i++)
    {
      String xpdlFileName = xpdlFiles[i];
      File xpdlBase = new File(contextBase, "WEB-INF/xpdl");
      File xpdlFile = new File(xpdlBase, xpdlFileName);
      long newLastModified = xpdlFile.lastModified();
      Long lastModified = (Long) xpdlXmlLastModified.get(xpdlFileName);
      if (lastModified == null)
      {
        xpdlXmlLastModified.put(xpdlFileName, new Long(newLastModified));
      }
      else
      {
        if (lastModified.longValue() != newLastModified)
        {
          if (newLastModified > (lastModified.longValue() + 5000))
          {
            xpdlXmlLastModified.remove(xpdlFileName);
            try
            {
              URL url = new URL("file", null, xpdlFile.getCanonicalPath());
              deployer.remove(xpdlFileName);
              deployer.install(xpdlFileName, url);
            }
            catch (Throwable t)
            {
              log.error(sm.getString("contextConfig.deployXPDL.error", xpdlFile.getName()), t);
            }
          }
          else
          {
            xpdlXmlLastModified.put(xpdlFileName, new Long(newLastModified));
          }
        }
      }
    }
  }
  /**
   * Deploy workflows.
   */
  protected void check()
  {
    if (context.getAutoDeploy())
    {
      deployApps();
      checkXpdlLastModified();
    }
  }
}
TOP

Related Classes of org.huihoo.willow.startup.ContextConfig

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.