Package org.jboss.mx.interceptor

Source Code of org.jboss.mx.interceptor.AbstractSharedInterceptor

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

import java.util.Set;
import java.util.Hashtable;

import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.MBeanException;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import javax.management.modelmbean.RequiredModelMBean;

import org.jboss.mx.server.Invocation;
import org.jboss.mx.server.InvocationException;

import org.jboss.mx.server.ServerConstants;
import org.jboss.mx.service.ServiceConstants;
import org.jboss.mx.modelmbean.ModelMBeanConstants;

import org.jboss.mx.util.AgentID;

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


/**
* Base class for shared interceptors. This class provides some default method
* implementations for shared interceptors.
*
* @see org.jboss.mx.interceptor.SharedInterceptor
* @see org.jboss.mx.server.MBeanInvoker
*
* @author  <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
* @version $Revision: 1.3 $  
*/
public abstract class AbstractSharedInterceptor
   extends AbstractInterceptor
   implements SharedInterceptor
{

   /**
    * MBean server reference for shared interceptors.
    */
   protected MBeanServer server     = null;
  
   /**
    * Object name of this interceptor. Shared interceptors must always contain
    * a valid object name.
    */
   protected ObjectName objectName  = null;
  
  
   // Constructors --------------------------------------------------
  
   /**
    * Constructs a new shared interceptor instance. The interceptor is not
    * automatically registered to the MBean server. Notice that the interceptor
    * name must be set before the call to {@link #register} method. Shared
    * interceptor names must be unique within the MBean server.
    */
   public AbstractSharedInterceptor() {}
  
   /**
    * Constructs a new shared interceptor instance with a given name. The interceptor
    * is not automatically registered to the MBean server. Notice that the
    * shared interceptor name must be unique name among all shared interceptors
    * within the MBean server.
    *
    * @param name name of this interceptor
    *
    * @throws IllegalArgumentException if name contains <tt>null</tt> reference
    */
   public AbstractSharedInterceptor(String name)
   {
      super(name);
   }
  
  
   // SharedInterceptor implementation ------------------------------
  
   public ObjectName getObjectName()
   {
      return objectName;
   }
  
   public MBeanServer getMBeanServer()
   {
      return server;
   }
  
   /**
    * Registers the interceptor to the MBean server.  <p>
    *
    * The interceptor is registered under the
    * {@link org.jboss.mx.service.ServiceConstants#JBOSSMX_DOMAIN JBOSSMX_DOMAIN}
    * name. An interceptor's object name contains a <tt>type</tt> property and
    * a <tt>name</tt> property. Property <tt>type</tt> always contains string
    * <tt>'Interceptor'</tt> as its value. Interceptor's name is used as a value
    * for the <tt>name</tt> property. Therefore, an interceptor created with
    * name <tt>'Bart'</tt> can be found from the MBean server under object name:   <br><pre>
    *
    *    {@link org.jboss.mx.service.ServiceConstants#JBOSSMX_DOMAIN JBOSSMX_DOMAIN}:type=Interceptor,name=Bart,*
    *
    * </pre>
    *
    * If the log reference has not been set for this interceptor when it is
    * registered, this implementation will register a log MBean via the system
    * log manager under {@link org.jboss.mx.service.ServiceConstants#JBOSSMX_DOMAIN JBOSSMX}
    * domain (see {@link org.jboss.mx.logging.SystemLogManager SystemLogManager}
    * for details). The log instance's name will match the pattern:   <br><pre>
    *
    *    "JBossMX.Interceptor.&lt;interceptor name&gt;"
    *
    * </pre>
    *
    * @param   server   MBean server where this shared interceptor is registered
    */
   public synchronized ObjectName register(MBeanServer server)
         throws InterceptorNameConflictException
   {
     
      // store MBean server reference
      this.server = server;
     
      // check if log instance has been set
      if (log == null)
      {
         // attempt to create a logger MBean
         try
         {
            ObjectName logManager = new ObjectName(ServerConstants.SYSTEM_LOG_MANAGER);
           
            this.log = (Logger)server.invoke(
                  logManager, "getLogger",
                  new Object[] { "JBossMX.Interceptor." + name },
                  new String[] { String.class.getName() }
            );
         }
         catch (Exception e) {
           
            // shouldn't happen
            log = SystemLogger.getLogger("JBossMX.Interceptor." + name);
         }
      }
        
      try
      {
         // store the object name for later use
         objectName = createObjectName();
     
         // query the server for this name
         Set names = server.queryNames(objectName, null /* NO QUERY EXPR. */);
        
         // if the query returns a non empty set, throw an exception
         if (names.size() > 0)
            throw new InterceptorNameConflictException(
                  "A shared interceptor named '" + name + "' already registered " +
                  "to this MBean server (" + AgentID.get(server) + ")"
            );
           
         // register the interceptor to server
         RequiredModelMBean rmm = new RequiredModelMBean();
         rmm.setManagedResource(this, ModelMBeanConstants.OBJECT_REF);
         rmm.setModelMBeanInfo(getManagementInterface());
         server.registerMBean(rmm, objectName);
        
         // mark the interceptor as shared
         isShared = true;
      }
     
      catch (InstanceAlreadyExistsException e)
      {
         // we already checked that the instance doesn't exist with a query,
         // however it is possible it was created by another thread before we
         // actually had a chance to register
         throw new InterceptorNameConflictException(
               "A shared interceptor named '" + name + "' already registered " +
               "to this MBean server (" + AgentID.get(server) + ")"
         );
      }
     
      catch (Exception e)
      {
         // anything else indicates there's something much more wrong if
         // we can't register a simple MBean, so just log an error
         if (log != null)
            log.error(e.toString(), e);
      }
     
      return objectName;
   }

   /**
    * This method is part of the interceptor MBean's registration lifecycle.
    * It is called before the MBean is registered to the server. Concrete
    * interceptor implementations can override this method to provide
    * initialization code that should be executed before the interceptor
    * is registered.   <p>
    *
    * Any exception that is propagated from this method to its caller will
    * cancel the interceptor registration.
    *
    * @throws Exception if you want to cancel the interceptor registration
    */
   public void init() throws Exception {}

   /**
    * This method is part of the interceptor MBean's registration lifecycle.
    * It is called after the MBean is registered to the server. Concrete
    * interceptor implementations can override this method to provide
    * initialization code that should be executed once the MBean server and
    * object name references for this interceptor have been resolved.
    */
   public void start() {}

   /**
    * This method is part of the interceptor MBean's registration lifecycle.
    * It is called before the MBean is unregistered from the server. Concrete
    * interceptor implementations can override this method to provide
    * cleanup code that should be executed before the interceptor is
    * unregistered.   <p>
    *
    * Any exception that is propagated from this method to its caller will
    * cancel the interceptor unregistration.
    *
    * @throws Exception if you want to cancel the interceptor unregistration
    */
   public void stop() throws Exception {}

   /**
    * This method is part of the interceptor MBean's registration lifecycle.
    * It is called after the MBean has been unregistered from the server. Concrete
    * interceptor implementations can override this method to provide
    * cleanup code that should be executed once the interceptor is no longer
    * registered to the MBean server.
    */
   public void destroy() {}

  
   // MBeanRegistration implementation ------------------------------
  
   public ObjectName preRegister(MBeanServer server, ObjectName oname) throws Exception
   {
      this.server = server;
     
      if (oname == null)
         this.objectName = createObjectName();
      else 
         this.objectName = oname;
    
      init();
     
      return objectName;
   }
  
   public void postRegister(Boolean registrationSuccesful) {
      isShared = true;
     
      start();
   }
  
   public void preDeregister() throws Exception {
      stop();

      isShared    = false;
      objectName  = null;     
   }
  
   public void postDeregister() {
      destroy();
   }
  
  
   // AbstractInterceptor overrides ---------------------------------
  
   /**
    * Shared interceptors allows their name to be set only before they have
    * been registered to the MBean server. After that the name is fixed and
    * any attempt to invoke this method to change the name will yield a
    * IllegalArgumentException.
    *
    * @param   name  name of this shared interceptor
    *
    * @throws IllegalArgumentException if there was an attempt to change the
    *         name after the interceptor had been registered to the server
    */
   public synchronized void setName(String name)
   {
      if (isShared())
         throw new IllegalArgumentException("Cannot change the interceptor name. Already registered.");
        
      this.name = name;
   }     
  
  
   // Object overrides ----------------------------------------------

   /**
    * Returns a string representation of this interceptor instance.
    *
    * @return  string representation
    */
   public String toString()
   {
      String className = getClass().getName();
      int index        = className.lastIndexOf('.');
     
      return className.substring((index < 0) ? 0 : index) + "[" +
             "name=" + name + "SHARED " + objectName + "]";
   }
  
  
   // Protected -----------------------------------------------------
  
   /**
    * Creates an object name for this interceptor.  The object name contains a
    * <tt>type</tt> property and a <tt>name</tt> property. Property <tt>type</tt>
    * always contains string <tt>'Interceptor'</tt> as its value. Interceptor's
    * name is used as a value for the <tt>name</tt> property. Therefore, an
    * interceptor created with name <tt>'Bart'</tt> will generate an object name
    * matching to pattern:   <br><pre>
    *
    *    {@link org.jboss.mx.service.ServiceConstants#JBOSSMX_DOMAIN JBOSSMX_DOMAIN}:type=Interceptor,name=Bart,*
    *
    * </pre>
    *
    * @return  generated object name for this interceptor
    *
    * @throws MalformedObjectNameException if the object name could not be
    *         created
    */
   protected ObjectName createObjectName() throws MalformedObjectNameException
   {
      // create the object name for this shared interceptor
      Hashtable props = new Hashtable(2);
      props.put("type", "Interceptor");
      props.put("name", name);
      props.put("ID", "0");
     
      return new ObjectName(ServiceConstants.JBOSSMX_DOMAIN, props);
   }

  
   // Private -------------------------------------------------------
  
   private ModelMBeanInfo getManagementInterface()
   {
      return new ModelMBeanInfoSupport(
         this.getClass().getName(),             // resource object class name
         "Interceptor invocation interface",    // description of the MBean
        
         null,                                  // attributes
        
         null,                                  // constructors
        
         new ModelMBeanOperationInfo[]          // operations
         {
            new ModelMBeanOperationInfo(
                  "invoke",                                 // name
                  "Shared interceptor invoke operation.",   // description
                  new MBeanParameterInfo[]                  // arguments
                  {
                     new MBeanParameterInfo(
                           "invocation",                    // name
                           Invocation.class.getName(),      // type
                           "The invocation object."         // description
                     )
                  },
                  Object.class.getName(),        // return type
                  MBeanOperationInfo.ACTION_INFO // impact
            )
         },
        
         null                                   // notifications
      );
   }
  
}


TOP

Related Classes of org.jboss.mx.interceptor.AbstractSharedInterceptor

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.