Package org.exoplatform.container.jmx

Source Code of org.exoplatform.container.jmx.ManagementContextImpl

/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This 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 (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.container.jmx;

import org.exoplatform.container.ExoContainer;
import org.exoplatform.management.ManagementContext;
import org.exoplatform.management.annotations.ManagedBy;
import org.exoplatform.management.jmx.annotations.NameTemplate;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBeanInfo;

/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
public class ManagementContextImpl implements ManagementContext
{

   /** . */
   Map<String, String> scopingProperties;

   /** The registrations done by this mbean. */
   private final Map<Object, ObjectName> registrations;

   /** . */
   private final ManagementContextImpl parent;

   /** . */
   final MBeanServer server;

   /** An optional container setup when the management context is attached to a container. */
   ManageableContainer container;

   public ManagementContextImpl()
   {
      this(MBeanServerFactory.createMBeanServer());
   }

   public ManagementContextImpl(MBeanServer server)
   {
      if (server == null)
      {
         throw new NullPointerException();
      }
      this.registrations = new HashMap<Object, ObjectName>();
      this.parent = null;

      // This is the root container that never have scoping properties
      // Also without that we would have an NPE when the portal container are registered
      // as the scoping properties would not exist since the root container would not be yet
     
      this.scopingProperties = Collections.emptyMap();
      this.server = server;
   }

   public ManagementContextImpl(ManagementContextImpl parent)
   {
      if (parent == null)
      {
         throw new NullPointerException();
      }
      this.registrations = new HashMap<Object, ObjectName>();
      this.parent = parent;
      this.scopingProperties = null;
      this.server = parent.server;
   }

   public ManagementContext getParent()
   {
      return parent;
   }

   public void register(Object o)
   {
      ObjectName name = manageMBean(o);
      if (name != null)
      {
         registrations.put(o, name);
      }
   }

   public void unregister(Object o)
   {
      ObjectName name = registrations.remove(o);
      if (name != null)
      {
         unmanageMBean(name);
      }
   }

   private ExoModelMBean createExoMBean(Object bean)
   {
      Object view = null;

      // Apply managed by annotation
      ManagedBy managedBy = bean.getClass().getAnnotation(ManagedBy.class);
      if (managedBy != null)
      {
         try
         {
            Class managedByClass = managedBy.value();
            Constructor<?> blah = managedByClass.getConstructor(bean.getClass());
            view = blah.newInstance(bean);
         }
         catch (NoSuchMethodException e)
         {
            e.printStackTrace();
         }
         catch (InstantiationException e)
         {
            e.printStackTrace();
         }
         catch (IllegalAccessException e)
         {
            e.printStackTrace();
         }
         catch (InvocationTargetException e)
         {
            e.printStackTrace();
         }
      }
      else
      {
         view = bean;
      }

      //
      if (view != null)
      {
         ExoMBeanInfoBuilder infoBuilder = new ExoMBeanInfoBuilder(view.getClass());
         if (infoBuilder.isBuildable())
         {
            try
            {
               ModelMBeanInfo info = infoBuilder.build();
               return new ExoModelMBean(this, view, info);
            }
            catch (Exception e)
            {
               e.printStackTrace();
            }
         }
      }

      //
      return null;
   }

   public ObjectName manageMBean(Object bean)
   {

      //
      ExoModelMBean mbean = createExoMBean(bean);

      //
      if (mbean != null)
      {
         Object mr = mbean.getManagedResource();
         ObjectName on = null;
         PropertiesInfo oni = PropertiesInfo.resolve(mr.getClass(), NameTemplate.class);
         if (oni != null)
         {
            try
            {
               Map<String, String> foo = oni.resolve(mr);
               on = JMX.createObjectName("exo", foo);
            }
            catch (MalformedObjectNameException e)
            {
               e.printStackTrace();
            }
         }

         //
         if (on != null)
         {
            // Merge with the container hierarchy context
            try
            {
               Map<String, String> props = new Hashtable<String, String>();

               // Julien : I know it's does not look great but it's necessary
               // for compiling under Java 5 and Java 6 properly. The methods
               // ObjectName#getKeyPropertyList() returns an Hashtable with Java 5
               // and a Hashtable<String, String> with Java 6.
               for (Object o : on.getKeyPropertyList().entrySet())
               {
                  Map.Entry entry = (Map.Entry)o;
                  String key = (String)entry.getKey();
                  String value = (String)entry.getValue();
                  props.put(key, value);
               }
               for (ManagementContextImpl current = this; current != null; current = current.parent)
               {
                  if (current.scopingProperties != null)
                  {
                     props.putAll(current.scopingProperties);
                  }
               }
               on = JMX.createObjectName(on.getDomain(), props);
               attemptToRegister(on, mbean);
               return on;
            }
            catch (MalformedObjectNameException e)
            {
               e.printStackTrace();
            }
         }
      }

      //
      return null;
   }

   public void unmanageMBean(ObjectName name)
   {
      try
      {
         server.unregisterMBean(name);
      }
      catch (InstanceNotFoundException e)
      {
         e.printStackTrace();
      }
      catch (MBeanRegistrationException e)
      {
         e.printStackTrace();
      }
   }

   synchronized void attemptToRegister(ObjectName name, Object mbean)
   {
      synchronized (server)
      {
         try
         {
            server.registerMBean(mbean, name);
         }
         catch (InstanceAlreadyExistsException e)
         {
            try
            {

               server.unregisterMBean(name);
               server.registerMBean(mbean, name);

            }
            catch (Exception e1)
            {
               throw new RuntimeException("Failed to register MBean '" + name + " due to " + e.getMessage(), e);
            }
         }
         catch (Exception e)
         {
            throw new RuntimeException("Failed to register MBean '" + name + " due to " + e.getMessage(), e);
         }
      }
   }

   public ExoContainer findContainer()
   {
      for (ManagementContextImpl current = this;true;current = current.parent)
      {
         if (current.container instanceof ExoContainer)
         {
            return (ExoContainer)current.container;
         }
         else if (current.parent == null)
         {
            return null;
         }
      }
   }

   @Override
   public String toString()
   {
      return "ManagementContextImpl[container=" + container + "]";
   }
}
TOP

Related Classes of org.exoplatform.container.jmx.ManagementContextImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.