//----------------------------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.Serializable;
import java.util.HashMap;
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.Logger;
import org.huihoo.willow.NamingServer;
import org.huihoo.willow.Service;
import org.huihoo.willow.util.LifecycleSupport;
import org.huihoo.willow.util.StringManager;
import org.huihoo.workflow.runtime.WorkflowService;
/**
* @author reic
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public abstract class NamingServerBase implements NamingServer, Lifecycle, Serializable
{
protected static Log log = LogFactory.getLog(NamingServerBase.class);
/**
* The string manager for this package.
*/
protected static StringManager sm = StringManager.getManager(Constants.PACKAGE);
// ----------------------------------------------------- Instance Variables
/**
* The child WorkflowService belonging to this , keyed by name.
*/
protected HashMap children = new HashMap();
/**
* Holder for our configured properties.
*/
protected HashMap properties = new HashMap();
/**
* The accept count for this NamingServer.
*/
protected int acceptCount = 10;
/**
* The IP address on which to bind, if any. If <code>null</code>, all
* addresses on the server will be bound.
*/
protected String address = null;
/**
* The debugging detail level for this component.
*/
protected int debug = 0;
/**
* The lifecycle event support for this component.
*/
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
/**
* Linger value on the incoming connection.
* Note : a value inferior to 0 means no linger.
*/
protected int connectionLinger = -1;
/**
* Timeout value on the incoming connection.
* Note : a value of 0 means no timeout.
*/
protected int connectionTimeout = 60000;
/**
* Timeout value on the server socket.
* Note : a value of 0 means no timeout.
*/
protected int serverSocketTimeout = 0;
/**
* The port number on which we listen for requests.
*/
protected int port = 0;
/**
* Use TCP no delay ?
*/
protected boolean tcpNoDelay = true;
/**
* Return the <code>Service</code> with which we are associated (if any).
*/
protected Service service = null;
/**
* Return the Engine used for processing requests received by this
*/
protected Engine engine = null;
/**
* The "enable DNS lookups" flag for this
*/
protected boolean enableLookups = false;
/**
* Has this component been initialized yet?
*/
protected boolean initialized = false;
/**
* Has this component been started yet?
*/
protected boolean started = false;
/**
* The human-readable name of this NamingServer.
*/
protected String name = null;
// ------------------------------------------------------------- Properties
/**
* Return a configured property.
*/
public Object getProperty(String name)
{
return properties.get(name);
}
/**
* Set a configured property.
*/
public void setProperty(String name, Object value)
{
properties.put(name, value);
}
/**
* remove a configured property.
*/
public void removeProperty(String name)
{
properties.remove(name);
}
/**
* Return the <code>Service</code> with which we are associated (if any).
*/
public Service getService()
{
return (this.service);
}
/**
* Set the <code>Service</code> with which we are associated (if any).
*
* @param service The service that owns this Engine
*/
public void setService(Service service)
{
this.service = service;
setProperty("service", service);
}
/**
* Return the connection linger for this NamingServer.
*/
public int getConnectionLinger()
{
return (connectionLinger);
}
/**
* Set the connection linger for this NamingServer.
*
* @param count The new connection linge
*/
public void setConnectionLinger(int connectionLinger)
{
this.connectionLinger = connectionLinger;
setProperty("soLinger", String.valueOf(connectionLinger));
}
/**
* Return the connection timeout for this NamingServer.
*/
public int getConnectionTimeout()
{
return (connectionTimeout);
}
/**
* Set the connection timeout for this NamingServer.
*
* @param count The new connection timeout
*/
public void setConnectionTimeout(int connectionTimeout)
{
this.connectionTimeout = connectionTimeout;
setProperty("soTimeout", String.valueOf(connectionTimeout));
}
/**
* Return the server socket timeout for this NamingServer.
*/
public int getServerSocketTimeout()
{
return (serverSocketTimeout);
}
/**
* Set the server socket timeout for this NamingServer.
*
* @param serverSocketTimeout The new server socket timeout
*/
public void setServerSocketTimeout(int serverSocketTimeout)
{
this.serverSocketTimeout = serverSocketTimeout;
setProperty("serverSoTimeout", String.valueOf(serverSocketTimeout));
}
/**
* Return the accept count for this Connector.
*/
public int getAcceptCount()
{
return (acceptCount);
}
/**
* Set the accept count for this Connector.
*
* @param count The new accept count
*/
public void setAcceptCount(int count)
{
this.acceptCount = count;
setProperty("backlog", String.valueOf(count));
}
/**
* Return the bind IP address for this NamingServer.
*/
public String getAddress()
{
return (this.address);
}
/**
* Set the bind IP address for this NamingServer.
*
* @param address The bind IP address
*/
public void setAddress(String address)
{
this.address = address;
setProperty("address", address);
}
public String getName()
{
return (name);
}
public void setName(String name)
{
this.name = name;
setProperty("name", name);
}
/**
* Return the Engine used for processing requests received by this
* NamingServer.
*/
public Engine getEngine()
{
return (this.engine);
}
/**
* Set the Engine used for processing requests received by this
* NamingServer.
*
* @param engine The new Engine to use
*/
public void setEngine(Engine engine)
{
this.engine = engine;
}
/**
* Return the debugging detail level for this component.
*/
public int getDebug()
{
return (debug);
}
/**
* Set the debugging detail level for this component.
*
* @param debug The new debugging detail level
*/
public void setDebug(int debug)
{
this.debug = debug;
}
/**
* Return the "enable DNS lookups" flag.
*/
public boolean getEnableLookups()
{
return (this.enableLookups);
}
/**
* Set the "enable DNS lookups" flag.
*
* @param enableLookups The new "enable DNS lookups" flag value
*/
public void setEnableLookups(boolean enableLookups)
{
this.enableLookups = enableLookups;
setProperty("enableLookups", String.valueOf(enableLookups));
}
/**
* Return the port number on which we listen for requests.
*/
public int getPort()
{
return (this.port);
}
/**
* Set the port number on which we listen for requests.
*
* @param port The new port number
*/
public void setPort(int port)
{
this.port = port;
setProperty("port", String.valueOf(port));
}
/**
* Return the TCP no delay flag value.
*/
public boolean getTcpNoDelay()
{
return (this.tcpNoDelay);
}
/**
* Set the TCP no delay flag which will be set on the socket after
* accepting a connection.
*
* @param tcpNoDelay The new TCP no delay flag
*/
public void setTcpNoDelay(boolean tcpNoDelay)
{
this.tcpNoDelay = tcpNoDelay;
setProperty("tcpNoDelay", String.valueOf(tcpNoDelay));
}
//---------------------------------------------------------public Methods
/**
* Add a new child Context to those associated with this
*/
public void addWorkflowService(WorkflowService child)
{
log.debug("Add WorkflowService " + child + " " + this);
synchronized (children)
{
if (children.get(child.getName()) != null)
{
throw new IllegalArgumentException("addWorkflowService: WorkflowService name '" + child.getName() + "' is not unique");
}
children.put(child.getName(), child);
}
}
/**
* Return the child WorkflowService, associated with this , with
* the specified name (if any); otherwise, return <code>null</code>
*
* @param name Name of the child WorkflowService to be retrieved
*/
public WorkflowService findWorkflowService(String name)
{
if (name == null)
return (null);
synchronized (children)
{ // Required by post-start changes
return ((WorkflowService) children.get(name));
}
}
/**
* Return the set of children WorkflowServices associated with this .
* If this has no children, a zero-length array is returned.
*/
public WorkflowService[] findWorkflowServices()
{
synchronized (children)
{
WorkflowService results[] = new WorkflowService[children.size()];
return ((WorkflowService[]) children.values().toArray(results));
}
}
/**
* Remove an existing child WorkflowService from association with this
*
* @param child Existing child WorkflowService to be removed
*/
public void removeWorkflowService(WorkflowService child)
{
synchronized (children)
{
if (children.get(child.getName()) == null)
return;
children.remove(child.getName());
}
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a lifecycle event 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 lifecycle event listener from this component.
*
* @param listener The listener to add
*/
public void removeLifecycleListener(LifecycleListener listener)
{
lifecycle.removeLifecycleListener(listener);
}
/**
* Invoke a pre-startup initialization. This is used to allow ServiceProviders
* to bind to restricted ports under Unix operating environments.
*
* @exception LifecycleException If this server was already initialized.
*/
public synchronized void initialize() throws LifecycleException
{
if (initialized)
{
log.info(sm.getString("providerBase.alreadyInitialized", logName()));
return;
}
initialized = true;
}
/**
* 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 synchronized void start() throws LifecycleException
{
// Validate and update our current component state
if (started)
{
log.info(sm.getString("providerBase.alreadyStarted", logName()));
return;
}
this.started = true;
}
/**
* 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 synchronized void stop() throws LifecycleException
{
if (!started)
{
log.info(sm.getString("providerBase.notStarted", logName()));
return;
}
this.started = false;
}
/**
* Return the abbreviated name of this engine for logging messsages
*/
protected String logName()
{
String className = this.getClass().getName();
int period = className.lastIndexOf(".");
if (period >= 0)
className = className.substring(period + 1);
return (className);
}
/**
* Log the specified message to our current Logger (if any).
*
* @param message Message to be logged
*/
protected void log(String message)
{
Logger logger = engine.getLogger();
if (logger != null)
{
logger.log(logName() + ": " + message);
}
else
{
log.info(message);
}
}
/**
* Log the specified message and exception to our current Logger
* (if any).
*
* @param message Message to be logged
* @param throwable Related exception
*/
protected void log(String message, Throwable throwable)
{
Logger logger = engine.getLogger();
if (logger != null)
{
logger.log(logName() + ": " + message, throwable);
}
else
{
log.error(message, throwable);
}
}
}