/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2005 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.objectweb.jonas.web.jetty50.jmx;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.management.MBeanException;
import javax.management.ObjectName;

import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.WebApplicationContext;
import org.mortbay.jetty.servlet.jmx.ConfigurationMBean;
import org.mortbay.util.LogSupport;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.objectweb.jonas.web.jetty50.JSR77Configuration;

/**
 * JSR77Configuration MBean.
 * It will register/deregister MBeans for the given WebApp.
 * Expected MBeans creation :
 * - 1 WebModule
 * - n Servlet
 *
 * @author Guillaume Sauthier
 */
public class JSR77ConfigurationMBean extends ConfigurationMBean {

    /**
     * logger
     */
    private static Log log = LogFactory.getLog(JSR77ConfigurationMBean.class);

    /**
     * MBeans map, used for deregistration
     */
    private Map jsr77MBeanMap = new HashMap();

    /**
     * Default constructor
     * @throws MBeanException if parent throws MBeanException
     */
    public JSR77ConfigurationMBean() throws MBeanException {
        super();
    }

    /**
     * We do not add any attributes/operations
     */
    protected void defineManagedResource() {
        super.defineManagedResource();
    }

    /**
     * Register the other jsr77 mbeans
     * @param ok Boolean
     *
     * @see javax.management.MBeanRegistration#postRegister(java.lang.Boolean)
     */

    public void postRegister(Boolean ok) {
        super.postRegister(ok);
        try {
            defineJsr77MBeans();
        } catch (Exception e) {
            log.warn(LogSupport.EXCEPTION, e);
        }
    }

    /**
     * Deregister also all of the jsr77 mbeans we were
     * responsible for registering.
     *
     * @see javax.management.MBeanRegistration#postDeregister()
     */
    public void postDeregister() {
        Iterator itor = jsr77MBeanMap.entrySet().iterator();
        while (itor.hasNext()) {
            try {
                Map.Entry entry = (Map.Entry) itor.next();
                getMBeanServer().unregisterMBean((ObjectName) entry.getValue());
            } catch (Exception e) {
                log.warn(LogSupport.EXCEPTION, e);
            }
        }
    }

    /**
     * Make and register an mbean for each of the jsr77
     * servlet stats.
     * Make the WebModule MBean
     *
     * @throws Exception if registration fails
     */
    private void defineJsr77MBeans() throws Exception {
        WebApplicationContext context = ((JSR77Configuration) _config).getWebApplicationContext();

        // create a WebModuleMBean
        J2EEWebModuleMBean wm = new J2EEWebModuleMBean();
        wm.setManagedResource(context, "objectReference");
        wm.setBaseObjectName(getBaseObjectName().toString());
        ObjectName oName = getMBeanServer().registerMBean(wm, null).getObjectName();
        jsr77MBeanMap.put(context.getName(), oName);

        // TODO a WebModule must have an attribute (servlets) for Servlet's ObjectName

        ServletHolder[] servlets = context.getServletHandler().getServlets();
        for (int i = 0; null != servlets && i < servlets.length; i++) {
            FixedJsr77ServletHolderMBean mbean = new FixedJsr77ServletHolderMBean();
            mbean.setManagedResource(servlets[i], "objectReference");
            mbean.setBaseObjectName(getBaseObjectName().toString());
            // add necessary data
            mbean.setJ2EEDomainName((String) context.getAttribute("J2EEDomainName"));
            mbean.setJ2EEApplicationName((String) context.getAttribute("J2EEApplicationName"));
            mbean.setJ2EEServerName((String) context.getAttribute("J2EEServerName"));
            oName = getMBeanServer().registerMBean(mbean, null).getObjectName();
            jsr77MBeanMap.put(servlets[i].getName(), oName);
        }
        
        //set the attribute (servlets) for Servlet's ObjectName
        wm.setServlets((ObjectName[]) jsr77MBeanMap.values().toArray(new ObjectName[jsr77MBeanMap.values().size()]));
    }

}
