changeset 779:39fcc5389e32

Eclipse VmClassStat Plugin This commit adds a new Eclipse plugin for the VmClassStat view, similar to that of the Swing GUI. This commit also adds tests for this new plugin to the c.r.t.eclipse.test and test.ui plugins. Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-November/004037.html
author Elliott Baron <ebaron@redhat.com>
date Thu, 15 Nov 2012 12:27:27 -0500
parents 10c1f499481c
children b8cb23fefea9
files eclipse/com.redhat.thermostat.client.feature/feature.xml eclipse/com.redhat.thermostat.client.feature/pom.xml eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/.classpath eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/.project eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/META-INF/MANIFEST.MF eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/build.properties eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/plugin.xml eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/pom.xml eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/Activator.java eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatView.java eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatViewProvider.java eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/VmClassStatViewPart.java eclipse/com.redhat.thermostat.eclipse.feature/feature.xml eclipse/com.redhat.thermostat.eclipse.feature/pom.xml eclipse/com.redhat.thermostat.eclipse.p2-repo/pom.xml eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF eclipse/com.redhat.thermostat.eclipse.test.ui/pom.xml eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTVmClassStatViewTest.java eclipse/com.redhat.thermostat.eclipse.test/META-INF/MANIFEST.MF eclipse/com.redhat.thermostat.eclipse.test/pom.xml eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/VmClassStatViewPartTest.java eclipse/pom.xml
diffstat 22 files changed, 804 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/eclipse/com.redhat.thermostat.client.feature/feature.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.client.feature/feature.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -112,4 +112,11 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="com.redhat.thermostat.client.classstat.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
--- a/eclipse/com.redhat.thermostat.client.feature/pom.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.client.feature/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -21,6 +21,11 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-vmclassstat-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-web-client</artifactId>
       <version>0.5.0-SNAPSHOT</version>
     </dependency>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/.classpath	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/.project	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.redhat.thermostat.eclipse.chart.vmclassstat</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/META-INF/MANIFEST.MF	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,33 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Thermostat VM Classes View
+Bundle-SymbolicName: com.redhat.thermostat.eclipse.chart.vmclassstat;singleton:=true
+Bundle-Version: 0.5.0.qualifier
+Bundle-Activator: com.redhat.thermostat.eclipse.chart.vmclassstat.Activator
+Bundle-Vendor: Red Hat Inc.
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Import-Package: com.redhat.thermostat.client.core.views,
+ com.redhat.thermostat.client.locale,
+ com.redhat.thermostat.client.osgi.service,
+ com.redhat.thermostat.client.ui,
+ com.redhat.thermostat.client.vmclassstat.core,
+ com.redhat.thermostat.common,
+ com.redhat.thermostat.common.appctx,
+ com.redhat.thermostat.common.dao,
+ com.redhat.thermostat.common.locale,
+ com.redhat.thermostat.common.utils,
+ com.redhat.thermostat.eclipse,
+ com.redhat.thermostat.eclipse.chart.common,
+ com.redhat.thermostat.eclipse.internal.views,
+ com.redhat.thermostat.storage.model,
+ org.jfree.chart,
+ org.jfree.chart.axis,
+ org.jfree.chart.plot,
+ org.jfree.data,
+ org.jfree.data.general,
+ org.jfree.data.time,
+ org.jfree.data.xy
+Export-Package: com.redhat.thermostat.eclipse.chart.vmclassstat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/build.properties	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/plugin.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            class="com.redhat.thermostat.eclipse.chart.vmclassstat.VmClassStatViewPart"
+            id="com.redhat.thermostat.eclipse.chart.vmClassStatView"
+            name="VM Classes"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension
+            targetID="com.redhat.thermostat.eclipse.perspective">
+         <view
+               id="com.redhat.thermostat.eclipse.chart.vmClassStatView"
+               minimized="false"
+               relationship="stack"
+               relative="com.redhat.thermostat.eclipse.chart.vmGcView">
+         </view>
+         <viewShortcut
+               id="com.redhat.thermostat.eclipse.chart.vmClassStatView">
+         </viewShortcut>
+      </perspectiveExtension>
+   </extension>
+
+</plugin>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>thermostat-eclipse-parent</artifactId>
+    <groupId>com.redhat.thermostat.eclipse.parent</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <groupId>com.redhat.thermostat.eclipse.parent</groupId>
+  <artifactId>com.redhat.thermostat.eclipse.chart.vmclassstat</artifactId>
+  <packaging>eclipse-plugin</packaging>
+  <version>0.5.0-SNAPSHOT</version>
+
+  <name>Thermostat Eclipse VmClassStat Plug-in</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-vmclassstat-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat.eclipse.parent</groupId>
+      <artifactId>com.redhat.thermostat.eclipse.chart.common</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat.eclipse.parent</groupId>
+      <artifactId>com.redhat.thermostat.eclipse.jfreechart-repo</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+      <type>pom</type>
+    </dependency>
+  </dependencies>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/Activator.java	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.eclipse.chart.vmclassstat;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatViewProvider;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+    // The plug-in ID
+    public static final String PLUGIN_ID = "com.redhat.thermostat.eclipse.chart.vmclassstat"; //$NON-NLS-1$
+
+    public static final String VIEW_ID_VM_CLASS_STAT = "com.redhat.thermostat.eclipse.chart.vmClassStatView";
+
+    // The shared instance
+    private static Activator plugin;
+
+    /**
+     * The constructor
+     */
+    public Activator() {
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+     * )
+     */
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        plugin = this;
+
+        // Register view
+        OSGIUtils.getInstance().registerService(VmClassStatViewProvider.class,
+                new SWTVmClassStatViewProvider(), null);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+     * )
+     */
+    public void stop(BundleContext context) throws Exception {
+        plugin = null;
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     * 
+     * @return the shared instance
+     */
+    public static Activator getDefault() {
+        return plugin;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatView.java	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.eclipse.chart.vmclassstat;
+
+import java.awt.EventQueue;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.NumberTickUnit;
+import org.jfree.chart.axis.TickUnits;
+import org.jfree.data.RangeType;
+import org.jfree.data.time.FixedMillisecond;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+
+import com.redhat.thermostat.client.vmclassstat.core.LocaleResources;
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatView;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.eclipse.SWTComponent;
+import com.redhat.thermostat.eclipse.chart.common.RecentTimeSeriesChartComposite;
+import com.redhat.thermostat.eclipse.chart.common.ViewVisibilityWatcher;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+
+public class SWTVmClassStatView extends VmClassStatView implements SWTComponent {
+    
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final TimeSeriesCollection dataset;
+    
+    private ViewVisibilityWatcher watcher;
+
+    private JFreeChart chart;
+
+    public SWTVmClassStatView() {
+        dataset = new TimeSeriesCollection();
+        watcher = new ViewVisibilityWatcher(notifier);
+    }
+    
+    @Override
+    public void createControl(Composite parent) {
+        // any name works
+        dataset.addSeries(new TimeSeries("class-stat"));
+
+        chart = ChartFactory.createTimeSeriesChart(
+                null,
+                translator.localize(LocaleResources.VM_CLASSES_CHART_REAL_TIME_LABEL),
+                translator.localize(LocaleResources.VM_CLASSES_CHART_LOADED_CLASSES_LABEL),
+                dataset,
+                false, false, false);
+
+        TickUnits tickUnits = new TickUnits();
+        tickUnits.add(new NumberTickUnit(1));
+        tickUnits.add(new NumberTickUnit(10));
+        tickUnits.add(new NumberTickUnit(100));
+        tickUnits.add(new NumberTickUnit(1000));
+        tickUnits.add(new NumberTickUnit(10000));
+        tickUnits.add(new NumberTickUnit(100000));
+        tickUnits.add(new NumberTickUnit(1000000));
+
+        NumberAxis axis = (NumberAxis) chart.getXYPlot().getRangeAxis();
+        axis.setStandardTickUnits(tickUnits);
+        axis.setRangeType(RangeType.POSITIVE);
+        axis.setAutoRangeMinimumSize(10);
+
+        Composite chartPanel = new RecentTimeSeriesChartComposite(parent, SWT.NONE, chart);
+        chartPanel.setLayout(new GridLayout());
+        chartPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+        watcher.watch(parent, Activator.VIEW_ID_VM_CLASS_STAT);
+    }
+
+    @Override
+    public void addClassCount(List<DiscreteTimeData<Long>> data) {
+        final List<DiscreteTimeData<Long>> copy = new ArrayList<>(data);
+        EventQueue.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = dataset.getSeries(0);
+                for (DiscreteTimeData<Long> data: copy) {
+                    RegularTimePeriod period = new FixedMillisecond(data.getTimeInMillis());
+                    if (series.getDataItem(period) == null) {
+                        series.add(period, data.getData(), false);
+                    }
+                }
+                series.fireSeriesChanged();
+            }
+        });
+    }
+
+    @Override
+    public void clearClassCount() {
+        EventQueue.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = dataset.getSeries(0);
+                series.clear();
+            }
+        });
+    }
+    
+    public JFreeChart getChart() {
+        return chart;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/SWTVmClassStatViewProvider.java	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.eclipse.chart.vmclassstat;
+
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatView;
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatViewProvider;
+
+public class SWTVmClassStatViewProvider implements VmClassStatViewProvider {
+
+    @Override
+    public VmClassStatView createView() {
+        return new SWTVmClassStatView();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.vmclassstat/src/com/redhat/thermostat/eclipse/chart/vmclassstat/VmClassStatViewPart.java	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.eclipse.chart.vmclassstat;
+
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatController;
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatViewProvider;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+import com.redhat.thermostat.eclipse.SWTComponent;
+import com.redhat.thermostat.eclipse.chart.common.VmRefViewPart;
+
+public class VmClassStatViewPart extends VmRefViewPart {
+
+    @Override
+    protected void createControllerView(VmRef ref) {
+        VmClassStatViewProvider viewProvider = OSGIUtils.getInstance()
+                .getService(VmClassStatViewProvider.class);
+        VmClassStatDAO classStatDAO = OSGIUtils.getInstance().getService(
+                VmClassStatDAO.class);
+        VmClassStatController controller = createController(classStatDAO, ref,
+                viewProvider);
+        SWTComponent view = (SWTComponent) controller.getView();
+        view.createControl(top);
+    }
+
+    public VmClassStatController createController(VmClassStatDAO classStatDao,
+            VmRef ref, VmClassStatViewProvider viewProvider) {
+        return new VmClassStatController(classStatDao, ref, viewProvider);
+    }
+    
+}
--- a/eclipse/com.redhat.thermostat.eclipse.feature/feature.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.feature/feature.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -13,7 +13,7 @@
    </copyright>
 
    <license url="http://www.gnu.org/licenses/">
-Copyright 2012 Red Hat, Inc.
+      Copyright 2012 Red Hat, Inc.
 
 This file is part of Thermostat.
 
@@ -74,4 +74,11 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="com.redhat.thermostat.eclipse.chart.vmclassstat"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
--- a/eclipse/com.redhat.thermostat.eclipse.feature/pom.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.feature/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -19,6 +19,11 @@
       <artifactId>com.redhat.thermostat.eclipse</artifactId>
       <version>0.5.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-vmclassstat-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
     <!-- using Web storage -->
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
--- a/eclipse/com.redhat.thermostat.eclipse.p2-repo/pom.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.p2-repo/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -19,6 +19,11 @@
       <artifactId>com.redhat.thermostat.eclipse</artifactId>
       <version>0.5.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-vmclassstat-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
     <!-- using Web storage -->
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF	Thu Nov 15 12:27:27 2012 -0500
@@ -12,11 +12,13 @@
 Import-Package: com.redhat.thermostat.client.core.views,
  com.redhat.thermostat.client.osgi.service,
  com.redhat.thermostat.client.ui,
+ com.redhat.thermostat.client.vmclassstat.core,
  com.redhat.thermostat.common,
  com.redhat.thermostat.common.appctx,
  com.redhat.thermostat.storage.model,
  com.redhat.thermostat.eclipse,
  com.redhat.thermostat.eclipse.chart.common,
+ com.redhat.thermostat.eclipse.chart.vmclassstat,
  org.apache.log4j;version="1.2.13",
  org.eclipse.swtbot.eclipse.finder,
  org.eclipse.swtbot.eclipse.finder.matchers,
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/pom.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -29,6 +29,11 @@
       <version>0.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-vmclassstat-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
       <groupId>com.redhat.thermostat.eclipse.parent</groupId>
       <artifactId>com.redhat.thermostat.eclipse.test-deps-repo</artifactId>
       <version>0.5.0-SNAPSHOT</version>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTVmClassStatViewTest.java	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.eclipse.test.ui;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.jfree.chart.JFreeChart;
+import org.jfree.data.xy.XYDataset;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.eclipse.chart.vmclassstat.SWTVmClassStatView;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+
+public class SWTVmClassStatViewTest {
+    private SWTWorkbenchBot bot;
+    private SWTVmClassStatView view;
+    private Shell shell;
+
+    @Before
+    public void beforeTest() throws Exception {
+        bot = new SWTWorkbenchBot();
+        
+        Display.getDefault().syncExec(new Runnable() {
+
+            @Override
+            public void run() {
+                shell = new Shell(Display.getCurrent());
+                Composite parent = new Composite(shell, SWT.NONE);
+                parent.setLayout(new GridLayout());
+                parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+                        true));
+                view = new SWTVmClassStatView();
+                view.createControl(parent);
+                shell.open();
+            }
+        });
+    }
+
+    @After
+    public void afterTest() throws Exception {
+        Display.getDefault().syncExec(new Runnable() {
+
+            @Override
+            public void run() {
+                if (shell != null) {
+                    shell.close();
+                    view = null;
+                }
+            }
+        });
+    }
+
+    @Test
+    public void testClearClassCount() {
+        List<DiscreteTimeData<Long>> data = new ArrayList<DiscreteTimeData<Long>>();
+        data.add(new DiscreteTimeData<Long>(1000L, 0L));
+        data.add(new DiscreteTimeData<Long>(2000L, 7L));
+        data.add(new DiscreteTimeData<Long>(3000L, 50L));
+        
+        addData(data);
+        
+        view.clearClassCount();
+        
+        // Wait until data removed
+        bot.waitUntil(new DefaultCondition() {
+            
+            @Override
+            public boolean test() throws Exception {
+                JFreeChart chart = view.getChart();
+                return chart.getXYPlot().getDataset().getItemCount(0) == 0;
+            }
+            
+            @Override
+            public String getFailureMessage() {
+                return "Data not cleared";
+            }
+        });
+    }
+
+    @Test
+    public void testAddClassCount() {
+        List<DiscreteTimeData<Long>> data = new ArrayList<DiscreteTimeData<Long>>();
+        data.add(new DiscreteTimeData<Long>(1000L, 0L));
+        data.add(new DiscreteTimeData<Long>(2000L, 7L));
+        data.add(new DiscreteTimeData<Long>(3000L, 50L));
+        
+        addData(data);
+        
+        // Verify data
+        XYDataset dataset = view.getChart().getXYPlot().getDataset();
+        assertEquals(1000L, dataset.getX(0, 0));
+        assertEquals(2000L, dataset.getX(0, 1));
+        assertEquals(3000L, dataset.getX(0, 2));
+        
+        assertEquals(0L, dataset.getY(0, 0));
+        assertEquals(7L, dataset.getY(0, 1));
+        assertEquals(50L, dataset.getY(0, 2));
+    }
+
+    public void addData(final List<DiscreteTimeData<Long>> data) {
+        view.addClassCount(data);
+        
+        bot.waitUntil(new DefaultCondition() {
+            
+            @Override
+            public boolean test() throws Exception {
+                JFreeChart chart = view.getChart();
+                return chart.getXYPlot().getDataset().getItemCount(0) == data.size();
+            }
+            
+            @Override
+            public String getFailureMessage() {
+                return "Data not added";
+            }
+        });
+    }
+
+}
--- a/eclipse/com.redhat.thermostat.eclipse.test/META-INF/MANIFEST.MF	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.test/META-INF/MANIFEST.MF	Thu Nov 15 12:27:27 2012 -0500
@@ -15,11 +15,13 @@
 Import-Package: com.redhat.thermostat.client.core.views,
  com.redhat.thermostat.client.osgi.service,
  com.redhat.thermostat.client.ui,
+ com.redhat.thermostat.client.vmclassstat.core,
  com.redhat.thermostat.common,
  com.redhat.thermostat.common.dao,
  com.redhat.thermostat.common.utils,
  com.redhat.thermostat.eclipse,
  com.redhat.thermostat.eclipse.chart.common,
+ com.redhat.thermostat.eclipse.chart.vmclassstat,
  com.redhat.thermostat.eclipse.internal.model,
  com.redhat.thermostat.eclipse.internal.views,
  org.mockito,
--- a/eclipse/com.redhat.thermostat.eclipse.test/pom.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/com.redhat.thermostat.eclipse.test/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -20,6 +20,11 @@
       <artifactId>com.redhat.thermostat.eclipse</artifactId>
       <version>0.5.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-vmclassstat-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
     <!-- using Web storage -->
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/VmClassStatViewPartTest.java	Thu Nov 15 12:27:27 2012 -0500
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.eclipse.test.views;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.Test;
+
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatController;
+import com.redhat.thermostat.client.vmclassstat.core.VmClassStatViewProvider;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmClassStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.eclipse.chart.common.RefViewPart;
+import com.redhat.thermostat.eclipse.chart.vmclassstat.SWTVmClassStatView;
+import com.redhat.thermostat.eclipse.chart.vmclassstat.VmClassStatViewPart;
+
+public class VmClassStatViewPartTest extends AbstractRefViewPartTest<VmRef> {
+
+    @Test
+    public void testSelectionAfter() throws Exception {
+        view.createPartControl(parent);
+
+        HostRef hostRef = new HostRef("TEST", "Test");
+        VmRef vmRef = new VmRef(hostRef, 0, "Test");
+        IStructuredSelection selection = mockSelection(vmRef);
+        view.selectionChanged(hostVMView, selection);
+        
+        verify(thermoView).createControl(any(Composite.class));
+    }
+    
+    @Override
+    protected void mockController() {
+        VmClassStatController controller = mock(VmClassStatController.class);
+        thermoView = mock(SWTVmClassStatView.class);
+
+        VmClassStatDAO classStatDao = mock(VmClassStatDAO.class);
+        VmClassStatViewProvider viewProvider = mock(VmClassStatViewProvider.class);
+        when(osgi.getService(VmClassStatDAO.class)).thenReturn(classStatDao);
+        when(osgi.getService(VmClassStatViewProvider.class)).thenReturn(viewProvider);
+
+        doReturn(controller).when(((VmClassStatViewPart) view)).createController(
+                same(classStatDao), any(VmRef.class), same(viewProvider));
+        when(controller.getView()).thenReturn(thermoView);
+    }
+
+    @Override
+    protected RefViewPart<VmRef> createViewPart() {
+        return new VmClassStatViewPart();
+    }
+
+}
--- a/eclipse/pom.xml	Thu Nov 15 11:20:34 2012 -0500
+++ b/eclipse/pom.xml	Thu Nov 15 12:27:27 2012 -0500
@@ -92,6 +92,7 @@
     <module>com.redhat.thermostat.eclipse.boot</module>
     <module>com.redhat.thermostat.eclipse</module>
     <module>com.redhat.thermostat.eclipse.chart.common</module>
+    <module>com.redhat.thermostat.eclipse.chart.vmclassstat</module>
     <module>com.redhat.thermostat.eclipse.test</module>
     <module>com.redhat.thermostat.eclipse.test.ui</module>
     <module>com.redhat.thermostat.eclipse.feature</module>