Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » system » [javadoc | source]
    1   /*
    2    * JBoss, Home of Professional Open Source
    3    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    4    * by the @authors tag. See the copyright.txt in the distribution for a
    5    * full listing of individual contributors.
    6    *
    7    * This is free software; you can redistribute it and/or modify it
    8    * under the terms of the GNU Lesser General Public License as
    9    * published by the Free Software Foundation; either version 2.1 of
   10    * the License, or (at your option) any later version.
   11    *
   12    * This software is distributed in the hope that it will be useful,
   13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15    * Lesser General Public License for more details.
   16    *
   17    * You should have received a copy of the GNU Lesser General Public
   18    * License along with this software; if not, write to the Free
   19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21    */
   22   package org.jboss.system;
   23   
   24   import java.util.ArrayList;
   25   import java.util.Iterator;
   26   import java.util.List;
   27   
   28   import javax.management.ObjectName;
   29   
   30   import org.jboss.logging.Logger;
   31   import org.jboss.mx.interceptor.AbstractInterceptor;
   32   import org.jboss.mx.interceptor.DynamicInterceptor;
   33   import org.jboss.mx.interceptor.Interceptor;
   34   import org.jboss.mx.server.Invocation;
   35   
   36   /**
   37    * Helper class that can be used for writing MBean Services
   38    * that dynamically hook-up an Interceptor to other (X)MBeans
   39    * that have been configured as Interceptable.
   40    * 
   41    * In a nutshell, call attach()/detach() from your
   42    * createService()/destroyService() or startService()/stopService()
   43    * pair methods to attach/detach an interceptor to the target mbean(s),
   44    * then override invoke() to do something with the invocations.
   45    * 
   46    * You may also provide your own Interceptor, in which case
   47    * you should call attach(Interceptor).
   48    * 
   49    * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
   50    * @version $Revision: 57108 $
   51    */
   52   public abstract class InterceptorServiceMBeanSupport extends ServiceMBeanSupport
   53      implements InterceptorServiceMBean
   54   {
   55      // Private Data --------------------------------------------------
   56      
   57      /** The Interceptables to attach to */
   58      private List interceptables;
   59      
   60      /** The attached interceptor */
   61      private Interceptor interceptor;
   62      
   63      // Constructors -------------------------------------------------
   64       
   65      /**
   66       * Constructs an <tt>InterceptorServiceMBeanSupport</tt>.
   67       */
   68      public InterceptorServiceMBeanSupport()
   69      {
   70           super();
   71      }
   72   
   73      /**
   74       * Constructs an <tt>InterceptorServiceMBeanSupport</tt>.
   75       *
   76       * Pass-through to ServiceMBeanSupport.
   77       *
   78       * @param type   The class type to determine Logger name from.
   79       */
   80      public InterceptorServiceMBeanSupport(final Class type)
   81      {
   82         super(type);
   83      }
   84      
   85      /**
   86       * Constructs an <tt>InterceptorServiceMBeanSupport</tt>.
   87       *
   88       * Pass-through to ServiceMBeanSupport.
   89       *
   90       * @param category   The logger category name.
   91       */
   92      public InterceptorServiceMBeanSupport(final String category)
   93      {
   94         super(category);
   95      }
   96   
   97      /**
   98       * Constructs an <tt>InterceptorServiceMBeanSupport</tt>.
   99       *
  100       * Pass-through to ServiceMBeanSupport.
  101       *
  102       * @param log   The logger to use.
  103       */
  104      public InterceptorServiceMBeanSupport(final Logger log)
  105      {
  106         super(log);
  107      }    
  108       
  109      // InterceptorServiceMBean ---------------------------------------
  110      
  111      public void setInterceptables(List interceptables)
  112      {
  113         // copy
  114         if (interceptables != null)
  115         {
  116            this.interceptables = new ArrayList(interceptables);
  117         }
  118      }
  119      
  120      public List getInterceptables()
  121      {
  122         // return a copy
  123         if (interceptables != null)
  124         {
  125            return new ArrayList(interceptables);
  126         }
  127         return null;
  128      }
  129      
  130      // Protected API -------------------------------------------------
  131      
  132      /**
  133       * Add our interceptor to the target Interceptables.
  134       * 
  135       * Override invoke(Invocation) to handle the calls.
  136       * 
  137       * @throws Exception thrown on any interceptor registration error
  138       */
  139      protected void attach() throws Exception
  140      {
  141         if (interceptor == null)
  142         {
  143            attach(new XMBeanInterceptor());
  144         }
  145      }
  146   
  147      /**
  148       * Add the provided interceptor to the target Interceptables.
  149       * 
  150       * @param interceptor the interceptor to add
  151       * @throws Exception thrown on any interceptor registration error
  152       */
  153      protected void attach(Interceptor interceptor) throws Exception
  154      {
  155         if (interceptor == null)
  156         {
  157            throw new IllegalArgumentException("Null interceptor");
  158         }
  159         
  160         // check we haven't attached already
  161         if (this.interceptor != null)
  162         {
  163            throw new IllegalStateException("Interceptor already attached");
  164         }
  165         
  166         log.debug("Attaching interceptor: " + interceptor.getName());
  167         
  168         // remember the interceptor
  169         this.interceptor = interceptor;
  170         
  171         // add the interceptor to the Interceptables; an exception
  172         // will be thrown if any of them is not Interceptable,
  173         // in which case detach() should be called.
  174         if (interceptables != null)
  175         {
  176            Object[] params = new Object[] { interceptor };
  177            String[] signature = new String[] { Interceptor.class.getName() };
  178            
  179            for (Iterator i = interceptables.iterator(); i.hasNext(); )
  180            {
  181               ObjectName target = (ObjectName)i.next();
  182               super.server.invoke(target,
  183                  DynamicInterceptor.ADD_INTERCEPTOR,
  184                  params,
  185                  signature);
  186               
  187               log.debug("Interceptor attached to: '" + target + "'");
  188            }
  189         }
  190      }
  191      
  192      /**
  193       * Remove the interceptor from the target Interceptables
  194       */
  195      protected void detach()
  196      {
  197         if (interceptor != null)
  198         {
  199            log.debug("Detaching interceptor: " + interceptor.getName());         
  200            if (interceptables != null)
  201            {
  202               Object[] params = new Object[] { interceptor };
  203               String[] signature = new String[] { Interceptor.class.getName() };
  204               
  205               for (Iterator i = interceptables.iterator(); i.hasNext(); )            
  206               {
  207                  ObjectName target = (ObjectName)i.next();               
  208                  try
  209                  {
  210                     super.server.invoke(target,
  211                        DynamicInterceptor.REMOVE_INTERCEPTOR,
  212                        params,
  213                        signature);
  214                     
  215                     log.debug("Interceptor detached from: '" + target + "'");                  
  216                  }
  217                  catch (Exception e)
  218                  {
  219                     log.debug("Caught exception while removing interceptor from '" +
  220                           target + "'", e);
  221                  }
  222               }
  223            }
  224            interceptor = null;
  225         }
  226      }
  227      
  228      /**
  229       * Use this to forward the call
  230       */
  231      protected Object invokeNext(Invocation invocation) throws Throwable
  232      {
  233         // call the next in the interceptor chain,
  234         // if nobody follows dispatch the call
  235         Interceptor next = invocation.nextInterceptor();
  236         if (next != null)
  237         {
  238            return next.invoke(invocation);
  239         }
  240         else
  241         {
  242            return invocation.dispatch();
  243         }
  244      }
  245      
  246      // Override ------------------------------------------------------
  247      
  248      /**
  249       * Override
  250       */
  251      protected Object invoke(Invocation invocation) throws Throwable
  252      {
  253         return invokeNext(invocation);
  254      }
  255      
  256      // Private Inner Class -------------------------------------------
  257      
  258      /**
  259       * Simple Interceptor delegating to
  260       * the invoke(Invocation) callback
  261       */   
  262      private class XMBeanInterceptor extends AbstractInterceptor
  263      {
  264         public XMBeanInterceptor()
  265         {
  266            super("XMBeanInterceptor('" + InterceptorServiceMBeanSupport.this.getServiceName() + "')");
  267         }
  268         
  269         public Object invoke(Invocation invocation) throws Throwable
  270         {
  271            // delegate
  272            return InterceptorServiceMBeanSupport.this.invoke(invocation);
  273         }
  274      }
  275   }    

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » system » [javadoc | source]