/*
 * Created on 2004-6-9
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package org.huihoo.willow.core;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.huihoo.willow.Container;
import org.huihoo.willow.ContainerEvent;
import org.huihoo.willow.ContainerListener;
import org.huihoo.willow.Context;
import org.huihoo.willow.Lifecycle;
import org.huihoo.willow.LifecycleEvent;
import org.huihoo.willow.LifecycleListener;
import org.huihoo.willow.Server;
import org.huihoo.willow.Service;


/**
 * @author reic
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class ServerLifecycleListener implements ContainerListener, LifecycleListener, PropertyChangeListener
{

	private static org.apache.commons.logging.Log log =
	org.apache.commons.logging.LogFactory.getLog(ServerLifecycleListener.class);

	// ------------------------------------------------------------- Properties

	/**
	 * The debugging detail level for this component.
	 */
	protected int debug = 0;

	public int getDebug()
	{
		return (this.debug);
	}

	public void setDebug(int debug)
	{
		this.debug = debug;
	}

	// ---------------------------------------------- ContainerListener Methods

	/**
	 * Handle a <code>ContainerEvent</code> from one of the Containers we are
	 * interested in.
	 *
	 * @param event The event that has occurred
	 */
	public void containerEvent(ContainerEvent event)
	{

		try
		{
			String type = event.getType();
			if (Container.ADD_CHILD_EVENT.equals(type))
			{
				processContainerAddChild(event.getContainer(), (Container) event.getData());
			}
			else
				if (Container.REMOVE_CHILD_EVENT.equals(type))
				{
					processContainerRemoveChild(event.getContainer(), (Container) event.getData());
				}
		}
		catch (Exception e)
		{
			log.error("Exception processing event " + event, e);
		}

	}

	// ---------------------------------------------- LifecycleListener Methods

	/**
	 * Primary entry point for startup and shutdown events.
	 *
	 * @param event The event that has occurred
	 */
	public void lifecycleEvent(LifecycleEvent event)
	{

		Lifecycle lifecycle = event.getLifecycle();
		if (Lifecycle.START_EVENT.equals(event.getType()))
		{

			if (lifecycle instanceof Server)
			{

			}

			// We are embedded.
			if (lifecycle instanceof Service)
			{
			}

		}
		else
			if (Lifecycle.STOP_EVENT.equals(event.getType()))
			{
				if (lifecycle instanceof Server)
				{
				}
				if (lifecycle instanceof Service)
				{
				}

			}

		if ((Context.RELOAD_EVENT.equals(event.getType()))
			|| (Lifecycle.START_EVENT.equals(event.getType())))
		{

		}

	}

	// ----------------------------------------- PropertyChangeListener Methods

	/**
	 * Handle a <code>PropertyChangeEvent</code> from one of the Containers
	 * we are interested in.
	 *
	 * @param event The event that has occurred
	 */
	public void propertyChange(PropertyChangeEvent event)
	{

		if (event.getSource() instanceof Container)
		{
			try
			{
				processContainerPropertyChange(
					(Container) event.getSource(),
					event.getPropertyName(),
					event.getOldValue(),
					event.getNewValue());
			}
			catch (Exception e)
			{
				log.error("Exception handling Container property change", e);
			}
		}
		else
			if (event.getSource() instanceof Server)
			{
				try
				{
					processServerPropertyChange(
						(Server) event.getSource(),
						event.getPropertyName(),
						event.getOldValue(),
						event.getNewValue());
				}
				catch (Exception e)
				{
					log.error("Exception handing NamingServer property change", e);
				}
			}
			else
				if (event.getSource() instanceof Service)
				{
					try
					{
						processServicePropertyChange(
							(Service) event.getSource(),
							event.getPropertyName(),
							event.getOldValue(),
							event.getNewValue());
					}
					catch (Exception e)
					{
						log.error("Exception handing Service property change", e);
					}
				}

	}

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

	/**
	 * Log a message.
	 *
	 * @param message The message to be logged
	 */
	protected void log(String message)
	{

		System.out.print("ServerLifecycleListener: ");
		System.out.println(message);

	}

	/**
	 * Log a message and associated exception.
	 *
	 * @param message The message to be logged
	 * @param throwable The exception to be logged
	 */
	protected void log(String message, Throwable throwable)
	{

		log(message);
		throwable.printStackTrace(System.out);

	}

	/**
	 * Process the addition of a new child Container to a parent Container.
	 *
	 * @param parent Parent container
	 * @param child Child container
	 */
	protected void processContainerAddChild(Container parent, Container child)
	{

		if (log.isDebugEnabled())
			log.debug("Process addChild[parent=" + parent + ",child=" + child + "]");
	}

	/**
	 * Process a property change event on a Container.
	 *
	 * @param container The container on which this event occurred
	 * @param propertyName The name of the property that changed
	 * @param oldValue The previous value (may be <code>null</code>)
	 * @param newValue The new value (may be <code>null</code>)
	 *
	 * @exception Exception if an exception is thrown
	 */
	protected void processContainerPropertyChange(
		Container container,
		String propertyName,
		Object oldValue,
		Object newValue)
		throws Exception
	{

		if (log.isTraceEnabled())
		{
			log.trace(
				"propertyChange[container="
					+ container
					+ ",propertyName="
					+ propertyName
					+ ",oldValue="
					+ oldValue
					+ ",newValue="
					+ newValue
					+ "]");
		}

	}

	/**
	 * Process the removal of a child Container from a parent Container.
	 *
	 * @param parent Parent container
	 * @param child Child container
	 */
	protected void processContainerRemoveChild(Container parent, Container child)
	{

		if (log.isDebugEnabled())
			log.debug("Process removeChild[parent=" + parent + ",child=" + child + "]");

		if (child instanceof Context)
		{
			Context context = (Context) child;
			if (context instanceof StandardContext)
			{
				((StandardContext) context).removePropertyChangeListener(this);
			}
		}

	}

	/**
	 * Process a property change event on a NamingServer.
	 *
	 * @param server The server on which this event occurred
	 * @param propertyName The name of the property that changed
	 * @param oldValue The previous value (may be <code>null</code>)
	 * @param newValue The new value (may be <code>null</code>)
	 *
	 * @exception Exception if an exception is thrown
	 */
	protected void processServerPropertyChange(
		Server server,
		String propertyName,
		Object oldValue,
		Object newValue)
		throws Exception
	{

		if (log.isTraceEnabled())
		{
			log.trace(
				"propertyChange[server="
					+ server
					+ ",propertyName="
					+ propertyName
					+ ",oldValue="
					+ oldValue
					+ ",newValue="
					+ newValue
					+ "]");
		}

	}

	/**
	 * Process a property change event on a Service.
	 *
	 * @param service The service on which this event occurred
	 * @param propertyName The name of the property that changed
	 * @param oldValue The previous value (may be <code>null</code>)
	 * @param newValue The new value (may be <code>null</code>)
	 *
	 * @exception Exception if an exception is thrown
	 */
	protected void processServicePropertyChange(
		Service service,
		String propertyName,
		Object oldValue,
		Object newValue)
		throws Exception
	{

		if (log.isTraceEnabled())
		{
			log.trace(
				"propertyChange[service="
					+ service
					+ ",propertyName="
					+ propertyName
					+ ",oldValue="
					+ oldValue
					+ ",newValue="
					+ newValue
					+ "]");
		}
	}

}
