All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.system.InterceptorServiceMBeanSupport Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * 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.jboss.system;

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

import javax.management.ObjectName;

import org.jboss.logging.Logger;
import org.jboss.mx.interceptor.AbstractInterceptor;
import org.jboss.mx.interceptor.DynamicInterceptor;
import org.jboss.mx.interceptor.Interceptor;
import org.jboss.mx.server.Invocation;

/**
 * Helper class that can be used for writing MBean Services
 * that dynamically hook-up an Interceptor to other (X)MBeans
 * that have been configured as Interceptable.
 * 
 * In a nutshell, call attach()/detach() from your
 * createService()/destroyService() or startService()/stopService()
 * pair methods to attach/detach an interceptor to the target mbean(s),
 * then override invoke() to do something with the invocations.
 * 
 * You may also provide your own Interceptor, in which case
 * you should call attach(Interceptor).
 * 
 * @author Dimitris Andreadis
 * @version $Revision: 86477 $
 */
@SuppressWarnings("unchecked")
public abstract class InterceptorServiceMBeanSupport extends ServiceMBeanSupport
   implements InterceptorServiceMBean
{
   // Private Data --------------------------------------------------
   
   /** The Interceptables to attach to */
   private List interceptables;
   
   /** The attached interceptor */
   private Interceptor interceptor;
   
   // Constructors -------------------------------------------------
    
   /**
    * Constructs an InterceptorServiceMBeanSupport.
    */
   public InterceptorServiceMBeanSupport()
   {
        super();
   }

   /**
    * Constructs an InterceptorServiceMBeanSupport.
    *
    * Pass-through to ServiceMBeanSupport.
    *
    * @param type   The class type to determine Logger name from.
    */
   public InterceptorServiceMBeanSupport(final Class type)
   {
      super(type);
   }
   
   /**
    * Constructs an InterceptorServiceMBeanSupport.
    *
    * Pass-through to ServiceMBeanSupport.
    *
    * @param category   The logger category name.
    */
   public InterceptorServiceMBeanSupport(final String category)
   {
      super(category);
   }

   /**
    * Constructs an InterceptorServiceMBeanSupport.
    *
    * Pass-through to ServiceMBeanSupport.
    *
    * @param log   The logger to use.
    */
   public InterceptorServiceMBeanSupport(final Logger log)
   {
      super(log);
   }    
    
   // InterceptorServiceMBean ---------------------------------------
   
   public void setInterceptables(List interceptables)
   {
      // copy
      if (interceptables != null)
      {
         this.interceptables = new ArrayList(interceptables);
      }
   }
   
   public List getInterceptables()
   {
      // return a copy
      if (interceptables != null)
      {
         return new ArrayList(interceptables);
      }
      return null;
   }
   
   // Protected API -------------------------------------------------
   
   /**
    * Add our interceptor to the target Interceptables.
    * 
    * Override invoke(Invocation) to handle the calls.
    * 
    * @throws Exception thrown on any interceptor registration error
    */
   protected void attach() throws Exception
   {
      if (interceptor == null)
      {
         attach(new XMBeanInterceptor());
      }
   }

   /**
    * Add the provided interceptor to the target Interceptables.
    * 
    * @param interceptor the interceptor to add
    * @throws Exception thrown on any interceptor registration error
    */
   protected void attach(Interceptor interceptor) throws Exception
   {
      if (interceptor == null)
      {
         throw new IllegalArgumentException("Null interceptor");
      }
      
      // check we haven't attached already
      if (this.interceptor != null)
      {
         throw new IllegalStateException("Interceptor already attached");
      }
      
      log.debug("Attaching interceptor: " + interceptor.getName());
      
      // remember the interceptor
      this.interceptor = interceptor;
      
      // add the interceptor to the Interceptables; an exception
      // will be thrown if any of them is not Interceptable,
      // in which case detach() should be called.
      if (interceptables != null)
      {
         Object[] params = new Object[] { interceptor };
         String[] signature = new String[] { Interceptor.class.getName() };
         
         for (Iterator i = interceptables.iterator(); i.hasNext(); )
         {
            ObjectName target = (ObjectName)i.next();
            super.server.invoke(target,
               DynamicInterceptor.ADD_INTERCEPTOR,
               params,
               signature);
            
            log.debug("Interceptor attached to: '" + target + "'");
         }
      }
   }
   
   /**
    * Remove the interceptor from the target Interceptables
    */
   protected void detach()
   {
      if (interceptor != null)
      {
         log.debug("Detaching interceptor: " + interceptor.getName());         
         if (interceptables != null)
         {
            Object[] params = new Object[] { interceptor };
            String[] signature = new String[] { Interceptor.class.getName() };
            
            for (Iterator i = interceptables.iterator(); i.hasNext(); )            
            {
               ObjectName target = (ObjectName)i.next();               
               try
               {
                  super.server.invoke(target,
                     DynamicInterceptor.REMOVE_INTERCEPTOR,
                     params,
                     signature);
                  
                  log.debug("Interceptor detached from: '" + target + "'");                  
               }
               catch (Exception e)
               {
                  log.debug("Caught exception while removing interceptor from '" +
                        target + "'", e);
               }
            }
         }
         interceptor = null;
      }
   }
   
   /**
    * Use this to forward the call
    * @param invocation 
    * @return the result
    * @throws Throwable 
    */
   protected Object invokeNext(Invocation invocation) throws Throwable
   {
      // call the next in the interceptor chain,
      // if nobody follows dispatch the call
      Interceptor next = invocation.nextInterceptor();
      if (next != null)
      {
         return next.invoke(invocation);
      }
      else
      {
         return invocation.dispatch();
      }
   }
   
   // Override ------------------------------------------------------
   
   protected Object invoke(Invocation invocation) throws Throwable
   {
      return invokeNext(invocation);
   }
   
   // Private Inner Class -------------------------------------------
   
   /**
    * Simple Interceptor delegating to
    * the invoke(Invocation) callback
    */   
   private class XMBeanInterceptor extends AbstractInterceptor
   {
      public XMBeanInterceptor()
      {
         super("XMBeanInterceptor('" + InterceptorServiceMBeanSupport.this.getServiceName() + "')");
      }
      
      public Object invoke(Invocation invocation) throws Throwable
      {
         // delegate
         return InterceptorServiceMBeanSupport.this.invoke(invocation);
      }
   }
}    




© 2015 - 2024 Weber Informatics LLC | Privacy Policy