[jbosscache-commits] JBoss Cache SVN: r6541 - in core/trunk/src: main/java/org/jboss/cache/factories and 6 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Aug 7 14:43:09 EDT 2008


Author: mircea.markus
Date: 2008-08-07 14:43:08 -0400 (Thu, 07 Aug 2008)
New Revision: 6541

Added:
   core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatisticsInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatsCommandInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java
   core/trunk/src/main/java/org/jboss/cache/jmx/annotations/
   core/trunk/src/main/java/org/jboss/cache/jmx/annotations/MBean.java
   core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedAttribute.java
   core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedOperation.java
   core/trunk/src/test/java/org/jboss/cache/jmx/ResourceDMBeanTest.java
Removed:
   core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptorMBean.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptorMBean.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/CacheSPI.java
   core/trunk/src/main/java/org/jboss/cache/DefaultCacheFactory.java
   core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
   core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyActivationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/base/CommandInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java
   core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapperMBean.java
   core/trunk/src/main/java/org/jboss/cache/jmx/JmxUtil.java
   core/trunk/src/test/java/org/jboss/cache/jmx/CacheJmxWrapperTestBase.java
   core/trunk/src/test/java/org/jboss/cache/jmx/InterceptorRegistrationTest.java
Log:
JBCACHE-1305 - JMX through annotations

Modified: core/trunk/src/main/java/org/jboss/cache/CacheSPI.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/CacheSPI.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/CacheSPI.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -18,6 +18,7 @@
 import org.jboss.cache.statetransfer.StateTransferManager;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.transaction.TransactionTable;
+import org.jboss.cache.factories.ComponentRegistry;
 
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
@@ -329,4 +330,11 @@
     * @return Set an unmodifiable set of children names, Object.
     */
    Set<String> getChildrenNames(String fqn);
+
+   /**
+    * Returns the component registry associated with this cache instance.
+    *
+    * @see org.jboss.cache.factories.ComponentRegistry
+    */
+   ComponentRegistry getComponentRegistry();
 }

Modified: core/trunk/src/main/java/org/jboss/cache/DefaultCacheFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/DefaultCacheFactory.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/DefaultCacheFactory.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -14,8 +14,12 @@
 import org.jboss.cache.factories.ComponentFactory;
 import org.jboss.cache.factories.ComponentRegistry;
 import org.jboss.cache.invocation.CacheInvocationDelegate;
+import org.jboss.cache.jmx.MBeanRegistryHelper;
+import org.jboss.cache.jmx.CacheJmxWrapper;
+import org.jboss.cache.jmx.ResourceDMBean;
 
 import java.io.InputStream;
+import java.util.Set;
 
 /**
  * Default implementation of the {@link org.jboss.cache.CacheFactory} interface.
@@ -123,6 +127,10 @@
       this.configuration = configuration;
 
       componentRegistry.registerComponent(spi, CacheSPI.class);
+      if (configuration.getExposeManagementStatistics())
+      {
+         componentRegistry.registerComponent(new MBeanRegistryHelper(componentRegistry), MBeanRegistryHelper.class);
+      }
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -920,6 +920,16 @@
       {
          for (Method m : injectionMethods) invokeInjectionMethod(instance, m);
       }
+
+      public Object getInstance()
+      {
+         return instance;
+      }
+
+      public String getName()
+      {
+         return name;
+      }
    }
 
 
@@ -951,4 +961,13 @@
                '}';
       }
    }
+
+   /**
+    * Returns an immutable set contating all the components that exists in the reporsitory at this moment.
+    */
+   public Set<Component> getRegiteredComponents()
+   {
+      HashSet<Component> defensiveCopy = new HashSet<Component>(componentLookup.values());
+      return Collections.unmodifiableSet(defensiveCopy);
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -49,7 +49,6 @@
          // wipe next/last chaining!!
          chainedInterceptor.setNext(null);
       }
-      chainedInterceptor.setStatisticsEnabled(configuration.getExposeManagementStatistics());
       return chainedInterceptor;
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -3,6 +3,8 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InternalNode;
 import org.jboss.cache.Modification;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
@@ -40,7 +42,7 @@
  * @author <a href="mailto:{hmesha at novell.com}">{Hany Mesha}</a>
  * @version $Id$
  */
-public class ActivationInterceptor extends CacheLoaderInterceptor implements ActivationInterceptorMBean
+public class ActivationInterceptor extends CacheLoaderInterceptor
 {
 
    protected TransactionManager txMgr = null;
@@ -263,30 +265,6 @@
       }
    }
 
-   public long getActivations()
-   {
-      return activations;
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      super.resetStatistics();
-      activations = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = super.dumpStatistics();
-      if (retval == null)
-      {
-         retval = new HashMap<String, Object>();
-      }
-      retval.put("Activations", activations);
-      return retval;
-   }
-
    private void prepareCacheLoader(InvocationContext ctx) throws Throwable
    {
       GlobalTransaction gtx = ctx.getGlobalTransaction();
@@ -308,6 +286,7 @@
    {
 
       private List<Modification> cacheLoaderModifications = new ArrayList<Modification>();
+
       private int txActs = 0;
 
       @Override
@@ -387,5 +366,31 @@
       {
          return txActs;
       }
+
    }
+
+   @ManagedAttribute(description = "number of cache node activations")
+   public long getActivations()
+   {
+      return activations;
+   }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      super.resetStatistics();
+      activations = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = super.dumpStatistics();
+      if (retval == null)
+      {
+         retval = new HashMap<String, Object>();
+      }
+      retval.put("Activations", activations);
+      return retval;
+   }
 }

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/ActivationInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing activation statistics
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface ActivationInterceptorMBean extends CacheLoaderInterceptorMBean
-{
-   /**
-    * Returns the number of cache node activations
-    * 
-    * @return the number of cache node activations
-    */
-   long getActivations();
-
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -5,6 +5,9 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InternalNode;
 import org.jboss.cache.NodeSPI;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
+import org.jboss.cache.jmx.annotations.MBean;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetDataMapCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
@@ -24,6 +27,7 @@
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.Start;
 import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.interceptors.base.JmxStatsCommandInterceptor;
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.loader.CacheLoader;
 import org.jboss.cache.loader.CacheLoaderManager;
@@ -45,7 +49,7 @@
  * @author Bela Ban
  * @version $Id$
  */
-public class CacheLoaderInterceptor extends CommandInterceptor implements CacheLoaderInterceptorMBean
+public class CacheLoaderInterceptor extends JmxStatsCommandInterceptor
 {
    private long cacheLoads = 0;
    private long cacheMisses = 0;
@@ -397,32 +401,6 @@
       return false;
    }
 
-   public long getCacheLoaderLoads()
-   {
-      return cacheLoads;
-   }
-
-   public long getCacheLoaderMisses()
-   {
-      return cacheMisses;
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      cacheLoads = 0;
-      cacheMisses = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("CacheLoaderLoads", cacheLoads);
-      retval.put("CacheLoaderMisses", cacheMisses);
-      return retval;
-   }
-
    /**
     * Loads a node from disk; if it exists creates parent TreeNodes.
     * If it doesn't exist on disk but in memory, clears the
@@ -483,4 +461,31 @@
       return nodeData;
    }
 
+   @ManagedAttribute (description = "number of cache loader node loads")
+   public long getCacheLoaderLoads()
+   {
+      return cacheLoads;
+   }
+
+   @ManagedAttribute (description = "number of cache loader node misses")
+   public long getCacheLoaderMisses()
+   {
+      return cacheMisses;
+   }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      cacheLoads = 0;
+      cacheMisses = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = new HashMap<String, Object>();
+      retval.put("CacheLoaderLoads", cacheLoads);
+      retval.put("CacheLoaderMisses", cacheMisses);
+      return retval;
+   }
 }
\ No newline at end of file

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,45 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing cache loader load statistics
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface CacheLoaderInterceptorMBean extends InterceptorMBean
-{
-   /**
-    * Returns the number of cache loader node loads
-    * 
-    * @return the number of cache loader node loads
-    */
-   long getCacheLoaderLoads();
-   
-   /**
-    * Returns the number of cache loader node misses
-    * 
-    * @return the number of cache loader node misses
-    */
-   long getCacheLoaderMisses();
-
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -22,13 +22,15 @@
 package org.jboss.cache.interceptors;
 
 import org.jboss.cache.DataContainer;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
 import org.jboss.cache.commands.write.EvictCommand;
 import org.jboss.cache.commands.write.PutDataMapCommand;
 import org.jboss.cache.commands.write.PutForExternalReadCommand;
 import org.jboss.cache.commands.write.PutKeyValueCommand;
 import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.interceptors.base.JmxStatsCommandInterceptor;
 import org.jboss.cache.invocation.InvocationContext;
 
 import java.util.HashMap;
@@ -40,17 +42,17 @@
  * @author Jerry Gauthier
  * @version $Id$
  */
-public class CacheMgmtInterceptor extends CommandInterceptor implements CacheMgmtInterceptorMBean
+public class CacheMgmtInterceptor extends JmxStatsCommandInterceptor
 {
-   private long m_hit_times = 0;
-   private long m_miss_times = 0;
-   private long m_store_times = 0;
-   private long m_hits = 0;
-   private long m_misses = 0;
-   private long m_stores = 0;
-   private long m_evictions = 0;
-   private long m_start = System.currentTimeMillis();
-   private long m_reset = m_start;
+   private long hitTimes = 0;
+   private long missTimes = 0;
+   private long storeTimes = 0;
+   private long hits = 0;
+   private long misses = 0;
+   private long stores = 0;
+   private long evictions = 0;
+   private long start = System.currentTimeMillis();
+   private long reset = start;
 
    private DataContainer dataContainer;
 
@@ -64,7 +66,7 @@
    public Object visitEvictFqnCommand(InvocationContext ctx, EvictCommand command) throws Throwable
    {
       Object returnValue = invokeNextInterceptor(ctx, command);
-      m_evictions++;
+      evictions++;
       return returnValue;
    }
 
@@ -76,13 +78,13 @@
       long t2 = System.currentTimeMillis();
       if (retval == null)
       {
-         m_miss_times = m_miss_times + (t2 - t1);
-         m_misses++;
+         missTimes = missTimes + (t2 - t1);
+         misses++;
       }
       else
       {
-         m_hit_times = m_hit_times + (t2 - t1);
-         m_hits++;
+         hitTimes = hitTimes + (t2 - t1);
+         hits++;
       }
       return retval;
    }
@@ -97,8 +99,8 @@
 
       if (data != null && data.size() > 0)
       {
-         m_store_times = m_store_times + (t2 - t1);
-         m_stores = m_stores + data.size();
+         storeTimes = storeTimes + (t2 - t1);
+         stores = stores + data.size();
       }
       return retval;
    }
@@ -116,89 +118,101 @@
       long t1 = System.currentTimeMillis();
       Object retval = invokeNextInterceptor(ctx, command);
       long t2 = System.currentTimeMillis();
-      m_store_times = m_store_times + (t2 - t1);
-      m_stores++;
+      storeTimes = storeTimes + (t2 - t1);
+      stores++;
       return retval;
    }
 
+   @ManagedAttribute(description = "number of cache attribute hits")
    public long getHits()
    {
-      return m_hits;
+      return hits;
    }
 
+   @ManagedAttribute (description = "number of cache attribute misses")
    public long getMisses()
    {
-      return m_misses;
+      return misses;
    }
 
+   @ManagedAttribute (description = "number of cache attribute put operations")
    public long getStores()
    {
-      return m_stores;
+      return stores;
    }
 
+   @ManagedAttribute (description = "number of cache eviction operations")
    public long getEvictions()
    {
-      return m_evictions;
+      return evictions;
    }
 
+   @ManagedAttribute (description = "hit/miss ratio for the cache")
    public double getHitMissRatio()
    {
-      double total = m_hits + m_misses;
+      double total = hits + misses;
       if (total == 0)
          return 0;
-      return (m_hits / total);
+      return (hits / total);
    }
 
+   @ManagedAttribute (description = "read/writes ratio for the cache")
    public double getReadWriteRatio()
    {
-      if (m_stores == 0)
+      if (stores == 0)
          return 0;
-      return (((double) (m_hits + m_misses) / (double) m_stores));
+      return (((double) (hits + misses) / (double) stores));
    }
 
+   @ManagedAttribute (description = "average number of milliseconds for a read operation")
    public long getAverageReadTime()
    {
-      long total = m_hits + m_misses;
+      long total = hits + misses;
       if (total == 0)
          return 0;
-      return (m_hit_times + m_miss_times) / total;
+      return (hitTimes + missTimes) / total;
    }
 
+   @ManagedAttribute (description = "average number of milliseconds for a write operation")
    public long getAverageWriteTime()
    {
-      if (m_stores == 0)
+      if (stores == 0)
          return 0;
-      return (m_store_times) / m_stores;
+      return (storeTimes) / stores;
    }
 
+   @ManagedAttribute (description = "number of cache eviction operations")
    public int getNumberOfAttributes()
    {
       return dataContainer.getNumberOfAttributes();
    }
 
+   @ManagedAttribute
    public int getNumberOfNodes()
    {
       return dataContainer.getNumberOfNodes();
    }
 
+   @ManagedAttribute (description = "seconds since cache started")
    public long getElapsedTime()
    {
-      return (System.currentTimeMillis() - m_start) / 1000;
+      return (System.currentTimeMillis() - start) / 1000;
    }
 
+   @ManagedAttribute (description = "number of seconds since the cache statistics were last reset")
    public long getTimeSinceReset()
    {
-      return (System.currentTimeMillis() - m_reset) / 1000;
+      return (System.currentTimeMillis() - reset) / 1000;
    }
 
-   @Override
+   @ManagedOperation
    public Map<String, Object> dumpStatistics()
    {
       Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("Hits", m_hits);
-      retval.put("Misses", m_misses);
-      retval.put("Stores", m_stores);
-      retval.put("Evictions", m_evictions);
+      retval.put("Hits", hits);
+      retval.put("Misses", misses);
+      retval.put("Stores", stores);
+      retval.put("Evictions", evictions);
       retval.put("NumberOfAttributes", dataContainer.getNumberOfAttributes());
       retval.put("NumberOfNodes", dataContainer.getNumberOfNodes());
       retval.put("ElapsedTime", getElapsedTime());
@@ -210,17 +224,17 @@
       return retval;
    }
 
-   @Override
+   @ManagedOperation
    public void resetStatistics()
    {
-      m_hits = 0;
-      m_misses = 0;
-      m_stores = 0;
-      m_evictions = 0;
-      m_hit_times = 0;
-      m_miss_times = 0;
-      m_store_times = 0;
-      m_reset = System.currentTimeMillis();
+      hits = 0;
+      misses = 0;
+      stores = 0;
+      evictions = 0;
+      hitTimes = 0;
+      missTimes = 0;
+      storeTimes = 0;
+      reset = System.currentTimeMillis();
    }
 }
 

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheMgmtInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,109 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing basic cache management statistics
- *
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface CacheMgmtInterceptorMBean extends InterceptorMBean
-{
-   /**
-    * Returns the number of cache attribute hits
-    *
-    * @return the number of cache hits
-    */
-   long getHits();
-
-   /**
-    * Returns the number of cache attribute misses
-    *
-    * @return the number of cache misses
-    */
-   long getMisses();
-
-   /**
-    * Returns the number of cache attribute put operations
-    *
-    * @return the number of cache put operations
-    */
-   long getStores();
-
-   /**
-    * Returns the number of cache eviction operations
-    *
-    * @return the number of cache eviction operations
-    */
-   long getEvictions();
-
-   int getNumberOfAttributes();
-
-   int getNumberOfNodes();
-
-   /**
-    * Returns the hit/miss ratio for the cache
-    * This ratio is defined as hits/(hits + misses)
-    *
-    * @return the hit/miss ratio for the cache
-    */
-   double getHitMissRatio();
-
-   /**
-    * Returns the read/write ratio for the cache
-    * This ratio is defined as (hits + misses)/stores
-    *
-    * @return the read/writes ratio for the cache
-    */
-   double getReadWriteRatio();
-
-   /**
-    * Returns average milliseconds for an attribute read operation
-    * This includes both hits and misses.
-    *
-    * @return the average number of milliseconds for a read operation
-    */
-   long getAverageReadTime();
-
-   /**
-    * Returns average milliseconds for an attribute write operation
-    *
-    * @return the average number of milliseconds for a write operation
-    */
-   long getAverageWriteTime();
-
-   /**
-    * Returns seconds since cache started
-    *
-    * @return the number of seconds since the cache was started
-    */
-   long getElapsedTime();
-
-   /**
-    * Returns seconds since cache statistics reset
-    * If statistics haven't been reset, this will be the same as ElapsedTime
-    *
-    * @return the number of seconds since the cache statistics were last reset
-    */
-   long getTimeSinceReset();
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -4,6 +4,8 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.Modification;
 import org.jboss.cache.NodeSPI;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.VisitableCommand;
 import org.jboss.cache.commands.WriteCommand;
@@ -46,7 +48,7 @@
  * @author Bela Ban
  * @version $Id$
  */
-public class CacheStoreInterceptor extends SkipCheckChainedInterceptor implements CacheStoreInterceptorMBean
+public class CacheStoreInterceptor extends SkipCheckChainedInterceptor
 {
    private CacheLoaderConfig loaderConfig = null;
    private TransactionManager txMgr = null;
@@ -56,6 +58,7 @@
    private CacheLoader loader;
    private CacheLoaderManager loaderManager;
    private boolean optimistic;
+   private boolean statsEnabled;
 
    public CacheStoreInterceptor()
    {
@@ -78,6 +81,7 @@
       // this should only happen after the CacheLoaderManager has started, since the CacheLoaderManager only creates the CacheLoader instance in it's @Start method.
       loader = loaderManager.getCacheLoader();
       optimistic = configuration.getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
+      this.setStatisticsEnabled(configuration.getExposeManagementStatistics());
    }
 
    /**
@@ -317,25 +321,6 @@
       }
    }
 
-   public long getCacheLoaderStores()
-   {
-      return cacheStores;
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      cacheStores = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("CacheLoaderStores", cacheStores);
-      return retval;
-   }
-
    private void prepareCacheLoader(GlobalTransaction gtx, TransactionContext transactionContext, boolean onePhase) throws Throwable
    {
       if (transactionContext == null)
@@ -372,9 +357,13 @@
 
    public static class StoreModificationsBuilder extends AbstractVisitor
    {
+
       boolean generateStatistics;
+
       int putCount;
+
       Set<Fqn> affectedFqns = new HashSet<Fqn>();
+
       List<Modification> modifications = new ArrayList<Modification>();
 
       public StoreModificationsBuilder(boolean generateStatistics)
@@ -435,5 +424,39 @@
          modifications.add(mod);
          return null;
       }
+
    }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      cacheStores = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = new HashMap<String, Object>();
+      retval.put("CacheLoaderStores", cacheStores);
+      return retval;
+   }
+
+   @ManagedAttribute
+   public boolean getStatisticsEnabled()
+   {
+      return statsEnabled;
+   }
+
+   @ManagedAttribute
+   public void setStatisticsEnabled(boolean enabled)
+   {
+      this.statsEnabled = enabled;
+   }
+
+   @ManagedAttribute(description = "number of cache loader stores")
+   public long getCacheLoaderStores()
+   {
+      return cacheStores;
+   }
+
 }

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing cache loader statistics
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface CacheStoreInterceptorMBean extends InterceptorMBean
-{
-   /**
-    * Returns the number of cache loader stores
-    * 
-    * @return the number of cache loader stores
-    */
-   long getCacheLoaderStores();
-
-}

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,63 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-import java.util.Map;
-
-/**
- * Interface containing common cache management operations
- *
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface InterceptorMBean
-{
-   /**
-    * Returns whether an interceptor's statistics are
-    * being captured.
-    *
-    * @return true if statistics are captured
-    */
-   boolean getStatisticsEnabled();
-
-   /**
-    * Enables an interceptor's cache statistics
-    * If true, the interceptor will capture statistics
-    * and make them available through the mbean.
-    *
-    * @param enabled true if statistics should be captured
-    */
-   void setStatisticsEnabled(boolean enabled);
-
-   /**
-    * Returns a map of the cache interceptor's statistics
-    * Map is keyed on statistic names (which are Strings) and values are Objects.
-    *
-    * @return a map containing statistics
-    */
-   Map<String, Object> dumpStatistics();
-
-   /**
-    * Resets an interceptor's cache statistics
-    */
-   void resetStatistics();
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -7,6 +7,8 @@
 package org.jboss.cache.interceptors;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.CommandsFactory;
 import org.jboss.cache.commands.VisitableCommand;
@@ -60,12 +62,13 @@
  *
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  */
-public class InvalidationInterceptor extends BaseRpcInterceptor implements InvalidationInterceptorMBean
+public class InvalidationInterceptor extends BaseRpcInterceptor 
 {
    private long invalidations = 0;
    protected Map<GlobalTransaction, List<WriteCommand>> txMods;
    protected boolean optimistic;
    private CommandsFactory commandsFactory;
+   private boolean statsEnabled;
 
    @Inject
    public void injectDependencies(CommandsFactory commandsFactory)
@@ -78,6 +81,7 @@
    {
       optimistic = configuration.getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
       if (optimistic) txMods = new ConcurrentHashMap<GlobalTransaction, List<WriteCommand>>();
+      this.setStatisticsEnabled(configuration.getExposeManagementStatistics());
    }
 
    @Override
@@ -350,25 +354,6 @@
    }
 
 
-   public long getInvalidations()
-   {
-      return invalidations;
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      invalidations = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("Invalidations", invalidations);
-      return retval;
-   }
-
    protected void invalidateAcrossCluster(Fqn fqn, TransactionWorkspace workspace, boolean synchronous, InvocationContext ctx) throws Throwable
    {
       if (!isLocalModeForced(ctx))
@@ -410,4 +395,36 @@
       OptimisticTransactionContext entry = (OptimisticTransactionContext) ctx.getTransactionContext();
       return entry.getTransactionWorkSpace();
    }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      invalidations = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = new HashMap<String, Object>();
+      retval.put("Invalidations", invalidations);
+      return retval;
+   }
+
+   @ManagedAttribute
+   public boolean getStatisticsEnabled()
+   {
+      return this.statsEnabled;
+   }
+
+   @ManagedAttribute
+   public void setStatisticsEnabled(boolean enabled)
+   {
+      this.statsEnabled = enabled;
+   }
+
+   @ManagedAttribute (description = "number of invalidations")
+   public long getInvalidations()
+   {
+      return invalidations;
+   }
 }

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing invalidation statistics
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface InvalidationInterceptorMBean extends InterceptorMBean
-{
-   /**
-    * Returns the number of cache invalidations
-    * 
-    * @return the number of invalidations
-    */
-   long getInvalidations();
-
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -33,7 +33,7 @@
  *
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  */
-public class InvocationContextInterceptor extends BaseTransactionalContextInterceptor implements InvocationContextInterceptorMBean
+public class InvocationContextInterceptor extends BaseTransactionalContextInterceptor
 {
    private RPCManager rpcManager;
 

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InvocationContextInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,10 +0,0 @@
-package org.jboss.cache.interceptors;
-
-/**
- * MBean to the {@link InvocationContextInterceptor}
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
- */
-public interface InvocationContextInterceptorMBean extends InterceptorMBean
-{
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyActivationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyActivationInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyActivationInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -3,6 +3,7 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.Modification;
 import org.jboss.cache.NodeSPI;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
@@ -42,7 +43,7 @@
  * @deprecated will be removed along with optimistic and pessimistic locking.
  */
 @Deprecated
-public class LegacyActivationInterceptor extends LegacyCacheLoaderInterceptor implements ActivationInterceptorMBean
+public class LegacyActivationInterceptor extends LegacyCacheLoaderInterceptor 
 {
 
    protected TransactionManager txMgr = null;
@@ -270,25 +271,6 @@
       return activations;
    }
 
-   @Override
-   public void resetStatistics()
-   {
-      super.resetStatistics();
-      activations = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = super.dumpStatistics();
-      if (retval == null)
-      {
-         retval = new HashMap<String, Object>();
-      }
-      retval.put("Activations", activations);
-      return retval;
-   }
-
    private void prepareCacheLoader(InvocationContext ctx) throws Throwable
    {
       GlobalTransaction gtx = ctx.getGlobalTransaction();
@@ -310,6 +292,7 @@
    {
 
       private List<Modification> cacheLoaderModifications = new ArrayList<Modification>();
+
       private int txActs = 0;
 
       @Override
@@ -389,5 +372,25 @@
       {
          return txActs;
       }
+
    }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      super.resetStatistics();
+      activations = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = super.dumpStatistics();
+      if (retval == null)
+      {
+         retval = new HashMap<String, Object>();
+      }
+      retval.put("Activations", activations);
+      return retval;
+   }
 }
\ No newline at end of file

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -5,26 +5,18 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.commands.WriteCommand;
-import org.jboss.cache.commands.read.GetChildrenNamesCommand;
-import org.jboss.cache.commands.read.GetDataMapCommand;
-import org.jboss.cache.commands.read.GetKeyValueCommand;
-import org.jboss.cache.commands.read.GetKeysCommand;
-import org.jboss.cache.commands.read.GetNodeCommand;
+import org.jboss.cache.commands.read.*;
 import org.jboss.cache.commands.tx.RollbackCommand;
-import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.MoveCommand;
-import org.jboss.cache.commands.write.PutDataMapCommand;
-import org.jboss.cache.commands.write.PutForExternalReadCommand;
-import org.jboss.cache.commands.write.PutKeyValueCommand;
-import org.jboss.cache.commands.write.RemoveKeyCommand;
-import org.jboss.cache.commands.write.RemoveNodeCommand;
+import org.jboss.cache.commands.write.*;
 import org.jboss.cache.config.Configuration;
 import static org.jboss.cache.config.Configuration.CacheMode;
 import org.jboss.cache.config.Configuration.NodeLockingScheme;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.interceptors.base.JmxStatsCommandInterceptor;
 import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
 import org.jboss.cache.loader.CacheLoader;
 import org.jboss.cache.loader.CacheLoaderManager;
 import org.jboss.cache.lock.LockManager;
@@ -34,12 +26,7 @@
 import org.jboss.cache.transaction.TransactionContext;
 import org.jboss.cache.transaction.TransactionTable;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 /**
  * Loads nodes that don't exist at the time of the call into memory from the CacheLoader
@@ -49,7 +36,7 @@
  * @deprecated will be removed along with optimistic and pessimistic locking.
  */
 @Deprecated
-public class LegacyCacheLoaderInterceptor extends CommandInterceptor implements CacheLoaderInterceptorMBean
+public class LegacyCacheLoaderInterceptor extends JmxStatsCommandInterceptor
 {
    private long cacheLoads = 0;
    private long cacheMisses = 0;
@@ -430,32 +417,6 @@
       return false;
    }
 
-   public long getCacheLoaderLoads()
-   {
-      return cacheLoads;
-   }
-
-   public long getCacheLoaderMisses()
-   {
-      return cacheMisses;
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      cacheLoads = 0;
-      cacheMisses = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("CacheLoaderLoads", cacheLoads);
-      retval.put("CacheLoaderMisses", cacheMisses);
-      return retval;
-   }
-
    protected void lock(Fqn fqn, LockType lockType, boolean recursive, InvocationContext ctx) throws Throwable
    {
       if (configuration.getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC) return;
@@ -582,4 +543,32 @@
       return nodeData;
    }
 
+   @ManagedAttribute(description = "number of cache loader node loads")
+   public long getCacheLoaderLoads()
+   {
+      return cacheLoads;
+   }
+
+   @ManagedAttribute(description = "number of cache loader node misses")
+   public long getCacheLoaderMisses()
+   {
+      return cacheMisses;
+   }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      cacheLoads = 0;
+      cacheMisses = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = new HashMap<String, Object>();
+      retval.put("CacheLoaderLoads", cacheLoads);
+      retval.put("CacheLoaderMisses", cacheMisses);
+      return retval;
+   }
+
 }
\ No newline at end of file

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -4,8 +4,11 @@
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.commands.write.EvictCommand;
 import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.interceptors.base.JmxStatsCommandInterceptor;
 import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
 import org.jboss.cache.loader.CacheLoader;
 import org.jboss.cache.loader.CacheLoaderManager;
 import org.jboss.cache.notifications.Notifier;
@@ -22,7 +25,7 @@
  * @author <a href="mailto:{hmesha at novell.com}">{Hany Mesha}</a>
  * @version $Id$
  */
-public class PassivationInterceptor extends CommandInterceptor implements PassivationInterceptorMBean
+public class PassivationInterceptor extends JmxStatsCommandInterceptor
 {
 
    private final AtomicLong passivations = new AtomicLong(0);
@@ -80,25 +83,6 @@
       }
    }
 
-   public long getPassivations()
-   {
-      return passivations.get();
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      passivations.set(0);
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("Passivations", passivations.get());
-      return retval;
-   }
-
    /**
     * Returns attributes for a node.
     */
@@ -122,9 +106,31 @@
 
    private static class NodeNotLoadedException extends Exception
    {
+
       /**
        * The serialVersionUID
        */
       private static final long serialVersionUID = -4078972305344328905L;
+
    }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      passivations.set(0);
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = new HashMap<String, Object>();
+      retval.put("Passivations", passivations.get());
+      return retval;
+   }
+
+   @ManagedAttribute (description = "number of cache node passivations")
+   public long getPassivations()
+   {
+      return passivations.get();
+   }
 }

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PassivationInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing passivation statistics
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface PassivationInterceptorMBean extends InterceptorMBean
-{
-   /**
-    * Returns the number of cache node passivations
-    * 
-    * @return the number of cache node passivations
-    */
-   long getPassivations();
-
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -9,6 +9,9 @@
 import org.jboss.cache.CacheException;
 import org.jboss.cache.RPCManager;
 import org.jboss.cache.ReplicationException;
+import org.jboss.cache.jmx.annotations.MBean;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.CommandsFactory;
 import org.jboss.cache.commands.ReplicableCommand;
@@ -58,7 +61,7 @@
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  * @author <a href="mailto:stevew at jofti.com">Steve Woodcock (stevew at jofti.com)</a>
  */
-public class TxInterceptor extends BaseTransactionalContextInterceptor implements TxInterceptorMBean
+public class TxInterceptor extends BaseTransactionalContextInterceptor
 {
    protected CommandsFactory commandsFactory;
    protected RPCManager rpcManager;
@@ -77,6 +80,7 @@
    private long rollbacks = 0;
    protected boolean optimistic = false;
    private LockManager lockManager;
+   private boolean statsEnabled;
 
    @Inject
    public void intialize(RPCManager rpcManager, ContextFactory contextFactory,
@@ -90,6 +94,7 @@
       this.invocationContextContainer = icc;
       this.componentRegistry = componentRegistry;
       this.lockManager = lockManager;
+      setStatisticsEnabled(configuration.getExposeManagementStatistics());
    }
 
    @Override
@@ -270,39 +275,6 @@
    // JMX statistics
    // ------------------------------------------------------------------------
 
-   public long getPrepares()
-   {
-      return prepares;
-   }
-
-   public long getCommits()
-   {
-      return commits;
-   }
-
-   public long getRollbacks()
-   {
-      return rollbacks;
-   }
-
-   @Override
-   public void resetStatistics()
-   {
-      prepares = 0;
-      commits = 0;
-      rollbacks = 0;
-   }
-
-   @Override
-   public Map<String, Object> dumpStatistics()
-   {
-      Map<String, Object> retval = new HashMap<String, Object>(3);
-      retval.put("Prepares", prepares);
-      retval.put("Commits", commits);
-      retval.put("Rollbacks", rollbacks);
-      return retval;
-   }
-
    // --------------------------------------------------------------
 
    /**
@@ -1131,4 +1103,52 @@
          return "TxInterceptor.LocalSynchronizationHandler(gtx=" + gtx + ", tx=" + getTxAsString() + ")";
       }
    }
+
+   @ManagedOperation
+   public void resetStatistics()
+   {
+      prepares = 0;
+      commits = 0;
+      rollbacks = 0;
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics()
+   {
+      Map<String, Object> retval = new HashMap<String, Object>(3);
+      retval.put("Prepares", prepares);
+      retval.put("Commits", commits);
+      retval.put("Rollbacks", rollbacks);
+      return retval;
+   }
+
+   @ManagedAttribute
+   public boolean getStatisticsEnabled()
+   {
+      return this.statsEnabled;
+   }
+
+   @ManagedAttribute
+   public void setStatisticsEnabled(boolean enabled)
+   {
+      this.statsEnabled = enabled;
+   }
+
+   @ManagedAttribute (description = "number of transaction prepares")
+   public long getPrepares()
+   {
+      return prepares;
+   }
+
+   @ManagedAttribute (description = "number of transaction commits")
+   public long getCommits()
+   {
+      return commits;
+   }
+
+   @ManagedAttribute (description = "number of transaction rollbacks")
+   public long getRollbacks()
+   {
+      return rollbacks;
+   }
 }
\ No newline at end of file

Deleted: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptorMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptorMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptorMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -1,52 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.cache.interceptors;
-
-/**
- * Interface capturing transaction statistics
- * @author Jerry Gauthier
- * @version $Id$
- */
-public interface TxInterceptorMBean extends InterceptorMBean
-{
-   /**
-    * Returns the number of transaction prepares
-    * 
-    * @return the number of prepares
-    */
-   long getPrepares();
-   
-   /**
-    * Returns the number of transaction commits
-    * 
-    * @return the number of commits
-    */
-   long getCommits();
-   
-   /**
-    * Returns the number of transaction rollbacks
-    * 
-    * @return the number of rollbacks
-    */
-   long getRollbacks();
-
-}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/base/CommandInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/base/CommandInterceptor.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/base/CommandInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -6,13 +6,8 @@
 import org.jboss.cache.commands.VisitableCommand;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.interceptors.InterceptorMBean;
 import org.jboss.cache.invocation.InvocationContext;
 
-import java.util.Collections;
-import java.util.Map;
-
 /**
  * This is the base class for all interceptors to extend, and implements the {@link org.jboss.cache.commands.Visitor} interface
  * allowing it to intercept invocations on {@link org.jboss.cache.commands.VisitableCommand}s.
@@ -36,9 +31,9 @@
  * @see org.jboss.cache.interceptors.InterceptorChain
  * @since 2.2
  */
-public class CommandInterceptor extends AbstractVisitor implements InterceptorMBean
+public class CommandInterceptor extends AbstractVisitor
 {
-   private boolean statsEnabled = false;
+   
 
    private CommandInterceptor next;
 
@@ -59,47 +54,7 @@
       this.configuration = configuration;
    }
 
-   @Start
-   private void checkStatisticsUsed()
-   {
-      setStatisticsEnabled(configuration.getExposeManagementStatistics());
-   }
-
    /**
-    * @return true if gathering statistics for JMX is enabled on this interceptor.
-    */
-   public boolean getStatisticsEnabled()
-   {
-      return statsEnabled;
-   }
-
-   /**
-    * @param enabled whether gathering statistics for JMX are enabled.
-    */
-   public void setStatisticsEnabled(boolean enabled)
-   {
-      statsEnabled = enabled;
-   }
-
-   /**
-    * Returns a map of statistics.  This is a default implementation which returns an empty map and should be overridden
-    * if it is to be meaningful.
-    *
-    * @return an empty map
-    */
-   public Map<String, Object> dumpStatistics()
-   {
-      return Collections.emptyMap();
-   }
-
-   /**
-    * Resets statistics gathered.  Is a no-op, and should be overridden if it is to be meaningful.
-    */
-   public void resetStatistics()
-   {
-   }
-
-   /**
     * Retrieves the next interceptor in the chain.
     *
     * @return the next interceptor in the chain.

Copied: core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatisticsInterceptor.java (from rev 6532, core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorMBean.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatisticsInterceptor.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatisticsInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.cache.interceptors.base;
+
+import java.util.Map;
+
+/**
+ * Interface containing common cache management operations
+ *
+ * @author Jerry Gauthier
+ * @version $Id$
+ */
+public interface JmxStatisticsInterceptor
+{
+   /**
+    * Returns whether an interceptor's statistics are
+    * being captured.
+    *
+    * @return true if statistics are captured
+    */
+   boolean getStatisticsEnabled();
+
+   /**
+    * Enables an interceptor's cache statistics
+    * If true, the interceptor will capture statistics
+    * and make them available through the mbean.
+    *
+    * @param enabled true if statistics should be captured
+    */
+   void setStatisticsEnabled(boolean enabled);
+
+   /**
+    * Returns a map of the cache interceptor's statistics
+    * Map is keyed on statistic names (which are Strings) and values are Objects.
+    *
+    * @return a map containing statistics
+    */
+   Map<String, Object> dumpStatistics();
+
+   /**
+    * Resets an interceptor's cache statistics
+    */
+   void resetStatistics();
+}


Property changes on: core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatisticsInterceptor.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Added: core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatsCommandInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatsCommandInterceptor.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/base/JmxStatsCommandInterceptor.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.cache.interceptors.base;
+
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.interceptors.base.JmxStatisticsInterceptor;
+import org.jboss.cache.factories.annotations.Start;
+
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * Base class for all the interceptors exposing management statistics.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 3.0
+ */
+public class JmxStatsCommandInterceptor extends CommandInterceptor implements JmxStatisticsInterceptor
+{
+   private boolean statsEnabled = false;
+
+   @Start
+   public void checkStatisticsUsed()
+   {
+      setStatisticsEnabled(configuration.getExposeManagementStatistics());
+   }
+
+   /**
+    * Returns whether an interceptor's statistics are
+    * being captured.
+    *
+    * @return true if statistics are captured
+    */
+   @ManagedAttribute
+   public boolean getStatisticsEnabled()
+   {
+      return statsEnabled;
+   }
+
+   /**
+    * @param enabled whether gathering statistics for JMX are enabled.
+    */
+   @ManagedAttribute
+   public void setStatisticsEnabled(boolean enabled)
+   {
+      statsEnabled = enabled;
+   }
+
+   /**
+    * Returns a map of statistics.  This is a default implementation which returns an empty map and should be overridden
+    * if it is to be meaningful.
+    *
+    * @return an empty map
+    */
+   public Map<String, Object> dumpStatistics()
+   {
+      return Collections.emptyMap();
+   }
+
+   /**
+    * Resets statistics gathered.  Is a no-op, and should be overridden if it is to be meaningful.
+    */
+   public void resetStatistics()
+   {
+   }
+
+
+}

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -38,6 +38,7 @@
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.NonVolatile;
 import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.factories.ComponentRegistry;
 import org.jboss.cache.interceptors.base.CommandInterceptor;
 import org.jboss.cache.loader.CacheLoaderManager;
 import org.jboss.cache.marshall.Marshaller;
@@ -619,6 +620,11 @@
       return (Set) getChildrenNames(Fqn.fromString(fqn));
    }
 
+   public ComponentRegistry getComponentRegistry()
+   {
+      return componentRegistry;
+   }
+
    public DataContainer getDataContainer()
    {
       return dataContainer;

Modified: core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapper.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -24,6 +24,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.*;
+import org.jboss.cache.factories.ComponentRegistry;
 import org.jboss.cache.config.*;
 import org.jboss.cache.config.parsing.JGroupsStackParser;
 import org.jboss.cache.config.parsing.element.BuddyElementParser;
@@ -40,6 +41,7 @@
 import javax.management.*;
 import javax.transaction.TransactionManager;
 import java.util.List;
+import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -59,10 +61,10 @@
 
    private MBeanServer server;
    private String cacheObjectName;
-   private boolean interceptorsRegistered;
+   private boolean jmxResourceRegistered;
    private CacheSPI<K, V> cache;
    private Configuration config;
-   private boolean registerInterceptors = true;
+   private boolean registerJmxResource = true;
    private final AtomicInteger listenerCount = new AtomicInteger(0);
    private final AtomicLong sequence = new AtomicLong(0);
    private final CacheNotificationListener cacheNotificationListener;
@@ -83,6 +85,7 @@
    private LoadersElementParser loadersElementParser = new LoadersElementParser();
    private EvictionElementParser evictionElementParser = new EvictionElementParser();
    private JGroupsStackParser stackParser = new JGroupsStackParser();
+   private List<ResourceDMBean> resourceDMBeans = new ArrayList<ResourceDMBean>();
 
    // ----------------------------------------------------------- Constructors
 
@@ -198,14 +201,14 @@
       return cache == null ? "Cache is null" : formatHtml(CachePrinter.printCacheLockingInfo(cache));
    }
 
-   public boolean getRegisterInterceptors()
+   public boolean getRegisterJmxResource()
    {
-      return registerInterceptors;
+      return registerJmxResource;
    }
 
-   public void setRegisterInterceptors(boolean register)
+   public void setRegisterJmxResource(boolean register)
    {
-      this.registerInterceptors = register;
+      this.registerJmxResource = register;
    }
 
    // ----------------------------------------------------  LegacyConfiguration
@@ -607,7 +610,7 @@
 
          cache.start();
 
-         registerInterceptors();
+         registerJmxResources();
 
          cacheStatus = CacheStatus.STARTED;
          sendStateChangeNotification(startingState, getState(), getClass().getSimpleName() + " started", null);
@@ -640,8 +643,8 @@
          if (cache.getCacheStatus() == CacheStatus.DESTROYED)
          {
             // Cache was already destroyed externally; 
-            // so get rid of the interceptor mbeans
-            unregisterInterceptors();
+            // so get rid of the jmx resources
+            unregisterJmxResources();
          }
 
          cacheStatus = CacheStatus.STOPPED;
@@ -682,9 +685,9 @@
       {
          cacheStatus = CacheStatus.DESTROYING;
 
-         // The cache is destroyed, so we shouldn't leave the interceptors
+         // The cache is destroyed, so we shouldn't leave the ResourcesDMBean
          // in JMX, even if we didn't register them in create
-         unregisterInterceptors();
+         unregisterJmxResources();
 
          if (cache != null)
             cache.destroy();
@@ -725,12 +728,11 @@
       if (notificationServiceName == null)
          notificationServiceName = result.getCanonicalName();
       cacheNotificationListener.setServiceName(notificationServiceName);
-
       return result;
    }
 
    /**
-    * Registers the cache's interceptors, if {@link #getRegisterInterceptors()}
+    * Registers the cache's MBean resources, if {@link #getRegisterJmxResource()}
     * is <code>true</code>.
     */
    public void postRegister(Boolean registrationDone)
@@ -738,16 +740,15 @@
       if (Boolean.TRUE.equals(registrationDone))
       {
          log.debug("Registered in JMX under " + cacheObjectName);
-
          if (cache != null && CacheStatus.STARTED.equals(cache.getCacheStatus()))
          {
             try
             {
-               registerInterceptors();
+               registerJmxResources();
             }
             catch (Exception e)
             {
-               log.error("Caught exception registering cache interceptors with JMX", e);
+               log.error("Caught exception registering cache ResourcesDMBean with JMX", e);
             }
          }
 
@@ -763,12 +764,12 @@
    }
 
    /**
-    * Unregisters the interceptors, if {@link #getRegisterInterceptors()} is
+    * Unregisters the ResourcesDMBean, if {@link #getRegisterJmxResource()} is
     * <code>true</code>.
     */
    public void postDeregister()
    {
-      unregisterInterceptors();
+      unregisterJmxResources();
 
       server = null;
       registered = false;
@@ -810,6 +811,10 @@
             cache.addCacheListener(cacheNotificationListener);
          }
       }
+      if (config != null)
+      {
+         this.registerJmxResource = config.getExposeManagementStatistics();
+      }
    }
 
    public String getCacheObjectName()
@@ -933,38 +938,56 @@
       }
    }
 
-   protected boolean registerInterceptors() throws CacheException
+   protected boolean registerJmxResources() throws CacheException
    {
-      if (registerInterceptors && !interceptorsRegistered && server != null)
+      if (registerJmxResource && !jmxResourceRegistered && server != null)
       {
-         log.debug("Registering interceptors");
+         log.debug("Registering jmx resources");
          List<CommandInterceptor> interc = cache.getInterceptorChain();
          if (interc != null && interc.size() > 0)
          {
             try
             {
-               JmxUtil.registerInterceptors(server, interc, cacheObjectName);
-               interceptorsRegistered = true;
+               for (ComponentRegistry.Component component : cache.getComponentRegistry().getRegiteredComponents())
+               {
+                  ResourceDMBean resourceDMBean = new ResourceDMBean(component.getInstance());
+                  if (resourceDMBean.isManagedResource())
+                  {
+                     resourceDMBeans.add(resourceDMBean);
+                  }
+               }               
+               for (ResourceDMBean resource: resourceDMBeans)
+               {
+                  String resourceName = resource.getObject().getClass().getSimpleName();
+                  ObjectName objectName = new ObjectName(cacheObjectName + JmxUtil.JMX_RESOURCE_KEY + resourceName);
+                  if (!server.isRegistered(objectName)) server.registerMBean(resource, objectName);
+               }
+               jmxResourceRegistered = true;
                return true;
             }
             catch (JMException e)
             {
-               throw new CacheException("Failed to register interceptors", e);
+               throw new CacheException("Failed to register jmx resources", e);
             }
          }
       }
       return false;
    }
 
-   protected void unregisterInterceptors()
+   protected void unregisterJmxResources()
    {
-      if (registerInterceptors && interceptorsRegistered && server != null)
+      if (registerJmxResource && jmxResourceRegistered && server != null)
       {
          try
          {
             log.debug("Unregistering interceptors");
-            JmxUtil.unregisterInterceptors(server, cache.getInterceptorChain(), getCacheObjectName());
-            interceptorsRegistered = false;
+            for (ResourceDMBean resource : resourceDMBeans)
+            {
+               String resourceName = resource.getObject().getClass().getSimpleName();
+               ObjectName objectName = new ObjectName(cacheObjectName + JmxUtil.JMX_RESOURCE_KEY + resourceName);
+               if (server.isRegistered(objectName)) server.unregisterMBean(objectName);
+            }
+            jmxResourceRegistered = false;
          }
          catch (Exception e)
          {

Modified: core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapperMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapperMBean.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/CacheJmxWrapperMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -164,7 +164,7 @@
     * <p/>
     * Default is <code>true</code>.
     */
-   boolean getRegisterInterceptors();
+   boolean getRegisterJmxResource();
 
    /**
     * Sets whether this object should register the cache's interceptors
@@ -172,5 +172,5 @@
     * <p/>
     * Default is <code>true</code>.
     */
-   void setRegisterInterceptors(boolean register);
+   void setRegisterJmxResource(boolean register);
 }

Modified: core/trunk/src/main/java/org/jboss/cache/jmx/JmxUtil.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/JmxUtil.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/JmxUtil.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -23,6 +23,7 @@
 
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.interceptors.base.JmxStatisticsInterceptor;
 
 import javax.management.JMException;
 import javax.management.MBeanServer;
@@ -49,7 +50,7 @@
    public static final String CACHE_TYPE_KEY = "cacheType";
    public static final String PLAIN_CACHE_TYPE = "Cache";
    public static final String MBEAN_CLASS_SUFFIX = "MBean";
-   public static final String INTERCEPTOR_KEY = ",cache-interceptor=";
+   public static final String JMX_RESOURCE_KEY = ",jmx-resource=";
 
    public static void registerCacheMBean(MBeanServer server, CacheJmxWrapperMBean cache, String cacheObjectName)
          throws JMException
@@ -61,58 +62,6 @@
       }
    }
 
-   /*
-    * Register the associated mbeans for cache interceptors
-    *
-    * @param server the mbean server with which the mbeans should be registered
-    * @param cache the cache having the set of interceptors to be registered
-    * @param registerCache whether the cache itself should be registered
-    */
-   public static void registerInterceptors(MBeanServer server, List<CommandInterceptor> interceptors, String cacheObjectName)
-         throws JMException
-   {
-      if (server == null || interceptors == null || cacheObjectName == null)
-      {
-         return;
-      }
-
-      for (CommandInterceptor interceptor : interceptors)
-      {
-         if (!interceptor.getStatisticsEnabled())
-            continue;
-
-         boolean mbeanExists = true;
-         try
-         {
-            // the mbean for interceptor AbcInterceptor will be named AbcInterceptorMBean
-            Class.forName(interceptor.getClass().getName() + MBEAN_CLASS_SUFFIX);
-         }
-         catch (Throwable e)
-         {
-            // if the class can't be instantiated, no mbean is available
-            mbeanExists = false;
-         }
-
-         // for JDK 1.4, must parse name and remove package prefix
-         // for JDK 1.5, can use getSimpleName() to establish class name without package prefix
-         String className = interceptor.getClass().getName();
-         String serviceName = cacheObjectName + INTERCEPTOR_KEY + className.substring(className.lastIndexOf('.') + 1);
-
-         ObjectName objName = new ObjectName(serviceName);
-         if (!server.isRegistered(objName))
-         {
-            if (mbeanExists)
-            // register associated interceptor mbean
-            {
-               server.registerMBean(interceptor, objName);
-            }
-            //else
-            // register dummy interceptor mbean
-            // server.registerMBean(new BaseInterceptor(), objName);
-         }
-      }
-   }
-
    public static String getDefaultCacheObjectName(org.jboss.cache.Cache cache)
    {
       // get the cache's registration name
@@ -131,7 +80,6 @@
       {
          tmpName = PREFIX + config.getClusterName();
       }
-
       return tmpName;
    }
 
@@ -145,34 +93,4 @@
    {
       server.unregisterMBean(new ObjectName(cacheObjectName));
    }
-
-   /*
-   * Unregister the associated mbeans for cache interceptors
-   *
-   * @param server the mbean server for which the mbeans should be unregistered
-   * @param cache the cache having the set of interceptors to be unregistered
-   * @param unregisterCache whether the cache itself should be unregistered
-   */
-   public static void unregisterInterceptors(MBeanServer server, List<CommandInterceptor> interceptors, String cacheObjectName)
-         throws Exception
-   {
-      if (server == null || interceptors == null || cacheObjectName == null)
-      {
-         return;
-      }
-
-      for (CommandInterceptor interceptor : interceptors)
-      {
-         // for JDK 1.4, must parse name and remove package prefix
-         // for JDK 1.5, can use getSimpleName() to establish class name without package prefix
-         String className = interceptor.getClass().getName();
-         String serviceName = cacheObjectName + INTERCEPTOR_KEY + className.substring(className.lastIndexOf('.') + 1);
-
-         ObjectName objName = new ObjectName(serviceName);
-         if (server.isRegistered(objName))
-         {
-            server.unregisterMBean(objName);
-         }
-      }
-   }
 }

Added: core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/ResourceDMBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,734 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.cache.jmx;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.jmx.annotations.MBean;
+import org.jboss.cache.jmx.annotations.ManagedAttribute;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
+
+import javax.management.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * This class was entirely copied from jgroups (same name there).
+ * Couldn't simply reuse it because jgroups does not ship with MBean, ManagedAttribute and ManagedOperation.
+ * Once jgroups will ship these classes, the code can be dinalmically reused from there.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 3.0
+ */
+public class ResourceDMBean implements DynamicMBean
+{
+   private static final Class<?>[] primitives = {int.class,
+         byte.class,
+         short.class,
+         long.class,
+         float.class,
+         double.class,
+         boolean.class,
+         char.class};
+
+   private static final String MBEAN_DESCRITION = "Dynamic MBean Description";
+
+   private final Log log = LogFactory.getLog(ResourceDMBean.class);
+   private final Object obj;
+   private String description = "";
+
+   private final MBeanAttributeInfo[] attrInfo;
+   private final MBeanOperationInfo[] opInfo;
+
+   private final HashMap<String, AttributeEntry> atts = new HashMap<String, AttributeEntry>();
+   private final List<MBeanOperationInfo> ops = new ArrayList<MBeanOperationInfo>();
+
+   public ResourceDMBean(Object instance)
+   {
+
+      if (instance == null)
+         throw new NullPointerException("Cannot make an MBean wrapper for null instance");
+
+      this.obj = instance;
+      findDescription();
+      findFields();
+      findMethods();
+
+      attrInfo = new MBeanAttributeInfo[atts.size()];
+      int i = 0;
+      log.info("Processing class " + instance.getClass());
+      log.info("Attributes are:");
+      MBeanAttributeInfo info = null;
+      for (AttributeEntry entry : atts.values())
+      {
+         info = entry.getInfo();
+         attrInfo[i++] = info;
+         log.info("Attribute " + info.getName()
+               + "[r="
+               + info.isReadable()
+               + ",w="
+               + info.isWritable()
+               + ",is="
+               + info.isIs()
+               + ",type="
+               + info.getType()
+               + "]");
+      }
+
+      opInfo = new MBeanOperationInfo[ops.size()];
+      ops.toArray(opInfo);
+
+      if (ops.size() > 0)
+         log.info("Operations are:");
+      for (MBeanOperationInfo op : opInfo)
+      {
+         log.info("Operation " + op.getReturnType() + " " + op.getName());
+      }
+
+   }
+
+   Object getObject()
+   {
+      return obj;
+   }
+
+   private void findDescription()
+   {
+      MBean mbean = getObject().getClass().getAnnotation(MBean.class);
+      if (mbean != null && mbean.description() != null && mbean.description().trim().length() > 0)
+      {
+         description = mbean.description();
+         if (log.isDebugEnabled())
+         {
+            log.debug("@MBean description set - " + mbean.description());
+         }
+         MBeanAttributeInfo info = new MBeanAttributeInfo(MBEAN_DESCRITION,
+               "java.lang.String",
+               "@MBean description",
+               true,
+               false,
+               false);
+         try
+         {
+            atts.put(MBEAN_DESCRITION,
+                  new FieldAttributeEntry(info, getClass().getDeclaredField("description")));
+         }
+         catch (NoSuchFieldException e)
+         {
+            //this should not happen unless somebody removes description field
+            log.warn("Could not reflect field description of this class. Was it removed?");
+         }
+      }
+   }
+
+   public synchronized MBeanInfo getMBeanInfo()
+   {
+
+      return new MBeanInfo(getObject().getClass().getCanonicalName(),
+            description,
+            attrInfo,
+            null,
+            opInfo,
+            null);
+   }
+
+   public synchronized Object getAttribute(String name)
+   {
+      if (name == null || name.length() == 0)
+         throw new NullPointerException("Invalid attribute requested " + name);
+
+      if (log.isDebugEnabled())
+      {
+         log.debug("getAttribute called for " + name);
+      }
+      Attribute attr = getNamedAttribute(name);
+      if (log.isDebugEnabled())
+      {
+         log.debug("getAttribute value found " + attr.getValue());
+      }
+      return attr.getValue();
+   }
+
+   public synchronized void setAttribute(Attribute attribute)
+   {
+      if (attribute == null || attribute.getName() == null)
+         throw new NullPointerException("Invalid attribute requested " + attribute);
+
+      setNamedAttribute(attribute);
+   }
+
+   public synchronized AttributeList getAttributes(String[] names)
+   {
+      AttributeList al = new AttributeList();
+      for (String name : names)
+      {
+         Attribute attr = getNamedAttribute(name);
+         if (attr != null)
+         {
+            al.add(attr);
+         }
+         else
+         {
+            log.warn("Did not find attribute " + name);
+         }
+      }
+      return al;
+   }
+
+   public synchronized AttributeList setAttributes(AttributeList list)
+   {
+      AttributeList results = new AttributeList();
+      for (int i = 0; i < list.size(); i++)
+      {
+         Attribute attr = (Attribute) list.get(i);
+
+         if (log.isDebugEnabled())
+         {
+            log.debug("Attribute name " + attr.getName() + " new value is " + attr.getValue());
+         }
+
+         if (setNamedAttribute(attr))
+         {
+            results.add(attr);
+         }
+         else
+         {
+            if (log.isWarnEnabled())
+            {
+               log.debug("Failed to update attribute name " + attr.getName()
+                     + " with value "
+                     + attr.getValue());
+            }
+         }
+      }
+      return results;
+   }
+
+   public Object invoke(String name, Object[] args, String[] sig) throws MBeanException,
+         ReflectionException
+   {
+      try
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("Invoke method called on " + name);
+         }
+         Class<?>[] classes = new Class[sig.length];
+         for (int i = 0; i < classes.length; i++)
+         {
+            classes[i] = getClassForName(sig[i]);
+         }
+         Method method = getObject().getClass().getMethod(name, classes);
+         return method.invoke(getObject(), args);
+      }
+      catch (Exception e)
+      {
+         throw new MBeanException(e);
+      }
+   }
+
+   public static Class<?> getClassForName(String name) throws ClassNotFoundException
+   {
+      try
+      {
+         Class<?> c = Class.forName(name);
+         return c;
+      }
+      catch (ClassNotFoundException cnfe)
+      {
+         //Could be a primitive - let's check
+         for (int i = 0; i < primitives.length; i++)
+         {
+            if (name.equals(primitives[i].getName()))
+            {
+               return primitives[i];
+            }
+         }
+      }
+      throw new ClassNotFoundException("Class " + name + " cannot be found");
+   }
+
+   private void findMethods()
+   {
+      //find all methods but don't include methods from Object class
+      List<Method> methods = new ArrayList<Method>(Arrays.asList(getObject().getClass().getMethods()));
+      List<Method> objectMethods = new ArrayList<Method>(Arrays.asList(Object.class.getMethods()));
+      methods.removeAll(objectMethods);
+
+      for (Method method : methods)
+      {
+         //does method have @ManagedAttribute annotation?
+         ManagedAttribute attr = method.getAnnotation(ManagedAttribute.class);
+         if (attr != null)
+         {
+            String methodName = method.getName();
+            if (!methodName.startsWith("get") && !methodName.startsWith("set")
+                  && !methodName.startsWith("is"))
+            {
+               if (log.isWarnEnabled())
+                  log.warn("method name " + methodName
+                        + " doesn't start with \"get\", \"set\", or \"is\""
+                        + ", but is annotated with @ManagedAttribute: will be ignored");
+            }
+            else
+            {
+               MBeanAttributeInfo info = null;
+               //Is name field of @ManagedAttributed used?
+               String attributeName = attr.name().length() > 0 ? attr.name().trim() : null;
+               boolean writeAttribute = false;
+               if (isSetMethod(method))
+               { // setter
+                  attributeName = (attributeName == null) ? methodName.substring(3) : attributeName;
+                  info = new MBeanAttributeInfo(attributeName,
+                        method.getParameterTypes()[0].getCanonicalName(),
+                        attr.description(),
+                        true,
+                        true,
+                        false);
+                  writeAttribute = true;
+               }
+               else
+               { // getter
+                  if (method.getParameterTypes().length == 0 && method.getReturnType() != java.lang.Void.TYPE)
+                  {
+                     boolean hasSetter = atts.containsKey(attributeName);
+                     //we found is method
+                     if (methodName.startsWith("is"))
+                     {
+                        attributeName = (attributeName == null) ? methodName.substring(2) : attributeName;
+                        info = new MBeanAttributeInfo(attributeName,
+                              method.getReturnType().getCanonicalName(),
+                              attr.description(),
+                              true,
+                              hasSetter,
+                              true);
+                     }
+                     else
+                     {
+                        //this has to be get
+                        attributeName = (attributeName == null) ? methodName.substring(3) : attributeName;
+                        info = new MBeanAttributeInfo(attributeName,
+                              method.getReturnType().getCanonicalName(),
+                              attr.description(),
+                              true,
+                              hasSetter,
+                              false);
+                     }
+                  }
+                  else
+                  {
+                     if (log.isWarnEnabled())
+                     {
+                        log.warn("Method " + method.getName()
+                              + " must have a valid return type and zero parameters");
+                     }
+                     continue;
+                  }
+               }
+
+               if (log.isDebugEnabled())
+               {
+                  log.debug("@Attr found for method " + method.getName() + " and registered as " + attributeName);
+               }
+
+               AttributeEntry ae = atts.get(attributeName);
+               //is it a read method?
+               if (!writeAttribute)
+               {
+                  //we already have annotated field as read
+                  if (ae instanceof FieldAttributeEntry && ae.getInfo().isReadable())
+                  {
+                     log.warn("not adding annotated method " + method
+                           + " since we already have read attribute");
+                  }
+                  //we already have annotated set method
+                  else if (ae instanceof MethodAttributeEntry)
+                  {
+                     MethodAttributeEntry mae = (MethodAttributeEntry) ae;
+                     if (mae.hasSetMethod())
+                     {
+                        atts.put(attributeName,
+                              new MethodAttributeEntry(mae.getInfo(), mae.getSetMethod(), method));
+                     }
+                  } //we don't have such entry
+                  else
+                  {
+                     atts.put(attributeName, new MethodAttributeEntry(info, null, method));
+                  }
+               }//is it a set method?
+               else
+               {
+                  if (ae instanceof FieldAttributeEntry)
+                  {
+                     //we already have annotated field as write
+                     if (ae.getInfo().isWritable())
+                     {
+                        log.warn("Not adding annotated method " + methodName
+                              + " since we already have writable attribute");
+                     }
+                     else
+                     {
+                        //we already have annotated field as read
+                        //lets make the field writable
+                        Field f = ((FieldAttributeEntry) ae).getField();
+                        MBeanAttributeInfo i = new MBeanAttributeInfo(ae.getInfo().getName(),
+                              f.getType().getCanonicalName(),
+                              attr.description(),
+                              true,
+                              Modifier.isFinal(f.getModifiers()) ? false : true,
+                              false);
+                        atts.put(attributeName, new FieldAttributeEntry(i, f));
+                     }
+                  }
+                  //we already have annotated getOrIs method
+                  else if (ae instanceof MethodAttributeEntry)
+                  {
+                     MethodAttributeEntry mae = (MethodAttributeEntry) ae;
+                     if (mae.hasIsOrGetMethod())
+                     {
+                        atts.put(attributeName,
+                              new MethodAttributeEntry(info,
+                                    method,
+                                    mae.getIsOrGetMethod()));
+                     }
+                  } //we don't have such entry
+                  else
+                  {
+                     atts.put(attributeName, new MethodAttributeEntry(info, method, null));
+                  }
+               }
+            }
+         }
+         else if (method.isAnnotationPresent(ManagedOperation.class) || isMBeanAnnotationPresentWithExposeAll())
+         {
+            ManagedOperation op = method.getAnnotation(ManagedOperation.class);
+            String attName = method.getName();
+            if (isSetMethod(method) || isGetMethod(method))
+            {
+               attName = attName.substring(3);
+            }
+            else if (isIsMethod(method))
+            {
+               attName = attName.substring(2);
+            }
+            //expose unless we already exposed matching attribute field
+            boolean isAlreadyExposed = atts.containsKey(attName);
+            if (!isAlreadyExposed)
+            {
+               ops.add(new MBeanOperationInfo(op != null ? op.description() : "", method));
+               if (log.isDebugEnabled())
+               {
+                  log.debug("@Operation found for method " + method.getName());
+               }
+            }
+         }
+      }
+   }
+
+   private boolean isSetMethod(Method method)
+   {
+      return (method.getName().startsWith("set") &&
+            method.getParameterTypes().length == 1 &&
+            method.getReturnType() == java.lang.Void.TYPE);
+   }
+
+   private boolean isGetMethod(Method method)
+   {
+      return (method.getParameterTypes().length == 0 &&
+            method.getReturnType() != java.lang.Void.TYPE &&
+            method.getName().startsWith("get"));
+   }
+
+   private boolean isIsMethod(Method method)
+   {
+      return (method.getParameterTypes().length == 0 &&
+            (method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class) &&
+            method.getName().startsWith("is"));
+   }
+
+   private void findFields()
+   {
+      //traverse class hierarchy and find all annotated fields
+      for (Class<?> clazz = getObject().getClass(); clazz != null; clazz = clazz.getSuperclass())
+      {
+
+         Field[] fields = clazz.getDeclaredFields();
+         for (Field field : fields)
+         {
+            ManagedAttribute attr = field.getAnnotation(ManagedAttribute.class);
+            if (attr != null)
+            {
+               String fieldName = renameToJavaCodingConvention(field.getName());
+               MBeanAttributeInfo info = new MBeanAttributeInfo(fieldName,
+                     field.getType().getCanonicalName(),
+                     attr.description(),
+                     true,
+                     Modifier.isFinal(field.getModifiers()) ? false : attr.writable(),
+                     false);
+
+               atts.put(fieldName, new FieldAttributeEntry(info, field));
+               if (log.isDebugEnabled())
+               {
+                  log.debug("@Attr found for field " + field.getName());
+               }
+            }
+         }
+      }
+   }
+
+   private Attribute getNamedAttribute(String name)
+   {
+      Attribute result = null;
+      if (name.equals(MBEAN_DESCRITION))
+      {
+         result = new Attribute(MBEAN_DESCRITION, this.description);
+      }
+      else
+      {
+         AttributeEntry entry = atts.get(name);
+         if (entry != null)
+         {
+            MBeanAttributeInfo i = entry.getInfo();
+            try
+            {
+               result = new Attribute(name, entry.invoke(null));
+               if (log.isDebugEnabled())
+                  log.debug("Attribute " + name
+                        + " has r="
+                        + i.isReadable()
+                        + ",w="
+                        + i.isWritable()
+                        + ",is="
+                        + i.isIs()
+                        + " and value "
+                        + result.getValue());
+            }
+            catch (Exception e)
+            {
+               log.debug("Exception while reading value of attribute " + name, e);
+            }
+         }
+         else
+         {
+            log.warn("Did not find queried attribute with name " + name);
+         }
+      }
+      return result;
+   }
+
+   private boolean setNamedAttribute(Attribute attribute)
+   {
+      boolean result = false;
+      if (log.isDebugEnabled())
+         log.debug("Invoking set on attribute " + attribute.getName()
+               + " with value "
+               + attribute.getValue());
+
+      AttributeEntry entry = atts.get(attribute.getName());
+      if (entry != null)
+      {
+         try
+         {
+            entry.invoke(attribute);
+            result = true;
+         }
+         catch (Exception e)
+         {
+            log.warn("Exception while writing value for attribute " + attribute.getName(), e);
+         }
+      }
+      else
+      {
+         log.warn("Could not invoke set on attribute " + attribute.getName()
+               + " with value "
+               + attribute.getValue());
+      }
+      return result;
+   }
+
+
+   private String renameToJavaCodingConvention(String fieldName)
+   {
+      if (fieldName.contains("_"))
+      {
+         Pattern p = Pattern.compile("_.");
+         Matcher m = p.matcher(fieldName);
+         StringBuffer sb = new StringBuffer();
+         while (m.find())
+         {
+            m.appendReplacement(sb, fieldName.substring(m.end() - 1, m.end()).toUpperCase());
+         }
+         m.appendTail(sb);
+         char first = sb.charAt(0);
+         if (Character.isLowerCase(first))
+         {
+            sb.setCharAt(0, Character.toUpperCase(first));
+         }
+         return sb.toString();
+      }
+      else
+      {
+         if (Character.isLowerCase(fieldName.charAt(0)))
+         {
+            return fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+         }
+         else
+         {
+            return fieldName;
+         }
+      }
+   }
+
+   private boolean isMBeanAnnotationPresentWithExposeAll()
+   {
+      Class<?> c = getObject().getClass();
+      return c.isAnnotationPresent(MBean.class) && c.getAnnotation(MBean.class).exposeAll();
+   }
+
+   private class MethodAttributeEntry implements AttributeEntry
+   {
+
+      final MBeanAttributeInfo info;
+
+      final Method isOrGetmethod;
+
+      final Method setMethod;
+
+      public MethodAttributeEntry(final MBeanAttributeInfo info,
+                                  final Method setMethod,
+                                  final Method isOrGetMethod)
+      {
+         super();
+         this.info = info;
+         this.setMethod = setMethod;
+         this.isOrGetmethod = isOrGetMethod;
+      }
+
+      public Object invoke(Attribute a) throws Exception
+      {
+         if (a == null && isOrGetmethod != null)
+            return isOrGetmethod.invoke(getObject(), new Object[]{});
+         else if (a != null && setMethod != null)
+            return setMethod.invoke(getObject(), new Object[]{a.getValue()});
+         else
+            return null;
+      }
+
+      public MBeanAttributeInfo getInfo()
+      {
+         return info;
+      }
+
+      public boolean hasIsOrGetMethod()
+      {
+         return isOrGetmethod != null;
+      }
+
+      public boolean hasSetMethod()
+      {
+         return setMethod != null;
+      }
+
+      public Method getIsOrGetMethod()
+      {
+         return isOrGetmethod;
+      }
+
+      public Method getSetMethod()
+      {
+         return setMethod;
+      }
+   }
+
+   private class FieldAttributeEntry implements AttributeEntry
+   {
+
+      private final MBeanAttributeInfo info;
+
+      private final Field field;
+
+      public FieldAttributeEntry(final MBeanAttributeInfo info, final Field field)
+      {
+         super();
+         this.info = info;
+         this.field = field;
+         if (!field.isAccessible())
+         {
+            field.setAccessible(true);
+         }
+      }
+
+      public Field getField()
+      {
+         return field;
+      }
+
+      public Object invoke(Attribute a) throws Exception
+      {
+         if (a == null)
+         {
+            return field.get(getObject());
+         }
+         else
+         {
+            field.set(getObject(), a.getValue());
+            return null;
+         }
+      }
+
+      public MBeanAttributeInfo getInfo()
+      {
+         return info;
+      }
+   }
+
+   private interface AttributeEntry
+   {
+      public Object invoke(Attribute a) throws Exception;
+
+      public MBeanAttributeInfo getInfo();
+   }
+
+   public boolean isManagedResource()
+   {
+      return !atts.isEmpty() || !ops.isEmpty();
+   }
+
+   public boolean isOperationRegistred(String operationName)
+   {
+      for (MBeanOperationInfo opInfo : this.ops)
+      {
+         if (opInfo.getName().equals(operationName))
+         {
+            return true;
+         }
+      }
+      return false;
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/jmx/annotations/MBean.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/annotations/MBean.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/annotations/MBean.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.cache.jmx.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Classes anotaded with this will be exposed as MBeans.
+ * If you are looking for more fined grained way of exposing jmx attributes/operations, take a look at
+ * {@link org.jboss.cache.jmx.annotations.ManagedAttribute} and {@link org.jboss.cache.jmx.annotations.ManagedOperation} 
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 3.0
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target( { ElementType.TYPE })
+ at Inherited
+public @interface MBean
+{
+   String objectName() default "";
+   boolean exposeAll() default false;
+   String description() default "";
+}

Added: core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedAttribute.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedAttribute.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedAttribute.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.cache.jmx.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Indicates that a public method or a field (any visibility) in
+ * an MBean class defines an MBean attribute. This annotation can
+ * be applied to either a field or a public setter and/or getter
+ * method of a public class that is itself is optionally annotated
+ * with an @MBean annotation, or inherits such an annotation from
+ * a superclass.
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD, ElementType.FIELD})
+public @interface ManagedAttribute
+{
+   String description() default "";
+
+   String name() default "";
+
+   boolean writable() default false;
+}

Added: core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedOperation.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedOperation.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/jmx/annotations/ManagedOperation.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.cache.jmx.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Indicates that a method in an MBean class defines an MBean
+ * operation. @ManagedOperation annotation can be applied to a
+ * public method of a public class that is itself optionally
+ * annotated with an @MBean annotation, or inherits such an
+ * annotation from a superclass.
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD})
+public @interface ManagedOperation
+{
+   String description() default "";
+}

Modified: core/trunk/src/test/java/org/jboss/cache/jmx/CacheJmxWrapperTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/jmx/CacheJmxWrapperTestBase.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/test/java/org/jboss/cache/jmx/CacheJmxWrapperTestBase.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -156,9 +156,8 @@
    {
       // should be 3 interceptor MBeans loaded:
       ObjectName[] interceptorMBeanNames = {
-            new ObjectName(baseName + JmxUtil.INTERCEPTOR_KEY + "TxInterceptor"),
-            new ObjectName(baseName + JmxUtil.INTERCEPTOR_KEY + "CacheMgmtInterceptor"),
-            new ObjectName(baseName + JmxUtil.INTERCEPTOR_KEY + "InvocationContextInterceptor")
+            new ObjectName(baseName + JmxUtil.JMX_RESOURCE_KEY + "TxInterceptor"),
+            new ObjectName(baseName + JmxUtil.JMX_RESOURCE_KEY + "CacheMgmtInterceptor"),
       };
 
       for (ObjectName n : interceptorMBeanNames)

Modified: core/trunk/src/test/java/org/jboss/cache/jmx/InterceptorRegistrationTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/jmx/InterceptorRegistrationTest.java	2008-08-07 16:45:39 UTC (rev 6540)
+++ core/trunk/src/test/java/org/jboss/cache/jmx/InterceptorRegistrationTest.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -277,7 +277,7 @@
    public void testRegisterInterceptors1() throws Exception
    {
       CacheJmxWrapper<String, String> wrapper = createWrapper(createConfiguration());
-      wrapper.setRegisterInterceptors(false);
+      wrapper.setRegisterJmxResource(false);
 
       registerWrapper(wrapper);
 
@@ -308,7 +308,7 @@
    public void testRegisterInterceptors2() throws Exception
    {
       CacheJmxWrapper<String, String> wrapper = createWrapper(createConfiguration());
-      wrapper.setRegisterInterceptors(false);
+      wrapper.setRegisterJmxResource(false);
 
       wrapper.create();
       wrapper.start();

Added: core/trunk/src/test/java/org/jboss/cache/jmx/ResourceDMBeanTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/jmx/ResourceDMBeanTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/jmx/ResourceDMBeanTest.java	2008-08-07 18:43:08 UTC (rev 6541)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt 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.cache.jmx;
+
+import org.testng.annotations.Test;
+import org.jboss.cache.interceptors.ActivationInterceptor;
+import org.jboss.cache.jmx.annotations.ManagedOperation;
+
+/**
+ * Tester class for {@link ResourceDMBean}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 3.0
+ */
+ at Test (groups = "unit")
+public class ResourceDMBeanTest
+{
+
+   /**
+    * If we have a method in the base class that is annotated as @ManagedOperation, will this be seen the same
+    * way in the inherited class?
+    */
+   public void testInheritedMethod()
+   {
+      Bbb bbb = new Bbb();
+      ResourceDMBean resourceDMBean = new ResourceDMBean(bbb);
+      assert resourceDMBean.isOperationRegistred("baseMethod");
+   }
+
+   static class Aaa
+   {
+      @ManagedOperation 
+      public void baseMethod() {}
+   }
+
+   static class Bbb extends Aaa
+   {
+      public void localMethod() {}
+   }
+}




More information about the jbosscache-commits mailing list