Package org.jboss.mx.modelmbean

Source Code of org.jboss.mx.modelmbean.ModelMBeanInvoker

/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.mx.modelmbean;

import java.util.Iterator;
import java.util.List;

import java.lang.reflect.Method;

import javax.management.AttributeChangeNotification;
import javax.management.AttributeChangeNotificationFilter;
import javax.management.AttributeList;
import javax.management.Attribute;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.ListenerNotFoundException;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.RuntimeOperationsException;

import javax.management.modelmbean.ModelMBean;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanNotificationInfo;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import javax.management.modelmbean.DescriptorSupport;
import javax.management.modelmbean.InvalidTargetObjectTypeException;

import org.jboss.mx.server.AbstractMBeanInvoker;
import org.jboss.mx.server.InvocationContext;

import org.jboss.mx.interceptor.Interceptor;
import org.jboss.mx.interceptor.PersistenceInterceptor;
import org.jboss.mx.interceptor.ModelMBeanAttributeInterceptor;
import org.jboss.mx.interceptor.ModelMBeanInfoInterceptor;

import org.jboss.mx.persistence.NullPersistence;
import org.jboss.mx.persistence.PersistenceManager;

import org.jboss.mx.logging.Logger;
import org.jboss.mx.logging.SystemLogger;


/**
* An extension of the {@link org.jboss.mx.server.MBeanInvoker MBeanInvoker}
* that implements the base Model MBean functionality, essentially making the
* Model MBean just another invoker of managed resources.
*
* @see javax.management.modelmbean.ModelMBean
* @see org.jboss.mx.server.MBeanInvoker
*
* @author  <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
* @author Matt Munz
* @version $Revision: 1.10 $
*/
public abstract class ModelMBeanInvoker extends AbstractMBeanInvoker
   implements ModelMBean, ModelMBeanConstants
{
   Logger log = SystemLogger.getLogger(ModelMBeanInvoker.class.getName());
  
   // Attributes ----------------------------------------------------
  
   /**
    * The resource type string of the managed resource, such as
    * {@link ModelMBeanConstants#OBJECT_REF} or
    * {@link XMBeanConstants#STANDARD_INTERFACE}. This type string can be
    * used by the invoker to determine the behavior implemented by the
    * invocation chain and how the managed resource is exposed to the client
    * programs.
    */
   protected String resourceType              = null;
  
   /**
    * Persistence manager.
    */
   protected PersistenceManager persistence   = new NullPersistence();
  
   /**
    * Notification broadcaster for this Model MBean.
    */
   protected NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();

   /**
    * Notification sequence number for generic Model MBean notifications.
    */
   protected long notifierSequence     = 1;
  
   /**
    * Notification sequence number for attribute change notifications.
    */
   protected long attrNotifierSequence = 1;


   // Constructors --------------------------------------------------
  
   /**
    * Default constructor.
    */
   public ModelMBeanInvoker()
   {
      super();
     
      setDelayedRegistration(true);
   }

   /**
    * Creates a Model MBean instance and initializes it with the given
    * Model MBean metadata.
    *
    * @param   info  Model MBean metadata
    */
   public ModelMBeanInvoker(ModelMBeanInfo info) throws MBeanException
   {
      this();
     
      setModelMBeanInfo(info);
   }



   // ModelMBean implementation -------------------------------------
  
   /**
    * Sets the MBean metadata for this Model MBean instance.
    *
    * @param   info  Model MBean metadata
    */
   public void setModelMBeanInfo(ModelMBeanInfo info) throws MBeanException, RuntimeOperationsException
   {
      if (info == null)
         throw new IllegalArgumentException("MBeanInfo cannot be null.");

      // need to type to an instance of MBeanInfo -- therefore the extra copy here
      this.info = new ModelMBeanInfoSupport(info);
   }
  
   /**
    * Sets the managed resource for this Model MBean instance. The resource
    * type must be known to the Model MBean implementation (see
    * {@link #isSupportedResourceType} for more information).
    *
    * @param   ref            reference to the managed resource
    * @param   resourceType   resource type identification string
    */
   public void setManagedResource(Object ref, String resourceType)
         throws MBeanException, InstanceNotFoundException, InvalidTargetObjectTypeException
   {
      if (ref == null)
         throw new IllegalArgumentException("Resource reference cannot be null.");

      if (!isSupportedResourceType(ref, resourceType))
         throw new InvalidTargetObjectTypeException("Unsupported resource type: " + resourceType);

      setResource(ref);
      this.resourceType = resourceType;
   }
  
   // ModelMBeanNotificationBroadcaster implementation --------------
  
   public void addNotificationListener(NotificationListener listener,
                                       NotificationFilter filter,
                                       Object handback)
   {
      notifier.addNotificationListener(listener, filter, handback);
   }

   public void removeNotificationListener(NotificationListener listener)
         throws ListenerNotFoundException
   {
      notifier.removeNotificationListener(listener);
   }

   public void removeNotificationListener(NotificationListener listener,
                                          NotificationFilter filter,
                                          Object handback)
         throws ListenerNotFoundException
   {
      notifier.removeNotificationListener(listener, filter, handback);
   }

   /**
    * Sends a notification with a given string message. The notification
    * type will be set as
    * {@link ModelMBeanConstants#GENERIC_MODELMBEAN_NOTIFICATION GENERIC_MODELMBEAN_NOTIFICATION}.
    *
    * @param   message  notification message
    */
   public void sendNotification(String message) throws MBeanException
   {
      Notification notif = new Notification(
                              GENERIC_MODELMBEAN_NOTIFICATION, // type
                              this,                            // source
                              ++notifierSequence,              // sequence number
                              message                          // message
                           );

      sendNotification(notif);
   }

   /**
    * Sends a notification.
    *
    * @param   notification notification to send
    */
   public void sendNotification(Notification notification) throws MBeanException
   {
      notifier.sendNotification(notification);
   }

   /**
    * Sends an attribute change notification.
    *
    * @param   notification attribute change notification to send
    */
   public void sendAttributeChangeNotification(AttributeChangeNotification notification)
         throws MBeanException
   {
      notifier.sendNotification(notification);
   }

   /**
    * Sends an attribute change notification.
    *
    * @param   oldValue attribute with the old value
    * @param   newValue attribute with the new value
    */
   public void sendAttributeChangeNotification(Attribute oldValue, Attribute newValue)
         throws MBeanException
   {
      if (!(oldValue.getName().equals(newValue.getName())))
         throw new IllegalArgumentException("attribute name mismatch between oldvalue and newvalue");
        
      String attr = oldValue.getName();
      String type = ((ModelMBeanInfo)info).getAttribute(attr).getType();

      AttributeChangeNotification notif = new AttributeChangeNotification(
                                             this,                          // source
                                             ++attrNotifierSequence,        // seq. #
                                             System.currentTimeMillis(),    // time stamp
                                             "" + attr + " changed from " + oldValue + " to " + newValue,
                                             attr, type,                    // name & type
                                             oldValue.getValue(),
                                             newValue.getValue()            // values
                                          );

      notifier.sendNotification(notif);
   }

   public MBeanNotificationInfo[] getNotificationInfo()
   {
      return info.getNotifications();
   }
  
   /**
   * @deprecated use {@link #addNotificationListener} instead
   */
   public void addAttributeChangeNotificationListener(
         NotificationListener listener,
         String attributeName,
         Object handback) throws MBeanException
   {
      AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
      filter.enableAttribute(attributeName);
      notifier.addNotificationListener(listener, filter, handback);
   }

   /**
   * @deprecated use {@link #removeNotificationListener} instead
   */
   public void removeAttributeChangeNotificationListener(
         NotificationListener listener,
         String attributeName) throws MBeanException, ListenerNotFoundException
   {
      notifier.removeNotificationListener(listener);
   }

   // PersistentMBean implementation --------------------------------
   public void load() throws MBeanException, InstanceNotFoundException
   {
      if (info == null)
         return;
     
      persistence.load(this, info);
   }

   public void store() throws MBeanException, InstanceNotFoundException
   {
      persistence.store(info);
   }

  
   // MBeanRegistration implementation ------------------------------
  
   /**
    * The default implementation of <tt>preRegister</tt> invokes the
    * {@link #configureInterceptorStack} method which sets up the interceptors
    * for this Model MBean instance. Subclasses may override the
    * <tt>configureInterceptorStack()</tt> method to implement their own
    * interceptor stack configurations. See the JavaDoc for
    * <tt>configureInterceptorStack()</tt> for more information.    <p>
    *
    * After the interceptor configuration, this implementation invokes the
    * {@link #load} method on this Model MBean instance. This will attempt
    * to load a pre-existing management attribute state for this Model MBean
    * instance. See the Javadoc for <tt>load()</tt> for more information.
    */
   public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
   {
      // initialize MBeanInfo first
      // add the resource classname to the MBean info
      ModelMBeanInfoSupport infoSupport = (ModelMBeanInfoSupport) info;
      Descriptor mbeanDescriptor = infoSupport.getMBeanDescriptor();
      mbeanDescriptor.setField(
        ModelMBeanConstants.RESOURCE_CLASS,
        getResource().getClass().getName());
      // make sure we call super to ensure the MBeanInvoker is initialized
      // before continuing
      super.preRegister(server, name);

      configureInterceptorStack((ModelMBeanInfo)info, server);

      initPersistence(server);
     
      load();
     
      return invokePreRegister(server, name);
   }

   public void postRegister(Boolean registrationSuccessful)
   {
      invokePostRegister(registrationSuccessful);
   }
  
   public void preDeregister() throws Exception
   {
      invokePreDeregister();
   }
  
   public void postDeregister()
   {
      invokePostDeregister();
   }

  
   // Protected ---------------------------------------------------

   /**
    * initializes the persistence manager based on the info for this bean.
    * If this is successful, loads the bean from the persistence store.
    * @todo Should log all errors using log4j
    */
   protected void initPersistence(MBeanServer server)
     throws MBeanException, InstanceNotFoundException
   {
     Descriptor[] descriptors;
     try { descriptors = ((ModelMBeanInfo)info).getDescriptors(MBEAN_DESCRIPTOR); }
     catch(MBeanException cause)
     {
       cause.printStackTrace();
       return;
     }
     if(descriptors == null) { return; }
     Object persistMgrName = null;
     for(int i = 0; ((i < descriptors.length) && (persistMgrName == null)); i++)
     {
       persistMgrName = descriptors[i].getFieldValue(PERSISTENCE_MANAGER);
     }
     if(persistMgrName == null) { return; } // use default -- null persistence
     try { persistence = (PersistenceManager) server.instantiate((String) persistMgrName); }
     catch(Exception cause)
     {
       log.error("Unable to instantiate the persistence manager.", cause);
     }
   }

  
   protected void initOperationContexts(MBeanOperationInfo[] operations)
   {
      // make sure we invoke the super class initialization sequence first
      super.initOperationContexts(operations);
     
      for (int i = 0; i < operations.length; ++i)
      {
         OperationKey key = new OperationKey(operations[i]);
        
         InvocationContext ctx = (InvocationContext)operationContextMap.get(key);
        
         ctx.setDescriptor(((ModelMBeanOperationInfo)operations[i]).getDescriptor());     
      }
   }
  
   protected void initAttributeContexts(MBeanAttributeInfo[] attributes)
   {
      super.initAttributeContexts(attributes);
     
      for (int i = 0; i < attributes.length; ++i)
      {
         InvocationContext ctx = (InvocationContext)attributeContextMap.get(attributes[i].getName());
        
         ctx.setDescriptor(((ModelMBeanAttributeInfo)attributes[i]).getDescriptor());
      }
   }
     
   protected void configureInterceptorStack(ModelMBeanInfo info, MBeanServer server)
     throws MBeanException
   {
  
      Iterator it = attributeContextMap.keySet().iterator();
     
      while (it.hasNext())
      {
         String key = (String)it.next();
        
         InvocationContext ctx = (InvocationContext)attributeContextMap.get(key);
         List list = (List)ctx.getInterceptors();
        
         // at minimum all model mbeans have this interceptor
         Interceptor interceptor = new ModelMBeanAttributeInterceptor();
         //interceptor.setLogger(log);
        
         list.add(interceptor);
      }
     
      List interceptors = getMBeanInfoCtx.getInterceptors();
      interceptors.add(new ModelMBeanInfoInterceptor());
      // @todo: review.  copied from prior version
      interceptors.add(new PersistenceInterceptor(
         server,
         this,
         info.getDescriptors(ALL_DESCRIPTORS)));
      // @todo: review.  end copy.
      getMBeanInfoCtx.setInterceptors(interceptors);
   }
  
   protected boolean isSupportedResourceType(Object resource, String resourceType)
   {
      if (resourceType.equals(OBJECT_REF))
         return true;
        
      return false;
   }
  
}
TOP

Related Classes of org.jboss.mx.modelmbean.ModelMBeanInvoker

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.