//----------------------------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.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.Engine;
import org.huihoo.willow.Lifecycle;
import org.huihoo.willow.LifecycleException;
import org.huihoo.willow.LifecycleListener;
import org.huihoo.willow.NamingServer;
import org.huihoo.willow.Provider;
import org.huihoo.willow.Server;
import org.huihoo.willow.ServerFactory;
import org.huihoo.willow.Service;
import org.huihoo.willow.bootstrap.J2EEServerFactory;
import org.huihoo.willow.util.LifecycleSupport;
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 class StandardService implements Lifecycle, Service
{
private static Log log = LogFactory.getLog(StandardService.class);
// ----------------------------------------------------- Instance Variables
/**
* The set of Providers associated with this Service.
*/
private Provider providers[] = new Provider[0];
/**
* The Engine associated with this Service.
*/
private Engine engine = null;
/**
* The NamingServer associated with this Service.
*/
private NamingServer namingServer = null;
/**
* The debugging detail level for this component.
*/
private int debug = 0;
/**
* Descriptive information about this component implementation.
*/
private static final String info = "org.huohoo.willow.core.StandardService/1.0";
/**
* Has this component been initialized?
*/
private boolean initialized = false;
/**
* The name of this service.
*/
private String name = null;
/**
* The lifecycle event support for this component.
*/
private LifecycleSupport lifecycle = new LifecycleSupport(this);
/**
* The string manager for this package.
*/
//private static final StringManager sm = StringManager.getManager(WorkflowClient.PACKAGE);
private static final StringManager sm = StringManager.getManager(Constants.PACKAGE);
/**
* The <code>Server</code> that owns this Service, if any.
*/
private Server server = null;
/**
* Has this component been started?
*/
private boolean started = false;
/**
* The property change support for this component.
*/
protected PropertyChangeSupport support = new PropertyChangeSupport(this);
// ------------------------------------------------------------- Properties
/**
* Return the <code>Engine</code> that handles requests for all
* <code>Providers</code> associated with this Service.
*/
public Engine getEngine()
{
return (this.engine);
}
/**
* Set the <code>Engine</code> that handles requests for all
* <code>Providers</code> associated with this Service.
*
* @param engine The new Engine
*/
public void setEngine(Engine engine)
{
Engine oldEngine = this.engine;
if ((oldEngine != null))
{
oldEngine.setService((Service)null);
}
this.engine = engine;
if ((this.engine != null) )
{
this.engine.setService(this);
}
if (started && (this.engine != null) && (this.engine instanceof Lifecycle))
{
try
{
((Lifecycle) this.engine).start();
}
catch (LifecycleException e)
{
;
}
}
if (started && (oldEngine != null) && (oldEngine instanceof Lifecycle))
{
try
{
((Lifecycle) oldEngine).stop();
}
catch (LifecycleException e)
{
;
}
}
// Report this property change to interested listeners
support.firePropertyChange("engine", oldEngine, this.engine);
}
/**
* Return the <code>Engine</code> that associated with this Service.
*/
public synchronized NamingServer getNamingServer()
{
return this.namingServer;
}
/**
* Set the <code>NamingServer</code> that associated with this Service.
*
* @param container The new NamingServer
*/
public void setNamingServer(NamingServer namingServer)
{
NamingServer oldNamingServer = this.namingServer;
if ((oldNamingServer != null))
oldNamingServer.setService((Service)null);
this.namingServer = namingServer;
if ((this.namingServer != null) )
{
this.namingServer.setService(this);
}
if (started && (this.namingServer != null) && (this.namingServer instanceof Lifecycle))
{
try
{
((Lifecycle) this.namingServer).start();
}
catch (LifecycleException e)
{
;
}
}
if (started && (oldNamingServer != null) && (oldNamingServer instanceof Lifecycle))
{
try
{
((Lifecycle) oldNamingServer).stop();
}
catch (LifecycleException e)
{
;
}
}
// Report this property change to interested listeners
support.firePropertyChange("serviceContextImpl", oldNamingServer, this.namingServer);
}
/**
* Return the debugging detail level of this component.
*/
public int getDebug()
{
return (this.debug);
}
/**
* Set the debugging detail level of this component.
*
* @param debug The new debugging detail level
*/
public void setDebug(int debug)
{
this.debug = debug;
}
/**
* Return descriptive information about this Service implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo()
{
return (this.info);
}
/**
* Return the name of this Service.
*/
public String getName()
{
return (this.name);
}
/**
* Set the name of this Service.
*
* @param name The new service name
*/
public void setName(String name)
{
this.name = name;
}
/**
* Return the <code>Server</code> with which we are associated (if any).
*/
public Server getServer()
{
return (this.server);
}
/**
* Set the <code>Server</code> with which we are associated (if any).
*
* @param server The server that owns this Service
*/
public void setServer(Server server)
{
this.server = server;
}
// --------------------------------------------------------- Public Methods
/**
* Add a new Provider to the set of defined Providers, and associate it
* with this Service's Container.
*
* @param connector The Provider to be added
*/
public void addProvider(Provider provider)
{
synchronized (provider)
{
provider.setEngine(this.engine);
provider.setService(this);
Provider results[] = new Provider[providers.length + 1];
System.arraycopy(providers, 0, results, 0, providers.length);
results[providers.length] = provider;
providers = results;
if (initialized)
{
try
{
provider.initialize();
}
catch (LifecycleException e)
{
e.printStackTrace(System.err);
}
}
if (started && (provider instanceof Lifecycle))
{
try
{
((Lifecycle) provider).start();
}
catch (LifecycleException e)
{
e.printStackTrace(System.err);
}
}
// Report this property change to interested listeners
support.firePropertyChange("provider", null, provider);
}
}
/**
* Add a property change listener to this component.
*
* @param listener The listener to add
*/
public void addPropertyChangeListener(PropertyChangeListener listener)
{
support.addPropertyChangeListener(listener);
}
/**
* Find and return the set of Providers associated with this Service.
*/
public Provider[] findProviders()
{
return (providers);
}
/**
* Remove the specified Provider from the set associated from this
* Service. The removed Provider will also be disassociated from our
* Container.
*
* @param Provider The Provider to be removed
*/
public void removeProvider(Provider provider)
{
synchronized (providers)
{
int j = -1;
for (int i = 0; i < providers.length; i++)
{
if (provider == providers[i])
{
j = i;
break;
}
}
if (j < 0)
return;
if (started && (providers[j] instanceof Lifecycle))
{
try
{
((Lifecycle) providers[j]).stop();
}
catch (LifecycleException e)
{
;
}
}
provider.setEngine(null);
provider.setService(null);
int k = 0;
Provider results[] = new Provider[providers.length - 1];
for (int i = 0; i < providers.length; i++)
{
if (i != j)
results[k++] = providers[i];
}
providers = results;
// Report this property change to interested listeners
support.firePropertyChange("provider", provider, null);
}
}
/**
* Remove a property change listener from this component.
*
* @param listener The listener to remove
*/
public void removePropertyChangeListener(PropertyChangeListener listener)
{
support.removePropertyChangeListener(listener);
}
/**
* Return a String representation of this component.
*/
public String toString()
{
StringBuffer sb = new StringBuffer("StandardService[");
sb.append(getName());
sb.append("]");
return (sb.toString());
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a LifecycleEvent listener to this component.
*
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener)
{
lifecycle.addLifecycleListener(listener);
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners()
{
return lifecycle.findLifecycleListeners();
}
/**
* Remove a LifecycleEvent listener from this component.
*
* @param listener The listener to remove
*/
public void removeLifecycleListener(LifecycleListener listener)
{
lifecycle.removeLifecycleListener(listener);
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called before any of the public
* methods of this component are utilized. It should also send a
* LifecycleEvent of type START_EVENT to any registered listeners.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException
{
// Validate and update our current component state
if (started)
{
log.info(sm.getString("standardService.start.started"));
}
if (server == null)
{
ServerFactory.getServer().addService(this);
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our defined Providers second
synchronized (providers)
{
for (int i = 0; i < providers.length; i++)
{
if(providers[i].getEngine()==null)
{
providers[i].setEngine(this.getEngine());
}
if (providers[i] instanceof Lifecycle)
{
((Lifecycle) providers[i]).start();
}
}
}
// Start our defined NamingServer first
if (namingServer != null)
{
synchronized (namingServer)
{
if(namingServer.getEngine()==null)
{
namingServer.setEngine(this.getEngine());
}
if (namingServer instanceof Lifecycle)
{
((Lifecycle) namingServer).start();
}
}
}
// Start our defined Engine first
if (engine != null)
{
synchronized (engine)
{
if (engine instanceof Lifecycle)
{
((Lifecycle) engine).start();
}
}
}
//-------------------------------------------------------------------------------
//--INSTALL WEB CONTAINER
String serverFactory=System.getProperty("j2ee.server.factory");
if(serverFactory!=null && !"".equals(serverFactory.trim()))
{
log.info("*******************************INSTALL J2EE SERVER*******************************");
try
{
Class clazz=StandardServer.class.getClassLoader().loadClass(serverFactory);
J2EEServerFactory webserverFactory=(J2EEServerFactory)clazz.newInstance();
String providerClassName= webserverFactory.getProviderClass();
Class providerClass=StandardServer.class.getClassLoader().loadClass(providerClassName);
Provider provider=(Provider)providerClass.newInstance();
addProvider(provider);
}
catch (Throwable t)
{
log.error("J2EEServerFactory creation threw exception", t);
}
}
// -------------------------------------------------------------------------------
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component. It should also send a LifecycleEvent
* of type STOP_EVENT to any registered listeners.
*
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException
{
// Validate and update our current component state
if (!started)
{
return;
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
log.info(sm.getString("standardService.stop.name", this.name));
started = false;
// Stop our defined Container second
if (engine != null)
{
synchronized (engine)
{
if (engine instanceof Lifecycle)
{
((Lifecycle) engine).stop();
}
}
}
// Stop our defined NamingServer first
if (namingServer != null)
{
synchronized (namingServer)
{
if (namingServer instanceof Lifecycle)
{
((Lifecycle) namingServer).stop();
}
}
}
// Stop our defined Providers first
synchronized (providers)
{
for (int i = 0; i < providers.length; i++)
{
if (providers[i] instanceof Lifecycle)
{
((Lifecycle) providers[i]).stop();
}
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
}