/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina.ha.jmx;

import org.apache.tomcat.util.modeler.Registry;
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.catalina.ha.tcp.SimpleTcpCluster;
import org.apache.catalina.ha.session.DeltaManager;
import org.apache.catalina.ha.deploy.FarmWarDeployer;
import org.apache.catalina.ha.authenticator.ClusterSingleSignOn;
import org.apache.catalina.core.StandardHost;
import javax.management.ObjectName;
import org.apache.catalina.core.StandardEngine;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServer;
import javax.management.modelmbean.ModelMBean;
import org.apache.tomcat.util.modeler.ManagedBean;
import javax.management.DynamicMBean;

public class ClusterJmxHelper {
    
    protected static Registry registry = Registry.getRegistry(null,null);
    
    protected static Log log = LogFactory.getLog(ClusterJmxHelper.class);
    
    protected static boolean jmxEnabled = true;
    
    protected static MBeanServer mbeanServer = null;
    
    public static Registry getRegistry() {
        return registry;
    }

    public static MBeanServer getMBeanServer() throws Exception {
        if (mbeanServer == null) {
            if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
                mbeanServer = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
            } else {
                mbeanServer = MBeanServerFactory.createMBeanServer();
            }
        }
        return mbeanServer;
    }
    
    protected static boolean initMetaData(Class clazz) {
        try {
            if (clazz==null) return false;
            getRegistry().loadMetadata(clazz.getResourceAsStream("mbeans-descriptors.xml"));
        }catch (Exception x) {
            log.warn("Unable to load meta data for class:"+clazz.getName());
            return false;
        }
        return true;
    }
    
    public static DynamicMBean getManagedBean(Object object) throws Exception {
        DynamicMBean mbean = null;
        if (getRegistry() != null) {
            ManagedBean managedBean = registry.findManagedBean(object.getClass().getName());
            mbean = managedBean.createMBean(object);
        }
        return mbean;
    }

    
    protected static void initDefaultCluster() {
        initMetaData(SimpleTcpCluster.class);
        initMetaData(DeltaManager.class);
        initMetaData(FarmWarDeployer.class); //not functional yet
        initMetaData(ClusterSingleSignOn.class); //not functional yet
    }
    
    public static boolean registerDefaultCluster(SimpleTcpCluster cluster)  {
        try {
            initDefaultCluster();
            ObjectName clusterName = getDefaultClusterName(cluster);
            if (!getMBeanServer().isRegistered(clusterName)) {
                getMBeanServer().registerMBean(getManagedBean(cluster), clusterName);
            }
            return true;
        }catch ( Exception x ) {
            log.warn("Unable to register default cluster implementation with JMX",x);
            return false;
        }
    }

    public static boolean unregisterDefaultCluster(SimpleTcpCluster cluster) throws Exception {
        ObjectName clusterName = getDefaultClusterName(cluster);
        if (getMBeanServer().isRegistered(clusterName)) {
            getMBeanServer().unregisterMBean(clusterName);
        }
        return true;
    }

    private static ObjectName getDefaultClusterName(SimpleTcpCluster cluster) throws Exception {
        String domain = getMBeanServer().getDefaultDomain();
        String type = ":type=";
        String clusterType= type+"Cluster";
        if (cluster.getContainer() instanceof StandardHost) {
            domain = ((StandardHost) cluster.getContainer()).getDomain();
            clusterType += ",host=" + cluster.getContainer().getName();
        } else {
            if (cluster.getContainer() instanceof StandardEngine) {
                domain = ((StandardEngine) cluster.getContainer()).getDomain();
            }
        }
        ObjectName clusterName = new ObjectName(domain + clusterType);
        return clusterName;
    }
    
}
@@ -4113,32 +4113,30 @@
 luster) 
-throws Exception
+%7B%0D%0A        try
  %7B%0D%0A    
@@ -4131,32 +4131,36 @@
  try %7B%0D%0A        
+    
 ObjectName clust
@@ -4205,24 +4205,28 @@
 );%0D%0A        
+   
+ 
 if (getMBean
@@ -4268,32 +4268,36 @@
  %7B%0D%0A            
+    
 getMBeanServer()
@@ -4328,35 +4328,43 @@
 Name);%0D%0A        
+ 
-%7D%0D%0A
+   %7D%0D%0A    
         return t
@@ -4365,24 +4365,185 @@
 turn true;%0D%0A
+        %7Dcatch ( Exception x ) %7B%0D%0A            log.warn(%22Unable to unregister default cluster implementation with JMX%22,x);%0D%0A            return false;%0D%0A        %7D%0D%0A
     %7D%0D%0A%0D%0A   

remove throwing of exceptions, handle everything inside the JMX helper