/*
 * JBoss, the OpenSource EJB server
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import javax.management.*;

import org.jboss.logging.Logger;


/** ServiceControl manages the JBoss services lifecycle.
 * 
 *   @see org.jboss.util.Service
 *   @author Rickard Öberg (rickard.oberg@telkel.com)
 *   @author Hugo Pinto (mailto:hugo@hugopinto.com)
 *   @author Scott.Stark@jboss.org
 *   @version $Revision: 1.9.4.1 $
 */
public class ServiceControl
   implements ServiceControlMBean, MBeanRegistration
{
   // Constants -----------------------------------------------------
   public static final String OBJECT_NAME = ":service=ServiceControl";
   static Logger log = Logger.getLogger(ServiceControl.class);

   // Attributes ----------------------------------------------------
   
   List mbeans = new ArrayList();
   // Static --------------------------------------------------------

   // Constructors --------------------------------------------------
   
   // Service implementation ----------------------------------------
   public void init()
      throws Exception
   {
      log.info("Initializing "+mbeans.size()+" MBeans");
      
      List mbeansCopy = new ArrayList(mbeans);
      Iterator enum = mbeansCopy.iterator();
      int serviceCounter = 0;
      while (enum.hasNext())
      {
         Service service = (Service)enum.next();
         try
         {
            service.init();
            serviceCounter++;
         }
         catch(Throwable e)
         {
            log.error("Could not initialize "+service, e);
         }
      }
      log.info("Initialized "+mbeansCopy.size()+" services");
   }
   
   public void start()
      throws Exception
   { 
      log.info("Starting "+mbeans.size()+" MBeans");
      
      List mbeansCopy = new ArrayList(mbeans);
      Iterator enum = mbeansCopy.iterator();
      int serviceCounter = 0;
      while (enum.hasNext())
      {
         Service service = (Service)enum.next();
         
         try
         {
            service.start();
            serviceCounter++;
         }
         catch(Throwable e)
         {
            log.error("Could not start "+service, e);
         }
      }
      log.info("Started "+mbeansCopy.size()+" services");
   }
   
   public void stop()
   {
      log.info("Stopping "+mbeans.size()+" MBeans");
      
      List mbeansCopy = new ArrayList(mbeans);
      ListIterator enum = mbeansCopy.listIterator();
      int serviceCounter = 0;
      while (enum.hasNext()) enum.next(); // pass them all
      while (enum.hasPrevious())
      {
         Service service = (Service) enum.previous();
         
         try
         {
            service.stop();
            serviceCounter++;
         }
         catch (Throwable e)
         {
            log.error("Could not stop "+service, e);
         }
      }
      log.info("Stopped "+mbeansCopy.size()+" services");
   }
   
   public void destroy()
   {
      log.info("Destroying "+mbeans.size()+" MBeans");
      
      List mbeansCopy = new ArrayList(mbeans);
      ListIterator enum = mbeansCopy.listIterator();
      int serviceCounter = 0;
      while (enum.hasNext()) enum.next(); // pass them all
      while (enum.hasPrevious())
      {
         Service service = (Service) enum.previous();
         
         try
         {
            service.destroy();
            serviceCounter++;
         }
         catch (Throwable e)
         {
            log.error("Could not destroy"+service, e);
         }
      }
      log.info("Destroyed "+mbeansCopy.size()+" services");
   }

   public void register(Service service)
   {
       mbeans.add(service);
   }
   public void unregister(Service service)
   {
       mbeans.remove(service);
   }

   // MBeanRegistration implementation ------------------------------
   public ObjectName preRegister(MBeanServer server, ObjectName name)
      throws java.lang.Exception
   {
      return name == null ? new ObjectName(OBJECT_NAME) : name;
   }
   
   public void postRegister(java.lang.Boolean registrationDone)
   {
   }
   
   public void preDeregister()
      throws java.lang.Exception
   {
   }
   
   public void postDeregister()
   {
   }

}
