//----------------------------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.net.URL;
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.EngineDeployer;
import org.huihoo.willow.Engine;
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.StandardEngine;
import org.huihoo.willow.util.StringManager;
/**
* @author reic
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public final class EngineConfig implements LifecycleListener
{
// ----------------------------------------------------- Instance Variables
private static Log log = LogFactory.getLog(EngineConfig.class);
/**
* The Java class name of the Context configuration class we should use.
*/
protected String configClass = "org.huihoo.willow.startup.ContextConfig";
/**
* The Java class name of the Context implementation we should use.
*/
protected String contextClass = "org.huihoo.willow.core.StandardContext";
/**
* The debugging detail level for this component.
*/
private int debug = 0;
/**
* The names of applications that we have auto-deployed (to avoid
* double deployment attempts).
*/
protected ArrayList deployed = new ArrayList();
/**
* The Engine we are associated with.
*/
private Engine engine = null;
/**
* The string resources for this package.
*/
private static final StringManager sm = StringManager.getManager(Constants.PACKAGE);
/**
* 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 Engine.
*
* @param event The lifecycle event that has occurred
*/
public void lifecycleEvent(LifecycleEvent event)
{
if (event.getType().equals("check"))
{
check();
}
// Identify the engine we are associated with
try
{
engine = (Engine) event.getLifecycle();
if (engine instanceof StandardEngine)
{
int engineDebug = ((StandardEngine) engine).getDebug();
if (engineDebug > this.debug)
{
this.debug = engineDebug;
}
}
}
catch (ClassCastException e)
{
log(sm.getString("engineConfig.cce", event.getLifecycle()), e);
return;
}
// 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
/**
* Log a message on the Logger associated with our Engine (if any)
*
* @param message Message to be logged
*/
private void log(String message)
{
Logger logger = null;
if (engine != null)
logger = engine.getLogger();
if (logger != null)
logger.log("EngineConfig: " + message);
else
System.out.println("EngineConfig: " + message);
}
/**
* Log a message on the Logger associated with our Engine (if any)
*
* @param message Message to be logged
* @param throwable Associated exception
*/
private void log(String message, Throwable throwable)
{
Logger logger = null;
if (engine != null)
logger = engine.getLogger();
if (logger != null)
logger.log("EngineConfig: " + message, throwable);
else
{
System.out.println("EngineConfig: " + message);
System.out.println("" + throwable);
throwable.printStackTrace(System.out);
}
}
/**
* Process a "start" event for this Engine.
*/
private void start()
{
if (debug > 0)
{
log(sm.getString("engineConfig.start"));
}
if (engine.getDeployOnStartup())
{
deployApps();
}
}
/**
* Process a "stop" event for this Engine.
*/
private void stop()
{
if (debug > 0)
{
log(sm.getString("engineConfig.stop"));
}
}
/**
* Undeploy all deployed applications.
*/
protected void undeployApps()
{
if (!(engine instanceof EngineDeployer))
{
return;
}
log.debug(sm.getString("engineConfig.undeploying"));
String contextPaths[] = ((EngineDeployer) engine).findDeployedApps();
for (int i = 0; i < contextPaths.length; i++)
{
log.debug(sm.getString("engineConfig.undeploy", contextPaths[i]));
try
{
((EngineDeployer) engine).remove(contextPaths[i]);
}
catch (Throwable t)
{
log.error(sm.getString("engineConfig.undeploy.error", contextPaths[i]), t);
}
}
deployed.clear();
}
/**
* Deploy webapps.
*/
protected void check()
{
if (engine.getAutoDeploy())
{
// Deploy apps if the Engine allows auto deploying
deployApps();
}
}
/**
* Deploy applications for any directories or WAR files that are found
* in our "application root" directory.
*/
protected void deployApps()
{
if (!(engine instanceof EngineDeployer))
{
return;
}
File engineBase = engine.getAbsoluteEngineBase();
if (!engineBase.exists() || !engineBase.isDirectory())
{
return;
}
String files[] = engineBase.list();
deployDirectories(engineBase, files);
}
/**
* Deploy directories.
*/
protected void deployDirectories(File appBase, String[] files)
{
for (int i = 0; i < files.length; i++)
{
String contextName = files[i];
if (deployed.contains(files[i]))
{
if (engine.findChild(contextName) != null)
{
engine.findChild(contextName).backgroundProcess();
}
continue;
}
File dir = new File(appBase, files[i]);
if (!dir.exists() || !dir.isDirectory() || !dir.canRead())
{
continue;
}
deployed.add(files[i]);
// Make sure there is an application configuration directory
// This is needed if the Context appBase is the same as the
// web server document root to make sure only web applications
// are deployed and not directories for web space.
File xpdlInf = new File(dir, "/WEB-INF");
if (!xpdlInf.exists() || !xpdlInf.isDirectory() || !xpdlInf.canRead())
{
continue;
}
// Calculate the context path and make sure it is unique
if (engine.findChild(contextName) != null)
{
continue;
}
// Deploy the application in this directory
if (log.isDebugEnabled())
{
log.debug(sm.getString("engineConfig.deployDir", files[i]));
}
long t1 = System.currentTimeMillis();
try
{
URL url = new URL("file", null, dir.getCanonicalPath());
((EngineDeployer) engine).install(contextName, url);
}
catch (Throwable t)
{
log.error(sm.getString("engineConfig.deployDir.error", files[i]), t);
}
long t2 = System.currentTimeMillis();
if ((t2 - t1) > 200)
{
log.debug("Deployed " + files[i] + " " + (t2 - t1));
}
}
}
}