You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2010/10/21 18:01:52 UTC

svn commit: r1026046 - in /openjpa/trunk: openjpa-kernel/ openjpa-kernel/src/main/java/org/apache/openjpa/datacache/ openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/ openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconso...

Author: curtisr7
Date: Thu Oct 21 16:01:51 2010
New Revision: 1026046

URL: http://svn.apache.org/viewvc?rev=1026046&view=rev
Log:
OPENJPA-1844: Add DataCache JConsole plugin.

Added:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePanel.java   (with props)
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePlugin.java   (with props)
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheStatistic.java   (with props)
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheTable.java   (with props)
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheWorker.java   (with props)
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrumentMBean.java
    openjpa/trunk/openjpa-kernel/src/main/resources/META-INF/services/com.sun.tools.jconsole.JConsolePlugin
Modified:
    openjpa/trunk/openjpa-kernel/pom.xml
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrument.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/JMXProvider.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/instrumentation/TestInstrumentationProvider.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java

Modified: openjpa/trunk/openjpa-kernel/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/pom.xml?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/pom.xml (original)
+++ openjpa/trunk/openjpa-kernel/pom.xml Thu Oct 21 16:01:51 2010
@@ -65,6 +65,14 @@
             <artifactId>ant</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>sun.jconsole</groupId>
+            <artifactId>jconsole</artifactId>
+            <version>1.6.0</version>
+            <scope>system</scope>
+            <systemPath>${java.home}/../lib/jconsole.jar</systemPath>
+        </dependency>
+        
     </dependencies>
 
     <build>

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.datacache;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.openjpa.util.OpenJPAId;
+
+/**
+ * Counts number of read/write requests and hit ratio for a cache in total and
+ * per-class basis.
+ * 
+ * All methods with Class as input argument treats null as 
+ * <code>java.lang.Object</code>. All per-class statistics  depends on 
+ * determining the runtime type of the instance being cached. If it is not
+ * possible to determine the runtime type from the given context, the statistics
+ * is registered under generic <code>java.lang.Object</code>. 
+ * 
+ * @since 1.3.0
+ */
+public interface CacheStatistics extends Serializable {
+
+	/**
+	 * Gets number of total read requests since last reset.
+	 */
+	public long getReadCount();
+
+	/**
+	 * Gets number of total read requests that has been found in cache since
+	 * last reset.
+	 */
+	public long getHitCount();
+
+	/**
+	 * Gets number of total write requests since last reset.
+	 */
+	public long getWriteCount();
+
+	/**
+	 * Gets number of total read requests since start.
+	 */
+	public long getTotalReadCount();
+
+	/**
+	 * Gets number of total read requests that has been found in cache since
+	 * start.
+	 */
+	public long getTotalHitCount();
+
+	/**
+	 * Gets number of total write requests since start.
+	 */
+	public long getTotalWriteCount();
+
+    /**
+     * Gets number of total read requests for the given class since last reset.
+     * 
+     * @deprecated - should use getReadCount(String c)
+     */
+    public long getReadCount(Class<?> cls);
+  
+    /**
+     * Gets number of total read requests for the given class since last reset.
+	 */
+	public long getReadCount(String c);
+
+    /**
+     * Gets number of total read requests that has been found in cache for the given class since last reset.
+     * 
+     * @deprecated - should use getHitCount(String c)
+     */
+    public long getHitCount(Class<?> cls);
+    
+	/**
+     * Gets number of total read requests that has been found in cache for the given class since last reset.
+     */
+	public long getHitCount(String c);
+	
+	/**
+     * Gets number of total write requests for the given class since last reset.
+     * 
+     * @deprecated - should use getWriteCount(String c)
+     */
+    public long getWriteCount(Class<?> cls);
+
+    /**
+     * Gets number of total write requests for the given class since last reset.
+	 */
+	public long getWriteCount(String c);
+
+	/**
+     * Gets number of total read requests for the given class since start.
+     * 
+     * @deprecated - should use getTotalReadCount(String c)
+     */
+    public long getTotalReadCount(Class<?> cls);
+    
+	/**
+	 * Gets number of total read requests for the given class since start.
+	 */
+	public long getTotalReadCount(String c);
+
+	/**
+     * Gets number of total read requests that has been found in cache for the given class since start.
+     */
+    public long getTotalHitCount(String c);
+
+    /**
+     * Gets number of total read requests that has been found in cache for the given class since start.
+     * 
+     * @deprecated - should use getTotalHitCount(String c)
+     */
+    public long getTotalHitCount(Class<?> cls);
+
+	/**
+     * Gets number of total write requests for the given class since start.
+     */
+    public long getTotalWriteCount(String c);
+
+    /**
+     * Gets number of total write requests for the given class since start.
+     * 
+     * @deprecated - should use getTotalWriteCount(String c)
+     */
+    public long getTotalWriteCount(Class<?> cls);
+
+	/**
+	 * Gets the time of last reset.
+	 */
+	public Date since();
+
+	/**
+	 * Gets the time of start.
+	 */
+	public Date start();
+
+	/**
+	 * Clears all accumulated statistics.
+	 */
+	public void reset();
+	
+	/**
+	 * Returns whether or not statistics will be collected.
+	 */
+	public boolean isEnabled();
+	
+	/**
+	 * Returns the types that are known to this cache being tracked.
+	 */
+    public Set<String> classNames();
+    
+}

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java Thu Oct 21 16:01:51 2010
@@ -33,8 +33,9 @@ public class CacheStatisticsImpl impleme
     private static final int ARRAY_SIZE = 3;
     private long[] astat = new long[ARRAY_SIZE];
     private long[] stat = new long[ARRAY_SIZE];
-    private Map<Class<?>, long[]> stats = new HashMap<Class<?>, long[]>();
-    private Map<Class<?>, long[]> astats = new HashMap<Class<?>, long[]>();
+    private Map<String, long[]> stats = new HashMap<String, long[]>();
+    private Map<String, long[]> astats = new HashMap<String, long[]>();
+
     private Date start = new Date();
     private Date since = new Date();
     private boolean enabled = false;
@@ -68,27 +69,50 @@ public class CacheStatisticsImpl impleme
     }
 
     public long getReadCount(Class<?> c) {
-        return getCount(stats, c, READ);
+        return getReadCount(c.getName());        
+    }
+    
+    public long getReadCount(String str){
+        return getCount(stats, str, READ);
     }
 
     public long getHitCount(Class<?> c) {
-        return getCount(stats, c, HIT);
+        return getHitCount(c.getName());
     }
 
+    public long getHitCount(String str) {
+        return getCount(stats, str, HIT);
+    }
+    
     public long getWriteCount(Class<?> c) {
-        return getCount(stats, c, WRITE);
+        return getWriteCount(c.getName());
+    }
+    public long getWriteCount(String str) {
+        return getCount(stats, str, WRITE);
     }
 
     public long getTotalReadCount(Class<?> c) {
-        return getCount(astats, c, READ);
+        return getTotalReadCount(c.getName());
     }
 
+    public long getTotalReadCount(String str) {
+        return getCount(astats, str, READ);        
+    }
+    
     public long getTotalHitCount(Class<?> c) {
-        return getCount(astats, c, HIT);
+        return getTotalHitCount(c.getName());   
+    }
+    
+    public long getTotalHitCount(String str) {
+        return getCount(astats, str, HIT);
     }
 
     public long getTotalWriteCount(Class<?> c) {
-        return getCount(astats, c, WRITE);
+        return getCount(astats, c.getName(), WRITE);
+    }
+    
+    public long getTotalWriteCount(String str) {
+        return getCount(astats, str, WRITE);
     }
 
     public Date since() {
@@ -109,7 +133,7 @@ public class CacheStatisticsImpl impleme
         return enabled;
     }
 
-    public Set<Class<?>> classNames() {
+    public Set<String> classNames() {
         return astats.keySet();
     }
     
@@ -129,9 +153,10 @@ public class CacheStatisticsImpl impleme
             return;
         }
         cls = (cls == null) ? Object.class : cls;
-        addSample(cls, READ);
+        String clsName = cls.getName();
+        addSample(clsName, READ);
         if (hit) {
-            addSample(cls, HIT);
+            addSample(clsName, HIT);
         }
     }
 
@@ -149,7 +174,7 @@ public class CacheStatisticsImpl impleme
             return;
         }
         cls = (cls == null) ? Object.class : cls;
-        addSample(cls, WRITE);
+        addSample(cls.getName(), WRITE);
     }
 
     public void newPut(Object oid) {
@@ -164,14 +189,14 @@ public class CacheStatisticsImpl impleme
     /**
      *  Private worker methods.
      */
-    private void addSample(Class<?> c, int index) {
+    private void addSample(String c, int index) {
         stat[index]++;
         astat[index]++;
         addSample(stats, c, index);
         addSample(astats, c, index);
     }
 
-    private void addSample(Map<Class<?>, long[]> target, Class<?> c, int index) {
+    private void addSample(Map<String, long[]> target, String c, int index) {
         long[] row = target.get(c);
         if (row == null) {
             row = new long[ARRAY_SIZE];
@@ -180,7 +205,7 @@ public class CacheStatisticsImpl impleme
         target.put(c, row);
     }
 
-    private long getCount(Map<Class<?>, long[]> target, Class<?> c, int index) {
+    private long getCount(Map<String, long[]> target, String c, int index) {
         long[] row = target.get(c);
         return (row == null) ? 0 : row[index];
     }

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.datacache;
+
+/**
+ * The provider extensions to the CacheStatistics interface.
+ */
+public interface CacheStatisticsSPI extends CacheStatistics {
+    /**
+     * Record a new cache get.
+     * 
+     * @param cls
+     *            - The class describing the type that is contained in the cache.
+     * @param hit
+     *            - true for a cache hit, false otherwise
+     */
+    public void newGet(Class<?> cls, boolean hit);
+
+
+    /**
+     * Record a new cache put.
+     * 
+     * @param cls
+     *            - The class describing the type that is contained in the cache.
+     */
+    public void newPut(Class<?> cls);
+
+
+    /**
+     * Enable statistics collection.
+     */
+    public void enable();
+
+    /**
+     * Disable statistics collection.
+     */
+    public void disable();
+}

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManager.java Thu Oct 21 16:01:51 2010
@@ -18,9 +18,10 @@
  */
 package org.apache.openjpa.datacache;
 
+import java.util.Map;
+
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.conf.Configurable;
 import org.apache.openjpa.lib.conf.ObjectValue;
 
 /**
@@ -98,9 +99,24 @@ public interface DataCacheManager {
      * @since 2.0.0
      */
     public CacheDistributionPolicy getDistributionPolicy();
-    
+
     /**
      * Close all caches.
      */
     public void close();
+    
+    /**
+     * Stop caching the type matching the provided class name.
+     */
+    public void stopCaching(String cls);
+
+    /**
+     * Start caching the type matching the provided class name.
+     */
+    public void startCaching(String cls);
+
+    /**
+     * Returns the names of classes that are known to the cache and whether or not they are currently being cached.
+     */
+    public Map<String, Boolean> listKnownTypes();
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheManagerImpl.java Thu Oct 21 16:01:51 2010
@@ -21,6 +21,7 @@ package org.apache.openjpa.datacache;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.Map.Entry;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.enhance.PCDataGenerator;
@@ -28,6 +29,7 @@ import org.apache.openjpa.kernel.OpenJPA
 import org.apache.openjpa.lib.conf.ObjectValue;
 import org.apache.openjpa.lib.util.Closeable;
 import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
 import org.apache.openjpa.util.ImplHelper;
 
 /**
@@ -198,4 +200,24 @@ public class DataCacheManagerImpl
         // Check for @DataCache annotations
         return meta.getDataCacheName() != null;
     }
+
+    public void startCaching(String cls) {
+        MetaDataRepository mdr = _conf.getMetaDataRepositoryInstance();
+        ClassMetaData cmd = mdr.getCachedMetaData(cls);
+        _cacheable.put(cmd, Boolean.TRUE);
+    }
+
+    public void stopCaching(String cls) {
+        MetaDataRepository mdr = _conf.getMetaDataRepositoryInstance();
+        ClassMetaData cmd = mdr.getCachedMetaData(cls);
+        _cacheable.put(cmd, Boolean.FALSE);
+    }
+
+    public Map<String, Boolean> listKnownTypes() {
+        Map<String, Boolean> res = new HashMap<String, Boolean>();
+        for (Entry<ClassMetaData, Boolean> entry : _cacheable.entrySet()) {
+            res.put(entry.getKey().getDescribedTypeString(), entry.getValue());
+        }
+        return res;
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java Thu Oct 21 16:01:51 2010
@@ -21,68 +21,64 @@ package org.apache.openjpa.instrumentati
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.openjpa.datacache.CacheStatistics;
+import org.apache.openjpa.datacache.CacheStatisticsSPI;
 import org.apache.openjpa.datacache.DataCache;
+import org.apache.openjpa.datacache.DataCacheManager;
+import org.apache.openjpa.datacache.DataCacheManagerImpl;
 import org.apache.openjpa.lib.instrumentation.AbstractInstrument;
 import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
 
 /**
- * Provides a basic instrument implementation wrapper for the data cache.  This
- * class can be extended to create a provider specific instrument for the
- * data cache.
+ * Provides a basic instrument implementation wrapper for the data cache. This class can be extended to create a
+ * provider specific instrument for the data cache.
  */
-public abstract class AbstractDataCacheInstrument extends AbstractInstrument 
-    implements DataCacheInstrument {
+public abstract class AbstractDataCacheInstrument extends AbstractInstrument implements DataCacheInstrument {
 
     /**
      * Value indicating that cache statistics are not available.
      */
     public static final long NO_STATS = -1;
 
+    private DataCacheManager _dcm = null;
     private DataCache _dc = null;
     private String _configID = null;
     private String _configRef = null;
-        
+
     public void setDataCache(DataCache dc) {
         _dc = dc;
     }
-    
+
+    public void setDataCacheManager(DataCacheManager dcm) {
+        _dcm = dcm;
+    }
+
     public void setConfigId(String cid) {
         _configID = cid;
     }
-    
+
     public void setContextRef(String cref) {
         _configRef = cref;
     }
-        
+
     public long getHitCount() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getHitCount();
         return NO_STATS;
     }
-    
-    public long getHitCount(String className) 
-        throws ClassNotFoundException {
-        Class<?> clazz = Class.forName(className);
-        return getHitCount(clazz);
-    }
-    
+
     public long getReadCount() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getReadCount();
         return NO_STATS;
     }
-    
-    public long getReadCount(String className)
-        throws ClassNotFoundException {
-        Class<?> clazz = Class.forName(className);
-        return getReadCount(clazz);        
-    }
-    
+
     public long getTotalHitCount() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
@@ -90,12 +86,6 @@ public abstract class AbstractDataCacheI
         return NO_STATS;
     }
 
-    public long getTotalHitCount(String className)
-        throws ClassNotFoundException {
-        Class<?> clazz = Class.forName(className);
-        return getTotalHitCount(clazz);      
-    }
-    
     public long getTotalReadCount() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
@@ -103,12 +93,6 @@ public abstract class AbstractDataCacheI
         return NO_STATS;
     }
 
-    public long getTotalReadCount(String className)
-        throws ClassNotFoundException {
-        Class<?> clazz = Class.forName(className);
-        return getTotalReadCount(clazz);      
-    }
-    
     public long getTotalWriteCount() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
@@ -116,12 +100,6 @@ public abstract class AbstractDataCacheI
         return NO_STATS;
     }
 
-    public long getTotalWriteCount(String className)
-        throws ClassNotFoundException {
-        Class<?> clazz = Class.forName(className);
-        return getTotalWriteCount(clazz);      
-    }
-    
     public long getWriteCount() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
@@ -129,32 +107,26 @@ public abstract class AbstractDataCacheI
         return NO_STATS;
     }
 
-    public long getWriteCount(String className)
-        throws ClassNotFoundException {
-        Class<?> clazz = Class.forName(className);
-        return getWriteCount(clazz);      
-    }
-
     public void reset() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
-            stats.reset();        
+            stats.reset();
     }
-    
+
     public Date sinceDate() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.since();
         return null;
     }
-    
+
     public Date startDate() {
         CacheStatistics stats = getStatistics();
         if (stats != null)
-            return stats.start();        
+            return stats.start();
         return null;
     }
-    
+
     public String getConfigId() {
         return _configID;
     }
@@ -168,7 +140,7 @@ public abstract class AbstractDataCacheI
             return _dc.getName();
         return null;
     }
-    
+
     private CacheStatistics getStatistics() {
         if (_dc != null) {
             return _dc.getStatistics();
@@ -176,65 +148,80 @@ public abstract class AbstractDataCacheI
         return null;
     }
 
-    private long getWriteCount(Class<?> c) {
+    public long getWriteCount(String c) {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getWriteCount(c);
         return NO_STATS;
     }
-    
-    private long getTotalWriteCount(Class<?> c) {
+
+    public long getTotalWriteCount(String c) {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getTotalWriteCount(c);
         return NO_STATS;
     }
-    
-    private long getTotalReadCount(Class<?> c) {
+
+    public long getTotalReadCount(String c) {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getTotalReadCount(c);
         return NO_STATS;
     }
-    
-    private long getTotalHitCount(Class<?> c) {
+
+    public long getTotalHitCount(String c) {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getTotalHitCount(c);
         return NO_STATS;
     }
 
-    private long getReadCount(Class<?> c) {
+    public long getReadCount(String c) {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getReadCount(c);
         return NO_STATS;
     }
 
-    private long getHitCount(Class<?> c) {
+    public long getHitCount(String c) {
         CacheStatistics stats = getStatistics();
         if (stats != null)
             return stats.getHitCount(c);
         return NO_STATS;
     }
-    
-    @SuppressWarnings("unchecked")
-    public Set<String> classNames() {
-        CacheStatistics stats = getStatistics();
-        if (stats != null) {
-            Set<String> classNames = new HashSet<String>();
-            Set<Class<?>> clazzNames = stats.classNames();
-            for (Class<?> clazz : clazzNames) {
-                if (clazz != null) {
-                    classNames.add(clazz.getName());
-                }
-            }
-            return classNames;
-        }
-        return Collections.EMPTY_SET;
-    }
-    
+
     public InstrumentationLevel getLevel() {
         return InstrumentationLevel.FACTORY;
     }
+
+    public void cache(String className, boolean enable) {
+        if (enable) {
+            _dcm.startCaching(className);
+        } else {
+            _dcm.stopCaching(className);
+        }
+    }
+
+    public Map<String, Boolean> listKnownTypes() {
+        return _dcm.listKnownTypes();
+    }
+    public void collectStatistics(boolean enable) {
+        CacheStatisticsSPI stats = (CacheStatisticsSPI) _dc.getStatistics();
+        if (enable) {
+            stats.enable();
+        } else {
+            stats.disable();
+        }
+    }
+
+    public Boolean getStatisticsEnabled() {
+        CacheStatisticsSPI stats = (CacheStatisticsSPI) _dc.getStatistics();
+        return stats.isEnabled();
+    }
+    public CacheStatistics getCacheStatistics() {
+        return _dc.getStatistics();
+    }
+    public void clear() {
+        _dc.clear();
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java Thu Oct 21 16:01:51 2010
@@ -19,7 +19,10 @@
 package org.apache.openjpa.instrumentation;
 
 import java.util.Date;
-import java.util.Set;
+import java.util.Map;
+
+import org.apache.openjpa.datacache.CacheStatistics;
+import org.apache.openjpa.datacache.DataCacheManager;
 
 /**
  * Interface for providing instrumented data cache metrics and operations.
@@ -29,68 +32,63 @@ public interface DataCacheInstrument {
     /**
      * Gets number of total read requests for the given class since last reset.
      */
-    public long getReadCount(String className) throws ClassNotFoundException;
+    public long getReadCount(String className);
 
     /**
-     * Gets number of total read requests that has been found in cache for the
-     * given class since last reset.
+     * Gets number of total read requests that has been found in cache for the given class since last reset.
      */
-    public long getHitCount(String className) throws ClassNotFoundException;
+    public long getHitCount(String className);
 
     /**
      * Gets number of total write requests for the given class since last reset.
      */
-    public long getWriteCount(String className) throws ClassNotFoundException;
+    public long getWriteCount(String className);
 
     /**
      * Gets number of total read requests for the given class since start.
      */
-    public long getTotalReadCount(String className) 
-        throws ClassNotFoundException;
+    public long getTotalReadCount(String className);
 
     /**
-     * Gets number of total read requests that has been found in cache for the
-     * given class since start.
+     * Gets number of total read requests that has been found in cache for the given class since start.
      */
-    public long getTotalHitCount(String className) 
-        throws ClassNotFoundException;
+    public long getTotalHitCount(String className);
 
     /**
      * Gets number of total write requests for the given class since start.
      */
-    public long getTotalWriteCount(String className) 
-        throws ClassNotFoundException;
-       
+    public long getTotalWriteCount(String className);
+
     /**
      * Returns the name of the cache
      */
     public String getCacheName();
-    
+
     /**
      * Returns the hit count since cache statistics were last reset
      */
     public long getHitCount();
-        
+
     /**
      * Returns the read count since cache statistics were last reset
      */
     public long getReadCount();
-        
+
     /**
      * Returns the total hits since start.
      */
     public long getTotalHitCount();
-    
+
     /**
      * Returns the total reads since start.
      */
     public long getTotalReadCount();
-    
+
     /**
      * Returns the total writes since start.
      */
     public long getTotalWriteCount();
-    
+
     /**
      * Returns the write count since cache statistics were last reset
      */
@@ -100,19 +98,45 @@ public interface DataCacheInstrument {
      * Resets cache statistics
      */
     public void reset();
-    
+
     /**
      * Returns date since cache statistics collection were last reset.
      */
     public Date sinceDate();
-    
+
     /**
      * Returns date cache statistics collection started.
      */
     public Date startDate();
+
+    /**
+     * Returns the names of classes that are known to the cache and whether or not they are currently being cached.
+     */
+    public Map<String, Boolean> listKnownTypes();
+
+    /**
+     * Returns true if cache statistics are currently being calculated. False otherwise.
+     */
+    public Boolean getStatisticsEnabled();
+
+    /**
+     * 
+     * @param enable - If true, the cache will start collecting statistics. Else cache statistics will not be collected.
+     */
+    public void collectStatistics(boolean enable);
+
+    /**
+     * This method is used to enable/disable caching for the specified className.
+     */
+    public void cache(String className, boolean enable);
+    
+    /**
+     * Returns the CacheStatistics for the cache.
+     */
+    public CacheStatistics getCacheStatistics();
     
     /**
-     * Returns the names of classes currently tracked in the cache.
+     * Clears all data from the DataCache.
      */
-    public Set<String> classNames();
+    public void clear();
 }

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePanel.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePanel.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePanel.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePanel.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.instrumentation.jconsole;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.ItemSelectable;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.border.LineBorder;
+import javax.swing.border.TitledBorder;
+
+import org.apache.openjpa.instrumentation.jmx.DataCacheJMXInstrumentMBean;
+
+/**
+ * <pre>
+ * 
+ * DataCachePanel Layout:
+ *  -> parentTopPanel:JPanel
+ *      -> actionsPanel:JPanel
+ *          -> enable checkbox
+ *          -> clear cache button
+ *          -> reset stats button
+ *      -> types panel
+ *          -> [N] types
+ *  -> statisticsPanel:JScrollPane
+ *  
+ * </pre>
+ */
+public class DataCachePanel extends JPanel {
+    private static final long serialVersionUID = 8273595264174478456L;
+    private DataCacheJMXInstrumentMBean _mbean;
+    private DataCacheTable _model;
+    private Map<String, JCheckBox> _typesPanelMap = new ConcurrentHashMap<String, JCheckBox>();
+    private JPanel _typesPanel;
+
+    public DataCachePanel(DataCacheJMXInstrumentMBean mbean) {
+        super(new BorderLayout());
+        _model = new DataCacheTable();
+        _mbean = mbean;
+
+        // setup parent panel
+        JPanel parentTopPanel = new JPanel(new GridLayout(2, 0));
+        parentTopPanel.setBorder(new TitledBorder(LineBorder.createGrayLineBorder(), ""));
+        // Add parentTopPanel to DataCachePanel
+        add(parentTopPanel, BorderLayout.PAGE_START);
+
+        // Panel for action buttons
+        JPanel actionsPanel = new JPanel(new GridLayout(1, 3));
+        actionsPanel.setBorder(new TitledBorder(LineBorder.createGrayLineBorder(), "Actions"));
+        parentTopPanel.add(actionsPanel, -1);
+
+        // Create new panel for [N] children checkboxes
+        // Don't add anything here yet. This will happen dynamically in updateTypesCached
+        _typesPanel = new JPanel(new GridLayout());
+        _typesPanel.setBorder(new TitledBorder(LineBorder.createGrayLineBorder(), "Currently known types"));
+        parentTopPanel.add(_typesPanel, -1);
+
+        // create enabled check box to parent
+        JCheckBox enableStatisticsCheckBox = new JCheckBox("Statistics enabled", mbean.getStatisticsEnabled());
+        enableStatisticsCheckBox.addItemListener(new ItemListener() {
+            public void itemStateChanged(ItemEvent e) {
+                boolean enable = (e.getStateChange() == ItemEvent.SELECTED);
+                _mbean.collectStatistics(enable);
+            }
+        });
+
+        // create clear cache button
+        JButton clear = new JButton("Clear cache");
+        clear.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                _mbean.clear();
+            }
+        });
+
+        // create clear cache button
+        JButton reset = new JButton("Reset statistics");
+        reset.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                _mbean.reset();
+            }
+        });
+
+        actionsPanel.add(enableStatisticsCheckBox, -1);
+        actionsPanel.add(clear, -1);
+        actionsPanel.add(reset, -1);
+
+        // setup stats table
+        JTable table = new JTable(_model);
+        table.setPreferredScrollableViewportSize(new Dimension(500, 300));
+        table.setIntercellSpacing(new Dimension(6, 3));
+        table.setRowHeight(table.getRowHeight() + 4);
+        add(new JScrollPane(table), BorderLayout.PAGE_END);
+    }
+
+    DataCacheTable getModel() {
+        return _model;
+    }
+
+    /**
+     * This method is responsible for taking the provided DataCacheStatistic and adding any a check box for any types
+     * that we don't already know about.
+     */
+    void updateTypesCached(DataCacheStatistic stat) {
+        List<String> masterList = stat.getAllTypes();
+        List<String> enabled = stat.getEnabledTypes();
+
+        for (String s : masterList) {
+            JCheckBox box = _typesPanelMap.get(s);
+            if (box == null) {
+                // We don't know about this type, make a new check box.
+                box = new JCheckBox(s, enabled.contains(s));
+                box.setName(s);
+                box.addItemListener(new ItemListener() {
+                    public void itemStateChanged(ItemEvent e) {
+                        // When this item is selected / deselected, spin up a new thread to make MBean call
+                        final ItemSelectable item = e.getItemSelectable();
+                        if (item instanceof JCheckBox) {
+                            try {
+                                new Thread() {
+                                    public void run() {
+                                        JCheckBox jcb = (JCheckBox) item;
+                                        _mbean.cache(jcb.getName(), jcb.isSelected());
+                                    };
+                                }.start();
+                            } catch (Exception ex) {
+                                // Unexpected
+                                ex.printStackTrace();
+                            }
+
+                        }
+                    }
+                });
+
+                _typesPanel.add(box);
+                _typesPanelMap.put(s, box);
+            } else {
+                box.setSelected(enabled.contains(s));
+            }
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePlugin.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePlugin.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePlugin.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePlugin.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.instrumentation.jconsole;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.JMX;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.swing.JPanel;
+import javax.swing.SwingWorker;
+
+import org.apache.openjpa.instrumentation.jmx.DataCacheJMXInstrumentMBean;
+
+import com.sun.tools.jconsole.JConsoleContext;
+import com.sun.tools.jconsole.JConsolePlugin;
+
+/**
+ * DataCachePlugin
+ */
+public class DataCachePlugin extends JConsolePlugin {
+    private Map<String, JPanel> _tabs;
+    private Map<DataCacheJMXInstrumentMBean, DataCachePanel> _mbeanPanelMap;
+
+    @Override
+    public Map<String, JPanel> getTabs() {
+        if (_tabs == null) {
+            _tabs = buildPanels(getMbeans());
+        }
+        return _tabs;
+    }
+
+    @Override
+    public SwingWorker<Map<DataCachePanel, DataCacheStatistic>, Object> newSwingWorker() {
+        return new DataCacheWorker(_mbeanPanelMap);
+    }
+
+    /**
+     * Private worker method that instantiates the CacheName -> DataCachePanel mapping.
+     */
+    private Map<String, JPanel> buildPanels(Map<String, DataCacheJMXInstrumentMBean> mbeans) {
+        _mbeanPanelMap = new HashMap<DataCacheJMXInstrumentMBean, DataCachePanel>();
+        Map<String, JPanel> res = new HashMap<String, JPanel>();
+        for (Map.Entry<String, DataCacheJMXInstrumentMBean> entry : mbeans.entrySet()) {
+            DataCacheJMXInstrumentMBean m = entry.getValue();
+            String cfgId = entry.getKey();
+            String name = m.getCacheName();
+
+            // TODO -- should NLSize this tab.
+            DataCachePanel panel = new DataCachePanel(m);
+            String key = "DataCache-" + cfgId + "-" + name;
+            // This 'shouldn't' ever happen... but it will if we have name collisions for one reason or another.
+            while (res.containsKey(key) == true) {
+                key = key + "_dup";
+            }
+            res.put(key, panel);
+            _mbeanPanelMap.put(m, panel);
+        }
+        return res;
+    }
+
+    /**
+     * Private worker method that returns all MBeans matching the query "org.apache.openjpa:type=DataCache,*"
+     */
+    private Map<String, DataCacheJMXInstrumentMBean> getMbeans() {
+        Map<String, DataCacheJMXInstrumentMBean> mbeans = new HashMap<String, DataCacheJMXInstrumentMBean>();
+
+        JConsoleContext ctx = getContext();
+        Set<MBeanServerConnection> connections = new HashSet<MBeanServerConnection>();
+        connections.add(ctx.getMBeanServerConnection());
+        connections.addAll(MBeanServerFactory.findMBeanServer(null));
+        if (connections == null || connections.size() == 0) {
+            System.err
+                .println("DataCachePlugin found zero from MBeanServerFactory.findMBeanServer(null) using default");
+        }
+
+        for (MBeanServerConnection server : connections) {
+            try {
+                ObjectName generic = new ObjectName("org.apache.openjpa:type=DataCache,*");
+                ObjectName[] objects = server.queryNames(generic, null).toArray(new ObjectName[0]);
+                if (objects == null || objects.length == 0) {
+                    System.err
+                        .println("No ObjectNames found matching 'org.apache.openjpa:type=DataCache,*' for MBeanServer "
+                            + server);
+                }
+                for (ObjectName o : objects) {
+                    DataCacheJMXInstrumentMBean bean = JMX.newMBeanProxy(server, o, DataCacheJMXInstrumentMBean.class);
+                    String cfgId = o.getKeyProperty("cfgid");
+                    // Handle config id collision
+                    int i = 1;
+                    String tempCfgId = cfgId;
+                    while (mbeans.containsKey(tempCfgId)) {
+                        tempCfgId = cfgId + "-" + i;
+                        i++;
+                    }
+                    mbeans.put(tempCfgId, bean);
+                }
+            } catch (Exception e) {
+                // Shouldn't happen. Allow to bubble up as runtime exception
+                throw new RuntimeException(e);
+            }
+        }
+        return mbeans;
+    }
+}

Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCachePlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheStatistic.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheStatistic.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheStatistic.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheStatistic.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.instrumentation.jconsole;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.openjpa.datacache.CacheStatistics;
+
+/**
+ * This class is a wrapper around org.apache.openjpa.datacache.CacheStatistics along with the stringified types that a
+ * given cache knows about.
+ */
+public class DataCacheStatistic {
+    CacheStatistics _stats;
+    Map<String, Boolean> _types;
+    List<String> _master;
+    List<String> _enabledTypes;
+    List<String> _disabledTypes;
+
+    public DataCacheStatistic(CacheStatistics stats, Map<String, Boolean> types) {
+        _stats = stats;
+        _types = types;
+        _enabledTypes = new ArrayList<String>();
+        _disabledTypes = new ArrayList<String>();
+        _master = new ArrayList<String>();
+        for (Entry<String, Boolean> type : types.entrySet()) {
+            boolean enabled = type.getValue();
+            String name = type.getKey();
+            if (enabled) {
+                _enabledTypes.add(name);
+            } else {
+                _disabledTypes.add(name);
+            }
+            _master.add(name);
+        }
+    }
+
+    public long getReads(String cls) {
+        return _stats.getReadCount(cls);
+    }
+
+    public long getHits(String cls) {
+        return _stats.getHitCount(cls);
+    }
+
+    public long getWrites(String cls) {
+        return _stats.getWriteCount(cls);
+    }
+
+    public List<String> getEnabledTypes() {
+        return _enabledTypes;
+    }
+
+    public List<String> getDisabledTypes() {
+        return _disabledTypes;
+    }
+
+    public List<String> getAllTypes() {
+        return _master;
+    }
+
+    public int getNumTypes() {
+        return _disabledTypes.size() + _enabledTypes.size();
+    }
+}

Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheStatistic.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheTable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheTable.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheTable.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheTable.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.instrumentation.jconsole;
+
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+/**
+ * DataCacheTable
+ */
+public class DataCacheTable extends AbstractTableModel {
+    private static final long serialVersionUID = -117710809875227870L;
+    // TODO -- should NLSize these column names
+    private String[] _cols = { "key", "reads", "hits", "writes" };
+    // row, col
+    private Object[][] _tableData;
+
+    public int getColumnCount() {
+        return _cols.length;
+    }
+
+    public int getRowCount() {
+        return (_tableData == null) ? 0 : _tableData.length;
+    }
+
+    public Object getValueAt(int row, int col) {
+        return _tableData[row][col];
+    }
+
+    public String getColumnName(int col) {
+        return _cols[col];
+    }
+
+    public void setDataCacheStatistics(DataCacheStatistic s) {
+        // extract data from statistics into table format
+        _tableData = new Object[s.getNumTypes()][_cols.length];
+        List<String> types = s.getAllTypes();
+        for (int i = 0; i < types.size(); i++) {
+            String type = types.get(i);
+            // { "key", "reads", "hits", "writes" }
+            _tableData[i][0] = type;
+            _tableData[i][1] = s.getReads(type);
+            _tableData[i][2] = s.getHits(type);
+            _tableData[i][3] = s.getWrites(type);
+        }
+    }
+
+}

Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheTable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheWorker.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheWorker.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheWorker.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheWorker.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.instrumentation.jconsole;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.swing.SwingWorker;
+
+import org.apache.openjpa.datacache.CacheStatistics;
+import org.apache.openjpa.instrumentation.jmx.DataCacheJMXInstrumentMBean;
+
+/**
+ * This worker class is driven by the JConsole. On a specified interval(default 4 sec, or -interval=n) this worker will
+ * be created and doInBackground() will be called. This method is responsible for performing any long running tasks that
+ * will collect data to be displayed by the UI.
+ * 
+ * It keeps a mapping of MBean -> JConsole panel. On each run it needs to collect data which corresponds to each known
+ * panel.
+ */
+public class DataCacheWorker extends SwingWorker<Map<DataCachePanel, DataCacheStatistic>, Object> {
+    Map<DataCacheJMXInstrumentMBean, DataCachePanel> _map;
+
+    DataCacheWorker(Map<DataCacheJMXInstrumentMBean, DataCachePanel> map) {
+        _map = map;
+    }
+
+    @Override
+    public Map<DataCachePanel, DataCacheStatistic> doInBackground() {
+        Map<DataCachePanel, DataCacheStatistic> res = new HashMap<DataCachePanel, DataCacheStatistic>();
+        // Loop over each known panel and build DataCacheStatistic that will be consumed by the UI.
+        for (Entry<DataCacheJMXInstrumentMBean, DataCachePanel> entry : _map.entrySet()) {
+            DataCacheJMXInstrumentMBean mbean = entry.getKey();
+            DataCachePanel panel = entry.getValue();
+            // Make MBean calls
+            CacheStatistics stats = mbean.getCacheStatistics();
+            Map<String, Boolean> types = mbean.listKnownTypes();
+
+            DataCacheStatistic stat = new DataCacheStatistic(stats, types);
+
+            res.put(panel, stat);
+        }
+
+        return res;
+    }
+
+    /**
+     * This method is called by JConsole. It needs to pass data which was obtained in the background on to the UI for
+     * updating.
+     * 
+     * Note : The method get() returns the values that were returned by the doInBackGround() method.
+     */
+    @Override
+    protected void done() {
+        try {
+            Map<DataCachePanel, DataCacheStatistic> res = get();
+            for (Entry<DataCachePanel, DataCacheStatistic> entry : res.entrySet()) {
+                DataCachePanel panel = entry.getKey();
+                DataCacheStatistic stat = entry.getValue();
+
+                // Give the types panel a chance to update known types.
+                panel.updateTypesCached(stat);
+
+                // Update statistics
+                DataCacheTable model = panel.getModel();
+                model.setDataCacheStatistics(stat);
+                model.fireTableDataChanged();
+            }
+        } catch (Exception e) {
+            // Unexpected
+            e.printStackTrace();
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jconsole/DataCacheWorker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrument.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrument.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrument.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrument.java Thu Oct 21 16:01:51 2010
@@ -33,8 +33,8 @@ import org.apache.openjpa.util.UserExcep
 /**
  * A JMX-specific instrument for the data cache
  */
-public class DataCacheJMXInstrument extends AbstractDataCacheInstrument 
-    implements JMXInstrument, DataCacheJMXInstrumentMBean {
+public class DataCacheJMXInstrument extends AbstractDataCacheInstrument implements JMXInstrument,
+    DataCacheJMXInstrumentMBean {
     
     private static Localizer _loc = Localizer.forPackage(DataCacheJMXInstrument.class);
 
@@ -72,6 +72,7 @@ public class DataCacheJMXInstrument exte
         }
         
         setDataCache(dc);
+        setDataCacheManager(dcm);
         setConfigId(conf.getId());
         setContextRef(Integer.toString(System.identityHashCode(getContext())));
     }

Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrumentMBean.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrumentMBean.java?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrumentMBean.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/DataCacheJMXInstrumentMBean.java Thu Oct 21 16:01:51 2010
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.instrumentation.jmx;
+
+import org.apache.openjpa.instrumentation.DataCacheInstrument;
+
+/**
+ * Simple MBean interface for providing instrumented data cache metrics 
+ * and operations.
+ * Note: Simple MBeans require an MBean interface matching the supplied 
+ * implementation class.
+ */
+public interface DataCacheJMXInstrumentMBean extends DataCacheInstrument {
+
+}

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/JMXProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/JMXProvider.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/JMXProvider.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/jmx/JMXProvider.java Thu Oct 21 16:01:51 2010
@@ -19,6 +19,7 @@
 package org.apache.openjpa.instrumentation.jmx;
 
 import java.lang.management.ManagementFactory;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.Map.Entry;
@@ -49,16 +50,18 @@ public class JMXProvider
      */
     public static final String MBEAN_DOMAIN = "org.apache.openjpa";
     
-    private MBeanServer _mbs = null;
+    private Set<MBeanServer> _mbs = null;
 
     /**
      * Register an MBean with the mbean server.
      * @param mBean
      */
     protected void registerMBean(JMXInstrument mBean) {
-        MBeanServer mbs = getMBeanServer(); 
+        Set<MBeanServer> mbs = getMBeanServer(); 
         try {
-            mbs.registerMBean(mBean, mBean.getObjectName());
+            for (MBeanServer s : mbs) {
+                s.registerMBean(mBean, mBean.getObjectName());
+            }
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -68,24 +71,31 @@ public class JMXProvider
      * Returns the mbean server
      * @return
      */
-    public MBeanServer getMBeanServer() {
+    public Set<MBeanServer> getMBeanServer() {
         if (_mbs == null) {
-            _mbs = ManagementFactory.getPlatformMBeanServer();
+            _mbs =  new HashSet<MBeanServer>();
+            // Look in both of these static methods to find all MBServers. In some environments the server returned by
+            // the getPlatformMBeanServer() call isn't the one used by the runtime. Might be over kill by calling both,
+            // but it shouldn't hurt anything.
+            _mbs.addAll(MBeanServerFactory.findMBeanServer(null));
+            _mbs.add(ManagementFactory.getPlatformMBeanServer());
         }
         return _mbs;
     }
 
     @Override
     public void start() {
-       try {
-           MBeanServer mbs = getMBeanServer();
-           if (mbs == null) {
-               throw new UserException("jmx-server-failed-creation");
-           }
-           setStarted(true);
-       } catch (Throwable t) {
-           throw new UserException("jmx-server-unavailable",t);
-       }
+        Set<MBeanServer> mbs = getMBeanServer();
+        try {
+            for (MBeanServer s : mbs) {
+                if (mbs == null || mbs.size() == 0) {
+                    throw new UserException("jmx-server-failed-creation");
+                }
+            }
+            setStarted(true);
+        } catch (Throwable t) {
+            throw new UserException("jmx-server-unavailable", t);
+        }
     }
 
     /**
@@ -155,8 +165,11 @@ public class JMXProvider
      */
     public void stopInstrument(Instrument instrument, boolean force) {
         if (instrument.isStarted() || force) {
+            Set<MBeanServer> mbs = getMBeanServer();
             try {
-                getMBeanServer().unregisterMBean(((JMXInstrument)instrument).getObjectName());
+                for (MBeanServer s : mbs) {
+                    s.unregisterMBean(((JMXInstrument) instrument).getObjectName());
+                }
                 instrument.setStarted(false);
             } catch (Exception e) {
                 // If force, swallow the exception since the bean may not even

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java Thu Oct 21 16:01:51 2010
@@ -155,6 +155,7 @@ public class ClassMetaData
 
     private Class<?> _type = Object.class;
     private int _hashCode = Object.class.getName().hashCode();
+    private String _typeString = Object.class.getName();
     private final Map<String,FieldMetaData> _fieldMap = new TreeMap<String,FieldMetaData>();
     private Map<String,FieldMetaData> _supFieldMap = null;
     private boolean _defSupFields = false;
@@ -259,7 +260,14 @@ public class ClassMetaData
     public Class<?> getDescribedType() {
         return _type;
     }
-
+    
+    /**
+     * The persistence capable stringified class described by this metadata.
+     */
+    public String getDescribedTypeString(){
+        return _typeString;
+    }
+    
     /**
      * Set the class described by this metadata. The type may be reset when
      * an embedded value changes its declared type.
@@ -269,7 +277,8 @@ public class ClassMetaData
             (type.getSuperclass().getName()))
             throw new MetaDataException(_loc.get("enum", type));
         _type = type;
-        _hashCode = _type.getName().hashCode();
+        _typeString = _type.getName();
+        _hashCode = _typeString.hashCode();
         if (PersistenceCapable.class.isAssignableFrom(type))
             setIntercepting(true);
     }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java Thu Oct 21 16:01:51 2010
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
@@ -107,6 +108,7 @@ public class MetaDataRepository implemen
     // cache of parsed metadata, oid class to class, and interface class
     // to metadatas
     private Map<Class<?>, ClassMetaData> _metas = new HashMap<Class<?>, ClassMetaData>();
+    private Map<String, ClassMetaData> _metaStringMap = new ConcurrentHashMap<String, ClassMetaData>();
     private Map<Class<?>, Class<?>> _oids = Collections.synchronizedMap(new HashMap<Class<?>, Class<?>>());
     private Map<Class<?>, Collection<Class<?>>> _impls =
         Collections.synchronizedMap(new HashMap<Class<?>, Collection<Class<?>>>());
@@ -1433,6 +1435,7 @@ public class MetaDataRepository implemen
             _aliases.clear();
             _pawares.clear();
             _nonMapped.clear();
+            _metaStringMap.clear();
     }
     /**
      * Return the set of configured persistent classes, or null if the user did not configure any.
@@ -2456,4 +2459,22 @@ public class MetaDataRepository implemen
             log.info(_loc.get("down-level-entity"));
         }
     }
+    
+    /**
+     * This method returns the ClassMetaData whose described type name matches the typeName parameter. It ONLY operates
+     * against MetaData that is currently known by this repository. Note: This method call WILL NOT resolve any
+     * metadata.
+     */
+    public ClassMetaData getCachedMetaData(String typeName) {
+        ClassMetaData cmd = _metaStringMap.get(typeName);
+        if (cmd == null) {
+            for (ClassMetaData c : getMetaDatas()) {
+                if (c.getDescribedType().getName().equals(typeName)) {
+                    _metaStringMap.put(typeName, c);
+                    return c;
+                }
+            }
+        }
+        return cmd;
+    }
 }

Added: openjpa/trunk/openjpa-kernel/src/main/resources/META-INF/services/com.sun.tools.jconsole.JConsolePlugin
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/META-INF/services/com.sun.tools.jconsole.JConsolePlugin?rev=1026046&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/resources/META-INF/services/com.sun.tools.jconsole.JConsolePlugin (added)
+++ openjpa/trunk/openjpa-kernel/src/main/resources/META-INF/services/com.sun.tools.jconsole.JConsolePlugin Thu Oct 21 16:01:51 2010
@@ -0,0 +1 @@
+org.apache.openjpa.instrumentation.jconsole.DataCachePlugin

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/instrumentation/TestInstrumentationProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/instrumentation/TestInstrumentationProvider.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/instrumentation/TestInstrumentationProvider.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/instrumentation/TestInstrumentationProvider.java Thu Oct 21 16:01:51 2010
@@ -203,13 +203,11 @@ public class TestInstrumentationProvider
         assertTrue(dci.getHitCount() > 0);
         assertTrue(dci.getReadCount() > 0);
         assertTrue(dci.getWriteCount() > 0);
-        try {
-            assertTrue(dci.getHitCount(CacheableEntity.class.getName()) > 0);
-            assertTrue(dci.getReadCount(CacheableEntity.class.getName()) > 0);
-            assertTrue(dci.getWriteCount(CacheableEntity.class.getName()) > 0);
-        } catch (ClassNotFoundException e) {
-            fail("Class name based assertion failed");
-        }
+
+        assertTrue(dci.getHitCount(CacheableEntity.class.getName()) > 0);
+        assertTrue(dci.getReadCount(CacheableEntity.class.getName()) > 0);
+        assertTrue(dci.getWriteCount(CacheableEntity.class.getName()) > 0);
+
         
         closeEMF(oemf);
     }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java?rev=1026046&r1=1026045&r2=1026046&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java Thu Oct 21 16:01:51 2010
@@ -35,7 +35,7 @@ import org.apache.openjpa.persistence.te
 public class TestStatistics extends SingleEMFTestCase {
     private static final boolean L2Cached = true;
     private static final boolean L1Cached = true;
-    private static final Class<?> cls = CachedEntityStatistics.class;
+    private static final String cls = CachedEntityStatistics.class.getName();
 
     Object[] p =
         new Object[] { CLEAR_TABLES, CachedEntityStatistics.class
@@ -267,16 +267,9 @@ public class TestStatistics extends Sing
     }
 
     /**
-     * Get {hit,read,write} count for the cache across given class extent.
-     */
-    long[] snapshot(Class<?> cls) {
-        return new long[] { stats.getReadCount(cls), stats.getHitCount(cls), stats.getWriteCount(cls) };
-    }
-
-    /**
      * Assert that the passed in hit/eviction/read/write match those values collected by stats.
      */
-    private static final void assertion(Class<?> cls, int hit, int read, int write, CacheStatistics stats) {
+    private static final void assertion(String cls, int hit, int read, int write, CacheStatistics stats) {
         if (cls == null) {
             throw new RuntimeException("invalid assertion. Null class");
         } else {