Mercurial > hg > release > thermostat-0.6
changeset 719:bc32ec1a9cbc
Move Swing-dependent code into separate bundles: memory-stats-panel
This commit splits the memory-stats-panel bundle into core and swing bundles.
Reviewed-by: omajid
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-October/003814.html
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/pom.xml Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-osgi-memory-stats-panel</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>0.5.0-SNAPSHOT</version> + </parent> + <artifactId>thermostat-osgi-memory-stats-panel-core</artifactId> + <packaging>bundle</packaging> + <name>Thermostat Client VM Memory Monitor Core plugin</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package> + com.redhat.thermostat.client.stats.memory.core, + com.redhat.thermostat.client.stats.memory.core.locale, + </Export-Package> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.client.stats.memory.core</Bundle-SymbolicName> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jfree</groupId> + <artifactId>jfreechart</artifactId> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryMeter.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,433 @@ +/* + * 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.client.stats.memory.core; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.beans.Transient; + +import javax.swing.JComponent; +import javax.swing.plaf.ColorUIResource; + +import sun.swing.SwingUtilities2; + +@SuppressWarnings({ "restriction", "serial" }) +public class MemoryMeter extends JComponent { + + // TODO the font should be customizable + private static final Font font = new Font("SansSerif", Font.PLAIN, 10); + + private static final int TICK_NUM = 100; + private static final int SMALL_TICK_NUM = 5; + + private static final int MAIN_BAR_HEIGHT = 20; + + private static final ColorUIResource MAIN_GRADIENT_TOP = new ColorUIResource(0xf1f3f1); + private static final ColorUIResource MAIN_BORDER_COLOR = new ColorUIResource(0xa8aca8); + + private static final ColorUIResource MAIN_BAR_BASE_COLOR_TOP = new ColorUIResource(0xbcd5ef); + private static final ColorUIResource MAIN_BAR_BASE_COLOR = new ColorUIResource(0x4A90D9); + + //private static final ColorUIResource STATS_BG = new ColorUIResource(0xF8F8F8); + private static final ColorUIResource STATS_BG = new ColorUIResource(0xFFFFFF); + + private ColorUIResource tickColor; + + private RangeModel primary; + private RangeModel secondary; + + private Insets boundInsets; + + private RangeModel internalSecondaryModel; + + private StatsModel primaryStats; + + private String primaryUnit; + private String secondaryUnit; + + public void setPrimaryScaleUnit(String primaryUnit) { + this.primaryUnit = primaryUnit; + } + + public void setSecondayScaleUnit(String secondaryUnit) { + this.secondaryUnit = secondaryUnit; + } + + public StatsModel getStats() { + return primaryStats; + } + + public void setStats(StatsModel primaryStats) { + this.primaryStats = primaryStats; + } + + public MemoryMeter() { + + secondaryUnit = ""; + primaryUnit = ""; + + boundInsets = new Insets(10, 10, 20, 20); + + tickColor = new ColorUIResource(0xdbdddb); + + primary = new RangeModel(); + primary.setMinimum(0); + primary.setMaximum(100); + primary.setMinNormalized(0); + primary.setMaxNormalized(100); + + secondary = new RangeModel(); + secondary.setMinimum(0); + secondary.setMaximum(100); + secondary.setMinNormalized(0); + secondary.setMaxNormalized(100); + + internalSecondaryModel = new RangeModel(); + } + + public ColorUIResource getTickColor() { + return tickColor; + } + + public void setTickColor(ColorUIResource tickColor) { + this.tickColor = tickColor; + } + + public RangeModel getPrimaryModel() { + return primary; + } + + public RangeModel getSecondaryModel() { + return secondary; + } + + protected Rectangle getOuterBounds() { + return new Rectangle(0, 0, getWidth(), getHeight()); + } + + protected Rectangle getBoundsWithInsets(Rectangle bounds) { + return new Rectangle(bounds.x + boundInsets.left, + bounds.y + boundInsets.top, + bounds.width - boundInsets.right, + bounds.height - boundInsets.bottom); + } + + /** + * paint the outher frame, including the light border sorrounding + */ + protected void paintOuterFrame(Graphics2D graphics, Rectangle bounds) { + + RoundRectangle2D frame = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height, 6, 6); + + Paint paint = new GradientPaint(0, 0, MAIN_GRADIENT_TOP, 0, getHeight(), getBackground()); + graphics.setPaint(paint); + graphics.fill(frame); + + paint = new GradientPaint(0, 0, MAIN_BORDER_COLOR, 0, getHeight(), getBackground()); + graphics.setPaint(paint); + frame = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width -1, bounds.height, 6, 6); + graphics.draw(frame); + } + + /** + * paint the track sorrounding the main bar + */ + protected void paintMainBarTrackFill(Graphics2D graphics, Rectangle bounds) { + + Paint paint = new GradientPaint(0, 0, MAIN_GRADIENT_TOP, 0, bounds.height, Color.WHITE); + graphics.setPaint(paint); + RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width, bounds.height, 6, 6); + graphics.fill(frame); + } + + /** + */ + protected void paintMainBarTrackBorder(Graphics2D graphics, Rectangle bounds) { + Paint paint = new GradientPaint(0, 0, MAIN_BORDER_COLOR, getWidth(), 0, getBackground()); + graphics.setPaint(paint); + + RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width - 1, bounds.height, 6, 6); + graphics.draw(frame); + } + + + /** + * this is the main bar, will it up to what is defined by the model + */ + protected void paintMainBarFill(Graphics2D graphics, Rectangle bounds) { + Paint paint = new GradientPaint(0, 0, MAIN_BAR_BASE_COLOR, getWidth() * 2, 0, getBackground()); + graphics.setPaint(paint); + + RoundRectangle2D frame = + new RoundRectangle2D.Float(0, 0, getPrimaryModel().getValueNormalized(), + bounds.height, 6, 6); + graphics.fill(frame); + + String value = String.valueOf(getPrimaryModel().getValue()) + " " + primaryUnit; + Rectangle2D fontBounds = font.getStringBounds(value, graphics.getFontRenderContext()); + int width = (int) (bounds.width/2 - fontBounds.getWidth()/2) - 1; + + if (width > getPrimaryModel().getValueNormalized()) { + graphics.setPaint(MAIN_BAR_BASE_COLOR); + } else { + graphics.setPaint(getBackground()); + } + + int height = (int) (bounds.height / 2 + fontBounds.getHeight()/2); + SwingUtilities2.drawString(this, graphics, value, width, height); + } + + /** + */ + private void paintMainBar(Graphics2D g, Rectangle bounds) { + + Graphics2D graphics = (Graphics2D) g.create(); + + graphics.translate(bounds.x, bounds.y); + paintMainBarTrackFill(graphics, bounds); + + paintMainBarFill(graphics, bounds); + + paintMainBarTrackBorder(graphics, bounds); + graphics.dispose(); + } + + /** + */ + protected void drawBottomBar(Graphics2D g, Rectangle bounds) { + + Graphics2D graphics = (Graphics2D) g.create(); + graphics.translate(bounds.x, bounds.y + bounds.height); + + drawTickMark(graphics, bounds); + + paintSecondaryBarFill(graphics, bounds); + + graphics.dispose(); + } + + /** + */ + protected void drawTickMark(Graphics2D graphics, Rectangle bounds) { + + graphics.setPaint(MAIN_BORDER_COLOR); + + int smallTop = bounds.height - 5; + int smallBottom = bounds.height; + + int mainTop = smallTop + 20; + int mainBottom = smallBottom - 15; + + // the first and last tick are always big, this is the first + graphics.drawLine(0, mainTop, 0, mainBottom); + + // the space between the vertical lines + double tickSpace = ((double) bounds.width) / TICK_NUM; + + internalSecondaryModel.setMaxNormalized(bounds.width); + int numTicks = 0; + + for (int x = 0; x < bounds.width; x += tickSpace + 0.5) { + if (numTicks % SMALL_TICK_NUM == 0) { + + graphics.drawLine(x, smallTop, x, smallBottom + 5); + + internalSecondaryModel.setValue(x); + } else { + graphics.drawLine(x, smallTop, x, smallBottom); + } + numTicks++; + } + + // that's the last + graphics.drawLine(bounds.width, mainTop, bounds.width, mainBottom); + graphics.drawLine(0, smallTop, bounds.width, smallTop); + + drawStrings(graphics, mainBottom, mainTop, bounds.width); + } + + protected void drawStrings(Graphics2D graphics, int top, int bottom, int right) { + + // now draw the min/max values of both side of markers + // top bar min value + FontMetrics fm = SwingUtilities2.getFontMetrics(this, font); + + String value = String.valueOf(getPrimaryModel().getMinimum()) + " " + primaryUnit; + int height = top + fm.getAscent()/2; + SwingUtilities2.drawString(this, graphics, value, 1, height); + + value = String.valueOf(getSecondaryModel().getMinimum()) + " " + secondaryUnit; + height = bottom; + SwingUtilities2.drawString(this, graphics, value, 1, height); + + value = String.valueOf(getPrimaryModel().getMaximum()) + " " + primaryUnit; + height = top + fm.getAscent()/2; + + int width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; + SwingUtilities2.drawString(this, graphics, value, width, height); + + value = String.valueOf(getSecondaryModel().getMaximum()) + " " + secondaryUnit; + height = bottom; + width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; + SwingUtilities2.drawString(this, graphics, value, width, height); + + // now draw the actual value for the bottom bar, the top bar is drawn in + // its fill method + value = String.valueOf(getSecondaryModel().getValue()) + " " + secondaryUnit; + width = right/2; + Rectangle2D bounds = font.getStringBounds(value, graphics.getFontRenderContext()); + width = (int) (width - bounds.getWidth()/2) - 1; + SwingUtilities2.drawString(this, graphics, value, width, height); + RoundRectangle2D frame = new RoundRectangle2D.Double(width - 2, height - bounds.getHeight(), + bounds.getWidth() + 4, bounds.getHeight() + 4, + 4, 4); + graphics.draw(frame); + } + + protected void paintSecondaryBarFill(Graphics2D graphics, Rectangle bounds) { + + graphics.setPaint(MAIN_BAR_BASE_COLOR_TOP); + graphics.drawLine(1, bounds.height, getSecondaryModel().getValueNormalized() - 1, bounds.height); + + graphics.setPaint(MAIN_BAR_BASE_COLOR); + graphics.fillRect(1, bounds.height + 1, getSecondaryModel().getValueNormalized(), 2); + } + + protected void paintStats(Graphics2D graphics, Rectangle bounds) { + + int imageWidth = bounds.width - 2; + if (imageWidth < 0 || bounds.height < 0) { + return; + } + + StatsModel stats = getStats(); + drawStats(graphics, stats, bounds.x, bounds.y, imageWidth, bounds.height); + } + + private void drawStats(Graphics2D graphics, StatsModel stats, int x, int y, int imageWidth, int height) { + if (stats != null) { + BufferedImage image = stats.getChart(imageWidth, height, STATS_BG, + new ColorUIResource(getForeground())); + + paintStatsLabel(graphics, image, stats.getName()); + graphics.drawImage(image, x, y, null); + } + } + + protected void paintStatsLabel(Graphics2D graphics, BufferedImage image, String label) { + int height = SwingUtilities2.getFontMetrics(this, font).getAscent() + 2; + if (height <= 0) { + return; + } + + Graphics2D imageGraphics = (Graphics2D) image.getGraphics(); + imageGraphics.setColor(getForeground()); + imageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + SwingUtilities2.drawString(this, imageGraphics, label, 2, height); + } + + @Override + protected void paintComponent(Graphics g) { + + Graphics2D graphics = (Graphics2D) g.create(); + graphics.setFont(font); + + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + + Rectangle outerBounds = getOuterBounds(); + Rectangle innerBounds = getBoundsWithInsets(outerBounds); + Rectangle statsBound = getBoundsWithInsets(outerBounds); + + // move the bar close to the center + innerBounds.height = MAIN_BAR_HEIGHT; + innerBounds.y = outerBounds.height/2; + + // make the stats area cover the upper portion instead + statsBound.height = (outerBounds.height/2) - MAIN_BAR_HEIGHT; + + resetModels(0, innerBounds.width); + + // some eye candy + paintOuterFrame(graphics, outerBounds); + + // paint the usage stats + paintStats(graphics, statsBound); + + // main and bottom bars + paintMainBar(graphics, innerBounds); + drawBottomBar(graphics, innerBounds); + + graphics.dispose(); + } + + private void resetModels(int min, int max) { + + getPrimaryModel().setMaxNormalized(max); + getPrimaryModel().setMinNormalized(min); + + RangeModel model = getSecondaryModel(); + model.setMaxNormalized(max); + model.setMinNormalized(min); + + internalSecondaryModel.setMaximum(model.getMaximum()); + internalSecondaryModel.setMinimum(model.getMinimum()); + internalSecondaryModel.setValue(model.getValue()); + + internalSecondaryModel.setMaxNormalized(max); + internalSecondaryModel.setMinNormalized(0); + } + + @Override + @Transient + public Dimension getPreferredSize() { + return new Dimension(850, 150); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsController.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,228 @@ +/* + * 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.client.stats.memory.core; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import com.redhat.thermostat.client.core.controllers.VmInformationServiceController; +import com.redhat.thermostat.client.core.views.BasicView.Action; +import com.redhat.thermostat.client.core.views.UIComponent; +import com.redhat.thermostat.client.stats.memory.core.locale.LocaleResources; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.NotImplementedException; +import com.redhat.thermostat.common.Timer; +import com.redhat.thermostat.common.Timer.SchedulingType; +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.dao.VmMemoryStatDAO; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.locale.Translate; +import com.redhat.thermostat.common.model.VmMemoryStat; +import com.redhat.thermostat.common.model.VmMemoryStat.Generation; +import com.redhat.thermostat.common.model.VmMemoryStat.Space; +import com.redhat.thermostat.common.utils.DisplayableValues.Scale; + +class MemoryStatsController implements VmInformationServiceController { + + private final MemoryStatsView view; + private final VmMemoryStatDAO vmDao; + + private final VmRef ref; + private final Timer timer; + + private final Map<String, Payload> regions; + + private VMCollector collector; + + class VMCollector implements Runnable { + + private long desiredUpdateTimeStamp = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1); + + @Override + public void run() { + List<VmMemoryStat> vmInfo = vmDao.getLatestVmMemoryStats(ref, desiredUpdateTimeStamp); + for (VmMemoryStat memoryStats: vmInfo) { + List<Generation> generations = memoryStats.getGenerations(); + + for (Generation generation : generations) { + List<Space> spaces = generation.spaces; + for (Space space: spaces) { + Payload payload = regions.get(space.name); + if (payload == null) { + payload = new Payload(); + payload.setName(space.name); + } + + Scale usedScale = normalizeScale(space.used, space.capacity); + double used = Scale.convertTo(usedScale, space.used, 100); + double maxUsed = Scale.convertTo(usedScale, space.capacity, 100); + + payload.setUsed(used); + payload.setMaxUsed(maxUsed); + payload.setUsedUnit(usedScale); + + Scale maxScale = normalizeScale(space.capacity, space.maxCapacity); + double capacity = Scale.convertTo(maxScale, space.capacity, 100); + double maxCapacity = Scale.convertTo(maxScale, space.maxCapacity, 100); + + payload.setCapacity(capacity); + payload.setMaxCapacity(maxCapacity); + payload.setCapacityUnit(maxScale); + + String tooltip = space.name + ": used: " + used + " " + usedScale + + ", capacity: " + capacity + " " + maxScale + + ", max capacity: " + maxCapacity + " " + maxScale; + + payload.setTooltip(tooltip); + + StatsModel model = payload.getModel(); + if (model == null) { + model = new StatsModel(); + model.setName(space.name); + model.setRange(3600); + } + + // normalize this always in the same unit + model.addData(memoryStats.getTimeStamp(), + Scale.convertTo(Scale.MiB, space.used, 100)); + + payload.setModel(model); + if (regions.containsKey(space.name)) { + view.updateRegion(payload.clone()); + } else { + view.addRegion(payload.clone()); + regions.put(space.name, payload); + } + + view.requestRepaint(); + desiredUpdateTimeStamp = Math.max(desiredUpdateTimeStamp, memoryStats.getTimeStamp()); + } + } + } + } + } + + public MemoryStatsController(final VmMemoryStatDAO vmMemoryStatDao, final VmRef ref, MemoryStatsViewProvider viewProvider) { + + regions = new HashMap<>(); + this.ref = ref; + vmDao = vmMemoryStatDao; + view = viewProvider.createView(); + + timer = ApplicationContext.getInstance().getTimerFactory().createTimer(); + + collector = new VMCollector(); + timer.setAction(collector); + + timer.setInitialDelay(0); + timer.setDelay(1000); + timer.setTimeUnit(TimeUnit.MILLISECONDS); + timer.setSchedulingType(SchedulingType.FIXED_RATE); + + view.addActionListener(new ActionListener<Action>() { + @Override + public void actionPerformed(ActionEvent<Action> actionEvent) { + switch(actionEvent.getActionId()) { + case HIDDEN: + stop(); + break; + + case VISIBLE: + start(); + break; + + default: + throw new NotImplementedException("unknown event: " + actionEvent.getActionId()); + } + } + }); + } + + // for testing + VMCollector getCollector() { + return collector; + }; + + Map<String, Payload> getRegions() { + return regions; + } + + private Scale normalizeScale(long min, long max) { + // FIXME: this is very dumb and very inefficient + // needs cleanup + Scale minScale = Scale.getScale(min); + Scale maxScale = Scale.getScale(max); + + Scale[] scales = Scale.values(); + int maxID = 0; + int minID = 0; + for (int i = 0; i < scales.length; i++) { + if (scales[i] == minScale) { + minID = i; + } + if (scales[i] == maxScale) { + maxID = i; + } + } + while (maxID - minID >= 2) { + minID++; + } + return scales[minID]; + } + + private void start() { + timer.start(); + } + + private void stop() { + timer.stop(); + } + + @Override + public String getLocalizedName() { + Translate<LocaleResources> t = LocaleResources.createLocalizer(); + return t.localize(LocaleResources.VM_INFO_TAB_MEMORY); + } + + @Override + public UIComponent getView() { + return (UIComponent) view; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,67 @@ +/* + * 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.client.stats.memory.core; + +import com.redhat.thermostat.client.core.VmFilter; +import com.redhat.thermostat.client.core.VmInformationService; +import com.redhat.thermostat.client.core.controllers.VmInformationServiceController; +import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter; +import com.redhat.thermostat.common.dao.VmMemoryStatDAO; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.utils.OSGIUtils; + +public class MemoryStatsService implements VmInformationService { + + private VmFilter filter = new AlwaysMatchFilter(); + + private VmMemoryStatDAO vmMemoryStatDao; + + public MemoryStatsService(VmMemoryStatDAO vmMemoryStatDao) { + this.vmMemoryStatDao = vmMemoryStatDao; + } + + @Override + public VmInformationServiceController getInformationServiceController(VmRef ref) { + MemoryStatsViewProvider viewProvider = OSGIUtils.getInstance().getService(MemoryStatsViewProvider.class); + return new MemoryStatsController(vmMemoryStatDao, ref, viewProvider); + } + + @Override + public VmFilter getFilter() { + return filter; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsView.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,48 @@ +/* + * 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.client.stats.memory.core; + +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.core.views.UIComponent; + +public abstract class MemoryStatsView extends BasicView implements UIComponent { + + public abstract void addRegion(Payload region); + public abstract void updateRegion(Payload region); + + public abstract void requestRepaint(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsViewProvider.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,46 @@ +/* + * 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.client.stats.memory.core; + +import com.redhat.thermostat.client.core.views.ViewProvider; + +public interface MemoryStatsViewProvider extends ViewProvider { + + @Override + public MemoryStatsView createView(); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/Payload.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,145 @@ +/* + * 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.client.stats.memory.core; + +import com.redhat.thermostat.common.utils.DisplayableValues.Scale; + +public class Payload implements Cloneable { + + private String name; + private String tooltip; + + private double capacity; + private double maxCapacity; + private double maxUsed; + private double used; + + private Scale usedUnit; + private Scale capacityUnit; + + private StatsModel model; + + public void setModel(StatsModel model) { + this.model = model; + } + + public StatsModel getModel() { + return model; + } + + public void setCapacityUnit(Scale capacityUnit) { + this.capacityUnit = capacityUnit; + } + + public Scale getCapacityUnit() { + return capacityUnit; + } + + public void setUsedUnit(Scale usedUnit) { + this.usedUnit = usedUnit; + } + + public Scale getUsedUnit() { + return usedUnit; + } + + public double getMaxCapacity() { + return maxCapacity; + } + + public void setMaxCapacity(double maxCapacity) { + this.maxCapacity = maxCapacity; + } + + public double getUsed() { + return used; + } + + public void setUsed(double used) { + this.used = used; + } + + public double getMaxUsed() { + return maxUsed; + } + + public void setMaxUsed(double maxUsed) { + this.maxUsed = maxUsed; + } + + public double getCapacity() { + return capacity; + } + + public void setCapacity(double capacity) { + this.capacity = capacity; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTooltip() { + return tooltip; + } + + public void setTooltip(String tooltip) { + this.tooltip = tooltip; + } + + @Override + protected Payload clone() { + + Payload copy = new Payload(); + + copy.used = used; + copy.capacity = capacity; + copy.capacityUnit = capacityUnit; + copy.maxCapacity = maxCapacity; + copy.maxUsed = maxUsed; + copy.model = model.clone(); + copy.name = name; + copy.tooltip = tooltip; + copy.usedUnit = usedUnit; + + return copy; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/RangeModel.java Tue Oct 23 11:22:31 2012 -0400 @@ -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.client.stats.memory.core; + +public class RangeModel { + + private int minNormalized; + private double min; + + private int maxNormalized; + private double max; + + private double value; + + public double getMinimum() { + return min; + } + + public void setMinimum(double newMinimum) { + this.min = newMinimum; + } + + public double getMaximum() { + return max; + } + + public void setMaximum(double newMaximum) { + this.max = newMaximum; + } + + public void setMaxNormalized(int maxNormalized) { + this.maxNormalized = maxNormalized; + } + + public void setMinNormalized(int minNormalized) { + this.minNormalized = minNormalized; + } + + public double getValue() { + return value; + } + + public void setValue(double newValue) { + this.value = newValue; + } + + int getMaxNormalized() { + return maxNormalized; + } + + int getMinNormalized() { + return minNormalized; + } + + public int getValueNormalized() { + double normalized = ((value - min) * (maxNormalized - minNormalized)/(max - min)) + minNormalized; + return (int) Math.round(normalized); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/StatsModel.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,181 @@ +/* + * 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.client.stats.memory.core; + +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.util.Date; + +import javax.swing.plaf.ColorUIResource; + +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.DateAxis; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.StandardXYItemRenderer; +import org.jfree.data.time.Millisecond; +import org.jfree.data.time.TimeSeries; +import org.jfree.data.time.TimeSeriesCollection; +import org.jfree.data.xy.XYDataset; +import org.jfree.ui.RectangleInsets; + +public class StatsModel implements Cloneable { + + private static final String lock = new String("MemoryStatsModelLock"); + + private String name; + + private TimeSeries dataSet; + + public StatsModel() { + dataSet = new TimeSeries(""); + } + + BufferedImage getChart(int width, int height, ColorUIResource bgColor, ColorUIResource fgColor) { + JFreeChart chart = createChart(bgColor, fgColor); + + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + chart.draw((Graphics2D) image.getGraphics(), new Rectangle2D.Double(0, 0, width, height), null); + + return image; + } + + public String getName() { + return name; + } + + public void setName(String name) { + dataSet.setDescription(name); + this.name = name; + } + + public void setRange(int seconds) { + dataSet.setMaximumItemCount(seconds); + } + + public void addData(long timestamp, double value) { + Millisecond millisecond = new Millisecond(new Date(timestamp)); + synchronized (lock) { + if (dataSet.getValue(millisecond) == null) { + dataSet.add(millisecond, value); + dataSet.removeAgedItems(true); + } + } + } + + @Override + protected StatsModel clone() { + + StatsModel model = new StatsModel(); + model.setName(name); + model.setRange(dataSet.getMaximumItemCount()); + + try { + model.dataSet = dataSet.createCopy(0, dataSet.getItemCount() - 1); + } catch (CloneNotSupportedException e) { + // ah... it's supported here... + e.printStackTrace(); + } + + return model; + } + + /** + * Creates a chart. + * + * @return a chart. + */ + private JFreeChart createChart(ColorUIResource bgColor, ColorUIResource fgColor) { + + XYDataset priceData = null; + synchronized (lock) { + try { + priceData = new TimeSeriesCollection(dataSet.createCopy(0, + dataSet.getItemCount() - 1)); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } + + XYPlot plot = new XYPlot(); + + plot.setDomainGridlinesVisible(false); + plot.setDomainCrosshairVisible(false); + plot.setRangeGridlinesVisible(false); + plot.setRangeCrosshairVisible(false); + + DateAxis dateAxis = new DateAxis(); + + dateAxis.setTickLabelsVisible(false); + dateAxis.setTickMarksVisible(false); + dateAxis.setAxisLineVisible(false); + dateAxis.setNegativeArrowVisible(false); + dateAxis.setPositiveArrowVisible(false); + dateAxis.setVisible(false); + + NumberAxis numberAxis = new NumberAxis(); + numberAxis.setTickLabelsVisible(false); + numberAxis.setTickMarksVisible(false); + numberAxis.setAxisLineVisible(false); + numberAxis.setNegativeArrowVisible(false); + numberAxis.setPositiveArrowVisible(false); + numberAxis.setVisible(false); + numberAxis.setAutoRangeIncludesZero(false); + + plot.setDomainAxis(dateAxis); + plot.setRangeAxis(numberAxis); + plot.setDataset(priceData); + + plot.setInsets(new RectangleInsets(-1, -1, 0, 0)); + + plot.setRenderer(new StandardXYItemRenderer(StandardXYItemRenderer.LINES)); + plot.setBackgroundPaint(bgColor); + + JFreeChart chart = new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT, plot, false); + + plot.getRenderer().setSeriesPaint(0, fgColor); + chart.setAntiAlias(true); + chart.setBorderVisible(false); + + return chart; + } + + TimeSeries getDataSet() { + return dataSet; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/locale/LocaleResources.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,52 @@ +/* + * 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.client.stats.memory.core.locale; + +import com.redhat.thermostat.common.locale.Translate; + +public enum LocaleResources { + + VM_INFO_TAB_MEMORY, + RESOURCE_MISSING; + + public static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.client.stats.memory.locale.strings"; + + public static Translate<LocaleResources> createLocalizer() { + return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/main/resources/com/redhat/thermostat/client/stats/memory/locale/strings.properties Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,2 @@ +RESOURCE_MISSING = Missing translation! +VM_INFO_TAB_MEMORY = Memory \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsControllerTest.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,269 @@ +/* + * 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.client.stats.memory.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.Timer; +import com.redhat.thermostat.common.Timer.SchedulingType; +import com.redhat.thermostat.common.TimerFactory; +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.appctx.ApplicationContextUtil; +import com.redhat.thermostat.common.dao.VmMemoryStatDAO; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.model.VmMemoryStat; +import com.redhat.thermostat.common.model.VmMemoryStat.Generation; +import com.redhat.thermostat.common.model.VmMemoryStat.Space; + +public class MemoryStatsControllerTest { + + private List<Generation> generations = new ArrayList<>(); + + private VmMemoryStatDAO memoryStatDao; + private MemoryStatsView view; + private Timer timer; + + private ActionListener<MemoryStatsView.Action> viewListener; + + private MemoryStatsController controller; + + private Space canary; + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Before + public void setUp() { + timer = mock(Timer.class); + ArgumentCaptor<Runnable> actionCaptor = ArgumentCaptor.forClass(Runnable.class); + doNothing().when(timer).setAction(actionCaptor.capture()); + + TimerFactory timerFactory = mock(TimerFactory.class); + when(timerFactory.createTimer()).thenReturn(timer); + ApplicationContext.getInstance().setTimerFactory(timerFactory); + + List<VmMemoryStat> vmInfo = new ArrayList<>(); + + for (int i = 0; i < 2; i++) { + Generation generation = new Generation(); + generation.name = "fluff" + i; + generation.spaces = new ArrayList<>(); + for (int j = 0; j < 2; j++) { + Space space = new Space(); + space.name = "fluffer" + i + j; + space.used = 100; + space.capacity = 1000; + space.maxCapacity = 10000; + + generation.spaces.add(space); + } + generations.add(generation); + } + + // special payload because the others have all the same values + canary = new Space(); + canary.name = "canary"; + canary.used = 1; + canary.capacity = 2; + canary.maxCapacity = 3; + + long timestamp = 1; + int vmID = 1; + for (int i = 0; i < 5; i++) { + VmMemoryStat vmMemory = new VmMemoryStat(timestamp++, vmID, generations); + vmInfo.add(vmMemory); + } + + generations.get(0).spaces.add(canary); + + memoryStatDao = mock(VmMemoryStatDAO.class); + when(memoryStatDao.getLatestVmMemoryStats(any(VmRef.class), anyLong())).thenReturn(vmInfo); + + view = mock(MemoryStatsView.class); + MemoryStatsViewProvider viewProvider = mock(MemoryStatsViewProvider.class); + when(viewProvider.createView()).thenReturn(view); + + ArgumentCaptor<ActionListener> viewArgumentCaptor = + ArgumentCaptor.forClass(ActionListener.class); + doNothing().when(view).addActionListener(viewArgumentCaptor.capture()); + + VmRef ref = mock(VmRef.class); + + controller = new MemoryStatsController(memoryStatDao, ref, viewProvider); + + viewListener = viewArgumentCaptor.getValue(); + } + + @Test + public void testStartStopTimer() { + viewListener.actionPerformed(new ActionEvent<>(view, MemoryStatsView.Action.VISIBLE)); + + verify(timer).start(); + verify(timer).setSchedulingType(SchedulingType.FIXED_RATE); + + viewListener.actionPerformed(new ActionEvent<>(view, MemoryStatsView.Action.HIDDEN)); + + verify(timer).stop(); + } + + @Test + public void testPayloadContainSpaces() { + MemoryStatsController.VMCollector collettor = controller.getCollector(); + collettor.run(); + + Map<String, Payload> regions = controller.getRegions(); + assertEquals(5, regions.size()); + + assertTrue(regions.containsKey("fluffer00")); + assertTrue(regions.containsKey("fluffer01")); + assertTrue(regions.containsKey("fluffer10")); + assertTrue(regions.containsKey("fluffer11")); + + assertTrue(regions.containsKey("canary")); + } + + @Test + public void testValues() { + MemoryStatsController.VMCollector collettor = controller.getCollector(); + collettor.run(); + + Map<String, Payload> regions = controller.getRegions(); + + Payload payload = regions.get("fluffer00"); + assertEquals("fluffer00", payload.getName()); + assertEquals(10000, payload.getMaxCapacity(), 0); + assertEquals(1000, payload.getCapacity(), 0); + assertEquals(100, payload.getUsed(), 0); + + payload = regions.get("canary"); + assertEquals("canary", payload.getName()); + assertEquals(3, payload.getMaxCapacity(), 0); + assertEquals(2, payload.getCapacity(), 0); + assertEquals(1, payload.getUsed(), 0); + + // the value above all ensure the same scale is used + String tooltip = payload.getName() + ": used: " + payload.getUsed() + " " + + payload.getUsedUnit() + ", capacity: " + + payload.getCapacity() + " " + payload.getUsedUnit() + + ", max capacity: " + payload.getMaxCapacity() + " " + + payload.getUsedUnit(); + + assertEquals(tooltip, payload.getTooltip()); + } + + + @Test + public void testTimerFetchesMemoryDataDeltaOnly() { + ArgumentCaptor<Long> timeStampCaptor = ArgumentCaptor.forClass(Long.class); + + final long DATA_TIMESTAMP = System.currentTimeMillis() + 1000000000; + Space space = new Space(); + space.capacity = 10; + space.maxCapacity = 20; + space.used = 5; + Generation gen = new Generation(); + gen.name = "foobar"; + gen.spaces = Arrays.asList(space); + VmMemoryStat stat = new VmMemoryStat(); + stat.setTimeStamp(DATA_TIMESTAMP); + stat.setGenerations(Arrays.asList(gen)); + + when(memoryStatDao.getLatestVmMemoryStats(isA(VmRef.class), anyLong())).thenReturn(Arrays.asList(stat)); + + Runnable timerAction = controller.getCollector(); + + timerAction.run(); + timerAction.run(); + + verify(memoryStatDao, times(2)).getLatestVmMemoryStats(isA(VmRef.class), timeStampCaptor.capture()); + + long timeStamp1 = timeStampCaptor.getAllValues().get(0); + assertTimeStampIsAround(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1), timeStamp1); + + long timeStamp2 = timeStampCaptor.getAllValues().get(1); + assertTimeStampIsAround(DATA_TIMESTAMP, timeStamp2); + } + + @Test + public void testTimerFetchesMemoryDataDeltaOnlyEvenWithNoData() { + ArgumentCaptor<Long> timeStampCaptor = ArgumentCaptor.forClass(Long.class); + + Runnable timerAction = controller.getCollector(); + + timerAction.run(); + timerAction.run(); + + verify(memoryStatDao, times(2)).getLatestVmMemoryStats(isA(VmRef.class), timeStampCaptor.capture()); + + long timeStamp1 = timeStampCaptor.getAllValues().get(0); + assertTimeStampIsAround(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1), timeStamp1); + + long timeStamp2 = timeStampCaptor.getAllValues().get(1); + assertTimeStampIsAround(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1), timeStamp2); + } + + private void assertTimeStampIsAround(long expected, long actual) { + assertTrue(actual <= expected + 1000); + assertTrue(actual >= expected - 1000); + } + + @After + public void tearDown() { + ApplicationContextUtil.resetApplicationContext(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/PayloadTest.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,82 @@ +/* + * 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.client.stats.memory.core; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.redhat.thermostat.common.utils.DisplayableValues.Scale; + +public class PayloadTest { + + @Test + public void testClone() { + + StatsModel model = new StatsModel(); + model.setName("fluffModel"); + model.setRange(100); + model.addData(500, 2.0); + model.addData(501, 2.1); + + Payload source = new Payload(); + source.setCapacity(10.0); + source.setName("fluff"); + source.setCapacityUnit(Scale.GiB); + source.setMaxCapacity(100.0); + source.setMaxUsed(5.0); + source.setUsed(3.0); + source.setUsedUnit(Scale.MiB); + source.setModel(model); + source.setTooltip("fluffTooltip"); + + Payload cloned = source.clone(); + assertNotSame(cloned, source); + + assertEquals(source.getName(), cloned.getName()); + assertEquals(source.getCapacity(), cloned.getCapacity(), 0); + assertEquals(source.getCapacityUnit(), cloned.getCapacityUnit()); + assertEquals(source.getMaxCapacity(), cloned.getMaxCapacity(), 0); + assertEquals(source.getMaxUsed(), cloned.getMaxUsed(), 0); + assertEquals(source.getTooltip(), cloned.getTooltip()); + assertEquals(source.getUsed(), cloned.getUsed(), 0); + assertEquals(source.getUsedUnit(), cloned.getUsedUnit()); + assertNotSame(source.getModel(), cloned.getModel()); + + assertEquals(source.getModel().getName(), cloned.getModel().getName()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/RangeModelTest.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,123 @@ +/* + * 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.client.stats.memory.core; + +import static org.junit.Assert.*; +import junit.framework.Assert; + +import org.junit.Test; + +public class RangeModelTest { + + @Test + public void testSameRange() { + RangeModel model = new RangeModel(); + + model.setMaximum(10); + model.setMinimum(0); + model.setValue(5); + + model.setMaxNormalized(10); + model.setMinNormalized(0); + + + Assert.assertEquals((int) model.getValue(), model.getValueNormalized()); + } + + @Test + public void testDoubleRange() { + RangeModel model = new RangeModel(); + + model.setMaximum(10); + model.setMinimum(0); + model.setValue(5); + + model.setMaxNormalized(20); + model.setMinNormalized(0); + + + Assert.assertEquals(10, model.getValueNormalized()); + } + + @Test + public void testRanges() { + RangeModel model = new RangeModel(); + + model.setMaximum(10); + model.setMinimum(0); + model.setValue(5); + + model.setMaxNormalized(40); + model.setMinNormalized(0); + + Assert.assertEquals(20, model.getValueNormalized()); + + model.setMaxNormalized(60); + model.setMinNormalized(0); + + Assert.assertEquals(30, model.getValueNormalized()); + + model.setMaxNormalized(200); + model.setMinNormalized(100); + + Assert.assertEquals(150, model.getValueNormalized()); + + model.setMaximum(100); + model.setMinimum(0); + model.setValue(50); + + model.setMaxNormalized(1); + model.setMinNormalized(0); + + Assert.assertEquals(1, model.getValueNormalized()); + + model.setValue(49); + Assert.assertEquals(0, model.getValueNormalized()); + + model.setMaximum(1.0); + model.setMinimum(0.0); + model.setValue(0.5); + + model.setMaxNormalized(100); + model.setMinNormalized(0); + + Assert.assertEquals(50, model.getValueNormalized()); + + model.setValue(0.72); + Assert.assertEquals(72, model.getValueNormalized()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/StatsModelTest.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,71 @@ +/* + * 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.client.stats.memory.core; + +import static org.junit.Assert.*; + +import org.jfree.data.time.TimeSeries; +import org.junit.Test; + +public class StatsModelTest { + + @Test + public void testClone() { + + StatsModel source = new StatsModel(); + source.setName("fluffModel"); + source.setRange(100); + source.addData(500, 2.0); + source.addData(501, 2.1); + + StatsModel cloned = source.clone(); + + assertNotSame(cloned, source); + + assertEquals(source.getName(), cloned.getName()); + + assertNotSame(cloned.getDataSet(), source.getDataSet()); + + for (Object series : cloned.getDataSet().getItems()) { + assertTrue(source.getDataSet().getItems().contains(series)); + } + + assertEquals(cloned.getDataSet().getItemCount(), + source.getDataSet().getItemCount()); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/core/src/test/java/com/redhat/thermostat/client/stats/memory/core/locale/TranslateTest.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,80 @@ +/* + * 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.client.stats.memory.core.locale; + +import java.io.IOException; +import java.util.Locale; +import java.util.Properties; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.client.stats.memory.core.locale.LocaleResources; +import com.redhat.thermostat.common.locale.Translate; + +public class TranslateTest { + + private Locale lang; + + @Before + public void setUp() { + this.lang = Locale.getDefault(); + Locale.setDefault(Locale.US); + } + + @After + public void tearDown() { + Locale.setDefault(lang); + } + + @Test + public void verifyTranslationsAreThere() throws IOException { + + String stringsResource = "/" + LocaleResources.RESOURCE_BUNDLE.replace(".", "/") + ".properties"; + + Properties props = new Properties(); + props.load(getClass().getResourceAsStream(stringsResource)); + + Assert.assertEquals(LocaleResources.values().length, props.values().size()); + Translate<LocaleResources> t = LocaleResources.createLocalizer(); + Assert.assertEquals("Missing translation!", t.localize(LocaleResources.RESOURCE_MISSING)); + Assert.assertEquals("Memory", t.localize(LocaleResources.VM_INFO_TAB_MEMORY)); + } +}
--- a/client/memory-stats-panel/pom.xml Tue Oct 23 11:21:50 2012 -0400 +++ b/client/memory-stats-panel/pom.xml Tue Oct 23 11:22:31 2012 -0400 @@ -1,81 +1,58 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.redhat.thermostat</groupId> <artifactId>thermostat-client</artifactId> - <groupId>com.redhat.thermostat</groupId> <version>0.5.0-SNAPSHOT</version> </parent> + <artifactId>thermostat-osgi-memory-stats-panel</artifactId> - <packaging>bundle</packaging> + <packaging>pom</packaging> + <name>Thermostat Client VM Memory Monitor plugin</name> - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <Private-Package> - com.redhat.thermostat.client.stats.memory, - com.redhat.thermostat.client.stats.memory.locale, - </Private-Package> - <Bundle-Activator>com.redhat.thermostat.client.stats.memory.MemoryStatsPanelActivator</Bundle-Activator> - <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> - <Bundle-SymbolicName>com.redhat.thermostat.client.stats.memory</Bundle-SymbolicName> - <!-- Do not autogenerate uses clauses in Manifests --> - <_nouses>true</_nouses> - </instructions> - </configuration> - </plugin> - </plugins> - </build> - <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.easytesting</groupId> - <artifactId>fest-swing</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>net.java.openjdk.cacio</groupId> - <artifactId>cacio-tta</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.core</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.compendium</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.jfree</groupId> - <artifactId>jfreechart</artifactId> - </dependency> - <dependency> - <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-common-core</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>com.redhat.thermostat</groupId> - <artifactId>thermostat-client-core</artifactId> - <version>${project.version}</version> - </dependency> - </dependencies> + <modules> + <module>core</module> + <module>swing</module> + </modules> + </project>
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryGraphPanel.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * 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.client.stats.memory; - -import java.awt.Dimension; -import java.beans.Transient; - -import javax.swing.BoxLayout; -import javax.swing.JPanel; - -@SuppressWarnings("serial") -class MemoryGraphPanel extends JPanel { - - private MemoryMeter meter; - - /** - * Create the panel. - */ - public MemoryGraphPanel() { - setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); - meter = new MemoryMeter(); - add(meter); - } - - public void setMemoryGraphProperties(Payload region) { - - meter.getPrimaryModel().setMinimum(0); - meter.getPrimaryModel().setMaximum(region.getMaxUsed()); - meter.getPrimaryModel().setValue(region.getUsed()); - - meter.getSecondaryModel().setMinimum(0); - meter.getSecondaryModel().setMaximum(region.getMaxCapacity()); - meter.getSecondaryModel().setValue(region.getCapacity()); - - meter.setToolTipText(region.getTooltip()); - - meter.setPrimaryScaleUnit(region.getUsedUnit().toString()); - meter.setSecondayScaleUnit(region.getCapacityUnit().toString()); - - meter.setStats(region.getModel()); - } - - @Override - @Transient - public Dimension getPreferredSize() { - return meter.getPreferredSize(); - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryMeter.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,433 +0,0 @@ -/* - * 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.client.stats.memory; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.GradientPaint; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.beans.Transient; - -import javax.swing.JComponent; -import javax.swing.plaf.ColorUIResource; - -import sun.swing.SwingUtilities2; - -@SuppressWarnings({ "restriction", "serial" }) -public class MemoryMeter extends JComponent { - - // TODO the font should be customizable - private static final Font font = new Font("SansSerif", Font.PLAIN, 10); - - private static final int TICK_NUM = 100; - private static final int SMALL_TICK_NUM = 5; - - private static final int MAIN_BAR_HEIGHT = 20; - - private static final ColorUIResource MAIN_GRADIENT_TOP = new ColorUIResource(0xf1f3f1); - private static final ColorUIResource MAIN_BORDER_COLOR = new ColorUIResource(0xa8aca8); - - private static final ColorUIResource MAIN_BAR_BASE_COLOR_TOP = new ColorUIResource(0xbcd5ef); - private static final ColorUIResource MAIN_BAR_BASE_COLOR = new ColorUIResource(0x4A90D9); - - //private static final ColorUIResource STATS_BG = new ColorUIResource(0xF8F8F8); - private static final ColorUIResource STATS_BG = new ColorUIResource(0xFFFFFF); - - private ColorUIResource tickColor; - - private RangeModel primary; - private RangeModel secondary; - - private Insets boundInsets; - - private RangeModel internalSecondaryModel; - - private StatsModel primaryStats; - - private String primaryUnit; - private String secondaryUnit; - - public void setPrimaryScaleUnit(String primaryUnit) { - this.primaryUnit = primaryUnit; - } - - public void setSecondayScaleUnit(String secondaryUnit) { - this.secondaryUnit = secondaryUnit; - } - - public StatsModel getStats() { - return primaryStats; - } - - public void setStats(StatsModel primaryStats) { - this.primaryStats = primaryStats; - } - - public MemoryMeter() { - - secondaryUnit = ""; - primaryUnit = ""; - - boundInsets = new Insets(10, 10, 20, 20); - - tickColor = new ColorUIResource(0xdbdddb); - - primary = new RangeModel(); - primary.setMinimum(0); - primary.setMaximum(100); - primary.setMinNormalized(0); - primary.setMaxNormalized(100); - - secondary = new RangeModel(); - secondary.setMinimum(0); - secondary.setMaximum(100); - secondary.setMinNormalized(0); - secondary.setMaxNormalized(100); - - internalSecondaryModel = new RangeModel(); - } - - public ColorUIResource getTickColor() { - return tickColor; - } - - public void setTickColor(ColorUIResource tickColor) { - this.tickColor = tickColor; - } - - public RangeModel getPrimaryModel() { - return primary; - } - - public RangeModel getSecondaryModel() { - return secondary; - } - - protected Rectangle getOuterBounds() { - return new Rectangle(0, 0, getWidth(), getHeight()); - } - - protected Rectangle getBoundsWithInsets(Rectangle bounds) { - return new Rectangle(bounds.x + boundInsets.left, - bounds.y + boundInsets.top, - bounds.width - boundInsets.right, - bounds.height - boundInsets.bottom); - } - - /** - * paint the outher frame, including the light border sorrounding - */ - protected void paintOuterFrame(Graphics2D graphics, Rectangle bounds) { - - RoundRectangle2D frame = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height, 6, 6); - - Paint paint = new GradientPaint(0, 0, MAIN_GRADIENT_TOP, 0, getHeight(), getBackground()); - graphics.setPaint(paint); - graphics.fill(frame); - - paint = new GradientPaint(0, 0, MAIN_BORDER_COLOR, 0, getHeight(), getBackground()); - graphics.setPaint(paint); - frame = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width -1, bounds.height, 6, 6); - graphics.draw(frame); - } - - /** - * paint the track sorrounding the main bar - */ - protected void paintMainBarTrackFill(Graphics2D graphics, Rectangle bounds) { - - Paint paint = new GradientPaint(0, 0, MAIN_GRADIENT_TOP, 0, bounds.height, Color.WHITE); - graphics.setPaint(paint); - RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width, bounds.height, 6, 6); - graphics.fill(frame); - } - - /** - */ - protected void paintMainBarTrackBorder(Graphics2D graphics, Rectangle bounds) { - Paint paint = new GradientPaint(0, 0, MAIN_BORDER_COLOR, getWidth(), 0, getBackground()); - graphics.setPaint(paint); - - RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, bounds.width - 1, bounds.height, 6, 6); - graphics.draw(frame); - } - - - /** - * this is the main bar, will it up to what is defined by the model - */ - protected void paintMainBarFill(Graphics2D graphics, Rectangle bounds) { - Paint paint = new GradientPaint(0, 0, MAIN_BAR_BASE_COLOR, getWidth() * 2, 0, getBackground()); - graphics.setPaint(paint); - - RoundRectangle2D frame = - new RoundRectangle2D.Float(0, 0, getPrimaryModel().getValueNormalized(), - bounds.height, 6, 6); - graphics.fill(frame); - - String value = String.valueOf(getPrimaryModel().getValue()) + " " + primaryUnit; - Rectangle2D fontBounds = font.getStringBounds(value, graphics.getFontRenderContext()); - int width = (int) (bounds.width/2 - fontBounds.getWidth()/2) - 1; - - if (width > getPrimaryModel().getValueNormalized()) { - graphics.setPaint(MAIN_BAR_BASE_COLOR); - } else { - graphics.setPaint(getBackground()); - } - - int height = (int) (bounds.height / 2 + fontBounds.getHeight()/2); - SwingUtilities2.drawString(this, graphics, value, width, height); - } - - /** - */ - private void paintMainBar(Graphics2D g, Rectangle bounds) { - - Graphics2D graphics = (Graphics2D) g.create(); - - graphics.translate(bounds.x, bounds.y); - paintMainBarTrackFill(graphics, bounds); - - paintMainBarFill(graphics, bounds); - - paintMainBarTrackBorder(graphics, bounds); - graphics.dispose(); - } - - /** - */ - protected void drawBottomBar(Graphics2D g, Rectangle bounds) { - - Graphics2D graphics = (Graphics2D) g.create(); - graphics.translate(bounds.x, bounds.y + bounds.height); - - drawTickMark(graphics, bounds); - - paintSecondaryBarFill(graphics, bounds); - - graphics.dispose(); - } - - /** - */ - protected void drawTickMark(Graphics2D graphics, Rectangle bounds) { - - graphics.setPaint(MAIN_BORDER_COLOR); - - int smallTop = bounds.height - 5; - int smallBottom = bounds.height; - - int mainTop = smallTop + 20; - int mainBottom = smallBottom - 15; - - // the first and last tick are always big, this is the first - graphics.drawLine(0, mainTop, 0, mainBottom); - - // the space between the vertical lines - double tickSpace = ((double) bounds.width) / TICK_NUM; - - internalSecondaryModel.setMaxNormalized(bounds.width); - int numTicks = 0; - - for (int x = 0; x < bounds.width; x += tickSpace + 0.5) { - if (numTicks % SMALL_TICK_NUM == 0) { - - graphics.drawLine(x, smallTop, x, smallBottom + 5); - - internalSecondaryModel.setValue(x); - } else { - graphics.drawLine(x, smallTop, x, smallBottom); - } - numTicks++; - } - - // that's the last - graphics.drawLine(bounds.width, mainTop, bounds.width, mainBottom); - graphics.drawLine(0, smallTop, bounds.width, smallTop); - - drawStrings(graphics, mainBottom, mainTop, bounds.width); - } - - protected void drawStrings(Graphics2D graphics, int top, int bottom, int right) { - - // now draw the min/max values of both side of markers - // top bar min value - FontMetrics fm = SwingUtilities2.getFontMetrics(this, font); - - String value = String.valueOf(getPrimaryModel().getMinimum()) + " " + primaryUnit; - int height = top + fm.getAscent()/2; - SwingUtilities2.drawString(this, graphics, value, 1, height); - - value = String.valueOf(getSecondaryModel().getMinimum()) + " " + secondaryUnit; - height = bottom; - SwingUtilities2.drawString(this, graphics, value, 1, height); - - value = String.valueOf(getPrimaryModel().getMaximum()) + " " + primaryUnit; - height = top + fm.getAscent()/2; - - int width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; - SwingUtilities2.drawString(this, graphics, value, width, height); - - value = String.valueOf(getSecondaryModel().getMaximum()) + " " + secondaryUnit; - height = bottom; - width = (int) (right - font.getStringBounds(value, graphics.getFontRenderContext()).getWidth()) - 1; - SwingUtilities2.drawString(this, graphics, value, width, height); - - // now draw the actual value for the bottom bar, the top bar is drawn in - // its fill method - value = String.valueOf(getSecondaryModel().getValue()) + " " + secondaryUnit; - width = right/2; - Rectangle2D bounds = font.getStringBounds(value, graphics.getFontRenderContext()); - width = (int) (width - bounds.getWidth()/2) - 1; - SwingUtilities2.drawString(this, graphics, value, width, height); - RoundRectangle2D frame = new RoundRectangle2D.Double(width - 2, height - bounds.getHeight(), - bounds.getWidth() + 4, bounds.getHeight() + 4, - 4, 4); - graphics.draw(frame); - } - - protected void paintSecondaryBarFill(Graphics2D graphics, Rectangle bounds) { - - graphics.setPaint(MAIN_BAR_BASE_COLOR_TOP); - graphics.drawLine(1, bounds.height, getSecondaryModel().getValueNormalized() - 1, bounds.height); - - graphics.setPaint(MAIN_BAR_BASE_COLOR); - graphics.fillRect(1, bounds.height + 1, getSecondaryModel().getValueNormalized(), 2); - } - - protected void paintStats(Graphics2D graphics, Rectangle bounds) { - - int imageWidth = bounds.width - 2; - if (imageWidth < 0 || bounds.height < 0) { - return; - } - - StatsModel stats = getStats(); - drawStats(graphics, stats, bounds.x, bounds.y, imageWidth, bounds.height); - } - - private void drawStats(Graphics2D graphics, StatsModel stats, int x, int y, int imageWidth, int height) { - if (stats != null) { - BufferedImage image = stats.getChart(imageWidth, height, STATS_BG, - new ColorUIResource(getForeground())); - - paintStatsLabel(graphics, image, stats.getName()); - graphics.drawImage(image, x, y, null); - } - } - - protected void paintStatsLabel(Graphics2D graphics, BufferedImage image, String label) { - int height = SwingUtilities2.getFontMetrics(this, font).getAscent() + 2; - if (height <= 0) { - return; - } - - Graphics2D imageGraphics = (Graphics2D) image.getGraphics(); - imageGraphics.setColor(getForeground()); - imageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - SwingUtilities2.drawString(this, imageGraphics, label, 2, height); - } - - @Override - protected void paintComponent(Graphics g) { - - Graphics2D graphics = (Graphics2D) g.create(); - graphics.setFont(font); - - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - - Rectangle outerBounds = getOuterBounds(); - Rectangle innerBounds = getBoundsWithInsets(outerBounds); - Rectangle statsBound = getBoundsWithInsets(outerBounds); - - // move the bar close to the center - innerBounds.height = MAIN_BAR_HEIGHT; - innerBounds.y = outerBounds.height/2; - - // make the stats area cover the upper portion instead - statsBound.height = (outerBounds.height/2) - MAIN_BAR_HEIGHT; - - resetModels(0, innerBounds.width); - - // some eye candy - paintOuterFrame(graphics, outerBounds); - - // paint the usage stats - paintStats(graphics, statsBound); - - // main and bottom bars - paintMainBar(graphics, innerBounds); - drawBottomBar(graphics, innerBounds); - - graphics.dispose(); - } - - private void resetModels(int min, int max) { - - getPrimaryModel().setMaxNormalized(max); - getPrimaryModel().setMinNormalized(min); - - RangeModel model = getSecondaryModel(); - model.setMaxNormalized(max); - model.setMinNormalized(min); - - internalSecondaryModel.setMaximum(model.getMaximum()); - internalSecondaryModel.setMinimum(model.getMinimum()); - internalSecondaryModel.setValue(model.getValue()); - - internalSecondaryModel.setMaxNormalized(max); - internalSecondaryModel.setMinNormalized(0); - } - - @Override - @Transient - public Dimension getPreferredSize() { - return new Dimension(850, 150); - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsController.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* - * 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.client.stats.memory; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import com.redhat.thermostat.client.core.controllers.VmInformationServiceController; -import com.redhat.thermostat.client.core.views.BasicView.Action; -import com.redhat.thermostat.client.core.views.UIComponent; -import com.redhat.thermostat.client.stats.memory.locale.LocaleResources; -import com.redhat.thermostat.common.ActionEvent; -import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.common.NotImplementedException; -import com.redhat.thermostat.common.Timer; -import com.redhat.thermostat.common.Timer.SchedulingType; -import com.redhat.thermostat.common.appctx.ApplicationContext; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; -import com.redhat.thermostat.common.dao.VmRef; -import com.redhat.thermostat.common.locale.Translate; -import com.redhat.thermostat.common.model.VmMemoryStat; -import com.redhat.thermostat.common.model.VmMemoryStat.Generation; -import com.redhat.thermostat.common.model.VmMemoryStat.Space; -import com.redhat.thermostat.common.utils.DisplayableValues.Scale; - -class MemoryStatsController implements VmInformationServiceController { - - private final MemoryStatsView view; - private final VmMemoryStatDAO vmDao; - - private final VmRef ref; - private final Timer timer; - - private final Map<String, Payload> regions; - - private VMCollector collector; - - class VMCollector implements Runnable { - - private long desiredUpdateTimeStamp = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1); - - @Override - public void run() { - List<VmMemoryStat> vmInfo = vmDao.getLatestVmMemoryStats(ref, desiredUpdateTimeStamp); - for (VmMemoryStat memoryStats: vmInfo) { - List<Generation> generations = memoryStats.getGenerations(); - - for (Generation generation : generations) { - List<Space> spaces = generation.spaces; - for (Space space: spaces) { - Payload payload = regions.get(space.name); - if (payload == null) { - payload = new Payload(); - payload.setName(space.name); - } - - Scale usedScale = normalizeScale(space.used, space.capacity); - double used = Scale.convertTo(usedScale, space.used, 100); - double maxUsed = Scale.convertTo(usedScale, space.capacity, 100); - - payload.setUsed(used); - payload.setMaxUsed(maxUsed); - payload.setUsedUnit(usedScale); - - Scale maxScale = normalizeScale(space.capacity, space.maxCapacity); - double capacity = Scale.convertTo(maxScale, space.capacity, 100); - double maxCapacity = Scale.convertTo(maxScale, space.maxCapacity, 100); - - payload.setCapacity(capacity); - payload.setMaxCapacity(maxCapacity); - payload.setCapacityUnit(maxScale); - - String tooltip = space.name + ": used: " + used + " " + usedScale + - ", capacity: " + capacity + " " + maxScale + - ", max capacity: " + maxCapacity + " " + maxScale; - - payload.setTooltip(tooltip); - - StatsModel model = payload.getModel(); - if (model == null) { - model = new StatsModel(); - model.setName(space.name); - model.setRange(3600); - } - - // normalize this always in the same unit - model.addData(memoryStats.getTimeStamp(), - Scale.convertTo(Scale.MiB, space.used, 100)); - - payload.setModel(model); - if (regions.containsKey(space.name)) { - view.updateRegion(payload.clone()); - } else { - view.addRegion(payload.clone()); - regions.put(space.name, payload); - } - - view.requestRepaint(); - desiredUpdateTimeStamp = Math.max(desiredUpdateTimeStamp, memoryStats.getTimeStamp()); - } - } - } - } - } - - public MemoryStatsController(final VmMemoryStatDAO vmMemoryStatDao, final VmRef ref, MemoryStatsViewProvider viewProvider) { - - regions = new HashMap<>(); - this.ref = ref; - vmDao = vmMemoryStatDao; - view = viewProvider.createView(); - - timer = ApplicationContext.getInstance().getTimerFactory().createTimer(); - - collector = new VMCollector(); - timer.setAction(collector); - - timer.setInitialDelay(0); - timer.setDelay(1000); - timer.setTimeUnit(TimeUnit.MILLISECONDS); - timer.setSchedulingType(SchedulingType.FIXED_RATE); - - view.addActionListener(new ActionListener<Action>() { - @Override - public void actionPerformed(ActionEvent<Action> actionEvent) { - switch(actionEvent.getActionId()) { - case HIDDEN: - stop(); - break; - - case VISIBLE: - start(); - break; - - default: - throw new NotImplementedException("unknown event: " + actionEvent.getActionId()); - } - } - }); - } - - // for testing - VMCollector getCollector() { - return collector; - }; - - Map<String, Payload> getRegions() { - return regions; - } - - private Scale normalizeScale(long min, long max) { - // FIXME: this is very dumb and very inefficient - // needs cleanup - Scale minScale = Scale.getScale(min); - Scale maxScale = Scale.getScale(max); - - Scale[] scales = Scale.values(); - int maxID = 0; - int minID = 0; - for (int i = 0; i < scales.length; i++) { - if (scales[i] == minScale) { - minID = i; - } - if (scales[i] == maxScale) { - maxID = i; - } - } - while (maxID - minID >= 2) { - minID++; - } - return scales[minID]; - } - - private void start() { - timer.start(); - } - - private void stop() { - timer.stop(); - } - - @Override - public String getLocalizedName() { - Translate<LocaleResources> t = LocaleResources.createLocalizer(); - return t.localize(LocaleResources.VM_INFO_TAB_MEMORY); - } - - @Override - public UIComponent getView() { - return (UIComponent) view; - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsPanelActivator.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * 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.client.stats.memory; - -import java.util.Map; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -import com.redhat.thermostat.client.core.VmInformationService; -import com.redhat.thermostat.client.osgi.service.ApplicationService; -import com.redhat.thermostat.common.MultipleServiceTracker; -import com.redhat.thermostat.common.MultipleServiceTracker.Action; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; - -public class MemoryStatsPanelActivator implements BundleActivator { - - private MultipleServiceTracker tracker; - private ServiceRegistration memoryStatRegistration; - - @Override - public void start(final BundleContext context) throws Exception { - MemoryStatsViewProvider provider = new SwingMemoryStatsViewProvider(); - context.registerService(MemoryStatsViewProvider.class.getName(), provider, null); - - Class<?>[] deps = new Class<?>[] { - ApplicationService.class, - VmMemoryStatDAO.class, - }; - - tracker = new MultipleServiceTracker(context, deps, new Action() { - - @Override - public void dependenciesUnavailable() { - memoryStatRegistration.unregister(); - memoryStatRegistration = null; - } - - @Override - public void dependenciesAvailable(Map<String, Object> services) { - VmMemoryStatDAO memoryStatDao = (VmMemoryStatDAO) services.get(VmMemoryStatDAO.class.getName()); - MemoryStatsService impl = new MemoryStatsService(memoryStatDao); - memoryStatRegistration = context.registerService(VmInformationService.class.getName(), impl , null); - } - }); - tracker.open(); - - } - - @Override - public void stop(BundleContext context) throws Exception { - tracker.close(); - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsService.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * 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.client.stats.memory; - -import com.redhat.thermostat.client.core.VmFilter; -import com.redhat.thermostat.client.core.VmInformationService; -import com.redhat.thermostat.client.core.controllers.VmInformationServiceController; -import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; -import com.redhat.thermostat.common.dao.VmRef; -import com.redhat.thermostat.common.utils.OSGIUtils; - -class MemoryStatsService implements VmInformationService { - - private VmFilter filter = new AlwaysMatchFilter(); - - private VmMemoryStatDAO vmMemoryStatDao; - - public MemoryStatsService(VmMemoryStatDAO vmMemoryStatDao) { - this.vmMemoryStatDao = vmMemoryStatDao; - } - - @Override - public VmInformationServiceController getInformationServiceController(VmRef ref) { - MemoryStatsViewProvider viewProvider = OSGIUtils.getInstance().getService(MemoryStatsViewProvider.class); - return new MemoryStatsController(vmMemoryStatDao, ref, viewProvider); - } - - @Override - public VmFilter getFilter() { - return filter; - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsView.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * 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.client.stats.memory; - -import com.redhat.thermostat.client.core.views.BasicView; -import com.redhat.thermostat.client.core.views.UIComponent; - -public abstract class MemoryStatsView extends BasicView implements UIComponent { - - public abstract void addRegion(Payload region); - public abstract void updateRegion(Payload region); - - public abstract void requestRepaint(); -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsViewImpl.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * 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.client.stats.memory; - -import java.awt.Component; -import java.awt.Dimension; -import java.beans.Transient; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; - -import com.redhat.thermostat.client.core.views.BasicView; -import com.redhat.thermostat.client.ui.ComponentVisibleListener; -import com.redhat.thermostat.client.ui.SwingComponent; -import com.redhat.thermostat.swing.HeaderPanel; - -public class MemoryStatsViewImpl extends MemoryStatsView implements SwingComponent { - - private static final long REPAINT_DELAY = 500; - private long lastRepaint; - - private HeaderPanel visiblePanel; - private JPanel realPanel; - - private final Map<String, MemoryGraphPanel> regions; - - private Dimension preferredSize; - - public MemoryStatsViewImpl() { - super(); - visiblePanel = new HeaderPanel(); - regions = new HashMap<>(); - - preferredSize = new Dimension(0, 0); - - visiblePanel.setHeader("Memory Regions"); - - visiblePanel.addHierarchyListener(new ComponentVisibleListener() { - @Override - public void componentShown(Component component) { - notifier.fireAction(Action.VISIBLE); - } - - @Override - public void componentHidden(Component component) { - notifier.fireAction(Action.HIDDEN); - } - }); - - realPanel = new JPanel(); - realPanel.setLayout(new BoxLayout(realPanel, BoxLayout.Y_AXIS)); - visiblePanel.setContent(realPanel); - } - - @Transient - public Dimension getPreferredSize() { - return new Dimension(preferredSize); - } - - @Override - public void updateRegion(final Payload region) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MemoryGraphPanel memoryGraphPanel = regions.get(region.getName()); - memoryGraphPanel.setMemoryGraphProperties(region); - } - }); - } - - @Override - public void addRegion(final Payload region) { - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MemoryGraphPanel memoryGraphPanel = new MemoryGraphPanel(); - - realPanel.add(memoryGraphPanel); - realPanel.add(Box.createRigidArea(new Dimension(5,5))); - regions.put(region.getName(), memoryGraphPanel); - - // components are stacked up vertically in this panel - Dimension memoryGraphPanelMinSize = memoryGraphPanel.getMinimumSize(); - preferredSize.height += memoryGraphPanelMinSize.height + 5; - if (preferredSize.width < (memoryGraphPanelMinSize.width + 5)) { - preferredSize.width = memoryGraphPanelMinSize.width + 5; - } - - updateRegion(region); - realPanel.revalidate(); - } - }); - } - - @Override - public Component getUiComponent() { - return visiblePanel; - } - - @Override - public void requestRepaint() { - // really only repaint every REPAINT_DELAY milliseconds - long now = System.currentTimeMillis(); - if (now - lastRepaint > REPAINT_DELAY) { - visiblePanel.repaint(); - lastRepaint = System.currentTimeMillis(); - } - } - - public BasicView getView() { - return this; - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/MemoryStatsViewProvider.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * 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.client.stats.memory; - -import com.redhat.thermostat.client.core.views.ViewProvider; - -public interface MemoryStatsViewProvider extends ViewProvider { - - @Override - public MemoryStatsView createView(); - -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/Payload.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * 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.client.stats.memory; - -import com.redhat.thermostat.common.utils.DisplayableValues.Scale; - -public class Payload implements Cloneable { - - private String name; - private String tooltip; - - private double capacity; - private double maxCapacity; - private double maxUsed; - private double used; - - private Scale usedUnit; - private Scale capacityUnit; - - private StatsModel model; - - public void setModel(StatsModel model) { - this.model = model; - } - - public StatsModel getModel() { - return model; - } - - public void setCapacityUnit(Scale capacityUnit) { - this.capacityUnit = capacityUnit; - } - - public Scale getCapacityUnit() { - return capacityUnit; - } - - public void setUsedUnit(Scale usedUnit) { - this.usedUnit = usedUnit; - } - - public Scale getUsedUnit() { - return usedUnit; - } - - public double getMaxCapacity() { - return maxCapacity; - } - - public void setMaxCapacity(double maxCapacity) { - this.maxCapacity = maxCapacity; - } - - public double getUsed() { - return used; - } - - public void setUsed(double used) { - this.used = used; - } - - public double getMaxUsed() { - return maxUsed; - } - - public void setMaxUsed(double maxUsed) { - this.maxUsed = maxUsed; - } - - public double getCapacity() { - return capacity; - } - - public void setCapacity(double capacity) { - this.capacity = capacity; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getTooltip() { - return tooltip; - } - - public void setTooltip(String tooltip) { - this.tooltip = tooltip; - } - - @Override - protected Payload clone() { - - Payload copy = new Payload(); - - copy.used = used; - copy.capacity = capacity; - copy.capacityUnit = capacityUnit; - copy.maxCapacity = maxCapacity; - copy.maxUsed = maxUsed; - copy.model = model.clone(); - copy.name = name; - copy.tooltip = tooltip; - copy.usedUnit = usedUnit; - - return copy; - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/RangeModel.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * 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.client.stats.memory; - -public class RangeModel { - - private int minNormalized; - private double min; - - private int maxNormalized; - private double max; - - private double value; - - public double getMinimum() { - return min; - } - - public void setMinimum(double newMinimum) { - this.min = newMinimum; - } - - public double getMaximum() { - return max; - } - - public void setMaximum(double newMaximum) { - this.max = newMaximum; - } - - public void setMaxNormalized(int maxNormalized) { - this.maxNormalized = maxNormalized; - } - - public void setMinNormalized(int minNormalized) { - this.minNormalized = minNormalized; - } - - public double getValue() { - return value; - } - - public void setValue(double newValue) { - this.value = newValue; - } - - int getMaxNormalized() { - return maxNormalized; - } - - int getMinNormalized() { - return minNormalized; - } - - public int getValueNormalized() { - double normalized = ((value - min) * (maxNormalized - minNormalized)/(max - min)) + minNormalized; - return (int) Math.round(normalized); - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/StatsModel.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * 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.client.stats.memory; - -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.util.Date; - -import javax.swing.plaf.ColorUIResource; - -import org.jfree.chart.JFreeChart; -import org.jfree.chart.axis.DateAxis; -import org.jfree.chart.axis.NumberAxis; -import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.renderer.xy.StandardXYItemRenderer; -import org.jfree.data.time.Millisecond; -import org.jfree.data.time.TimeSeries; -import org.jfree.data.time.TimeSeriesCollection; -import org.jfree.data.xy.XYDataset; -import org.jfree.ui.RectangleInsets; - -public class StatsModel implements Cloneable { - - private static final String lock = new String("MemoryStatsModelLock"); - - private String name; - - private TimeSeries dataSet; - - public StatsModel() { - dataSet = new TimeSeries(""); - } - - BufferedImage getChart(int width, int height, ColorUIResource bgColor, ColorUIResource fgColor) { - JFreeChart chart = createChart(bgColor, fgColor); - - BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - chart.draw((Graphics2D) image.getGraphics(), new Rectangle2D.Double(0, 0, width, height), null); - - return image; - } - - public String getName() { - return name; - } - - public void setName(String name) { - dataSet.setDescription(name); - this.name = name; - } - - public void setRange(int seconds) { - dataSet.setMaximumItemCount(seconds); - } - - public void addData(long timestamp, double value) { - Millisecond millisecond = new Millisecond(new Date(timestamp)); - synchronized (lock) { - if (dataSet.getValue(millisecond) == null) { - dataSet.add(millisecond, value); - dataSet.removeAgedItems(true); - } - } - } - - @Override - protected StatsModel clone() { - - StatsModel model = new StatsModel(); - model.setName(name); - model.setRange(dataSet.getMaximumItemCount()); - - try { - model.dataSet = dataSet.createCopy(0, dataSet.getItemCount() - 1); - } catch (CloneNotSupportedException e) { - // ah... it's supported here... - e.printStackTrace(); - } - - return model; - } - - /** - * Creates a chart. - * - * @return a chart. - */ - private JFreeChart createChart(ColorUIResource bgColor, ColorUIResource fgColor) { - - XYDataset priceData = null; - synchronized (lock) { - try { - priceData = new TimeSeriesCollection(dataSet.createCopy(0, - dataSet.getItemCount() - 1)); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - } - - XYPlot plot = new XYPlot(); - - plot.setDomainGridlinesVisible(false); - plot.setDomainCrosshairVisible(false); - plot.setRangeGridlinesVisible(false); - plot.setRangeCrosshairVisible(false); - - DateAxis dateAxis = new DateAxis(); - - dateAxis.setTickLabelsVisible(false); - dateAxis.setTickMarksVisible(false); - dateAxis.setAxisLineVisible(false); - dateAxis.setNegativeArrowVisible(false); - dateAxis.setPositiveArrowVisible(false); - dateAxis.setVisible(false); - - NumberAxis numberAxis = new NumberAxis(); - numberAxis.setTickLabelsVisible(false); - numberAxis.setTickMarksVisible(false); - numberAxis.setAxisLineVisible(false); - numberAxis.setNegativeArrowVisible(false); - numberAxis.setPositiveArrowVisible(false); - numberAxis.setVisible(false); - numberAxis.setAutoRangeIncludesZero(false); - - plot.setDomainAxis(dateAxis); - plot.setRangeAxis(numberAxis); - plot.setDataset(priceData); - - plot.setInsets(new RectangleInsets(-1, -1, 0, 0)); - - plot.setRenderer(new StandardXYItemRenderer(StandardXYItemRenderer.LINES)); - plot.setBackgroundPaint(bgColor); - - JFreeChart chart = new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT, plot, false); - - plot.getRenderer().setSeriesPaint(0, fgColor); - chart.setAntiAlias(true); - chart.setBorderVisible(false); - - return chart; - } - - TimeSeries getDataSet() { - return dataSet; - } -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/SwingMemoryStatsViewProvider.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * 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.client.stats.memory; - -public class SwingMemoryStatsViewProvider implements MemoryStatsViewProvider { - - @Override - public MemoryStatsView createView() { - return new MemoryStatsViewImpl(); - } - -}
--- a/client/memory-stats-panel/src/main/java/com/redhat/thermostat/client/stats/memory/locale/LocaleResources.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * 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.client.stats.memory.locale; - -import com.redhat.thermostat.common.locale.Translate; - -public enum LocaleResources { - - VM_INFO_TAB_MEMORY, - RESOURCE_MISSING; - - public static final String RESOURCE_BUNDLE = - "com.redhat.thermostat.client.stats.memory.locale.strings"; - - public static Translate<LocaleResources> createLocalizer() { - return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); - } -}
--- a/client/memory-stats-panel/src/main/resources/com/redhat/thermostat/client/stats/memory/locale/strings.properties Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -RESOURCE_MISSING = Missing translation! -VM_INFO_TAB_MEMORY = Memory \ No newline at end of file
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/MemoryStatsControllerTest.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,269 +0,0 @@ -/* - * 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.client.stats.memory; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.isA; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import com.redhat.thermostat.common.ActionEvent; -import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.common.Timer; -import com.redhat.thermostat.common.Timer.SchedulingType; -import com.redhat.thermostat.common.TimerFactory; -import com.redhat.thermostat.common.appctx.ApplicationContext; -import com.redhat.thermostat.common.appctx.ApplicationContextUtil; -import com.redhat.thermostat.common.dao.VmMemoryStatDAO; -import com.redhat.thermostat.common.dao.VmRef; -import com.redhat.thermostat.common.model.VmMemoryStat; -import com.redhat.thermostat.common.model.VmMemoryStat.Generation; -import com.redhat.thermostat.common.model.VmMemoryStat.Space; - -public class MemoryStatsControllerTest { - - private List<Generation> generations = new ArrayList<>(); - - private VmMemoryStatDAO memoryStatDao; - private MemoryStatsView view; - private Timer timer; - - private ActionListener<MemoryStatsView.Action> viewListener; - - private MemoryStatsController controller; - - private Space canary; - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Before - public void setUp() { - timer = mock(Timer.class); - ArgumentCaptor<Runnable> actionCaptor = ArgumentCaptor.forClass(Runnable.class); - doNothing().when(timer).setAction(actionCaptor.capture()); - - TimerFactory timerFactory = mock(TimerFactory.class); - when(timerFactory.createTimer()).thenReturn(timer); - ApplicationContext.getInstance().setTimerFactory(timerFactory); - - List<VmMemoryStat> vmInfo = new ArrayList<>(); - - for (int i = 0; i < 2; i++) { - Generation generation = new Generation(); - generation.name = "fluff" + i; - generation.spaces = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Space space = new Space(); - space.name = "fluffer" + i + j; - space.used = 100; - space.capacity = 1000; - space.maxCapacity = 10000; - - generation.spaces.add(space); - } - generations.add(generation); - } - - // special payload because the others have all the same values - canary = new Space(); - canary.name = "canary"; - canary.used = 1; - canary.capacity = 2; - canary.maxCapacity = 3; - - long timestamp = 1; - int vmID = 1; - for (int i = 0; i < 5; i++) { - VmMemoryStat vmMemory = new VmMemoryStat(timestamp++, vmID, generations); - vmInfo.add(vmMemory); - } - - generations.get(0).spaces.add(canary); - - memoryStatDao = mock(VmMemoryStatDAO.class); - when(memoryStatDao.getLatestVmMemoryStats(any(VmRef.class), anyLong())).thenReturn(vmInfo); - - view = mock(MemoryStatsView.class); - MemoryStatsViewProvider viewProvider = mock(MemoryStatsViewProvider.class); - when(viewProvider.createView()).thenReturn(view); - - ArgumentCaptor<ActionListener> viewArgumentCaptor = - ArgumentCaptor.forClass(ActionListener.class); - doNothing().when(view).addActionListener(viewArgumentCaptor.capture()); - - VmRef ref = mock(VmRef.class); - - controller = new MemoryStatsController(memoryStatDao, ref, viewProvider); - - viewListener = viewArgumentCaptor.getValue(); - } - - @Test - public void testStartStopTimer() { - viewListener.actionPerformed(new ActionEvent<>(view, MemoryStatsView.Action.VISIBLE)); - - verify(timer).start(); - verify(timer).setSchedulingType(SchedulingType.FIXED_RATE); - - viewListener.actionPerformed(new ActionEvent<>(view, MemoryStatsView.Action.HIDDEN)); - - verify(timer).stop(); - } - - @Test - public void testPayloadContainSpaces() { - MemoryStatsController.VMCollector collettor = controller.getCollector(); - collettor.run(); - - Map<String, Payload> regions = controller.getRegions(); - assertEquals(5, regions.size()); - - assertTrue(regions.containsKey("fluffer00")); - assertTrue(regions.containsKey("fluffer01")); - assertTrue(regions.containsKey("fluffer10")); - assertTrue(regions.containsKey("fluffer11")); - - assertTrue(regions.containsKey("canary")); - } - - @Test - public void testValues() { - MemoryStatsController.VMCollector collettor = controller.getCollector(); - collettor.run(); - - Map<String, Payload> regions = controller.getRegions(); - - Payload payload = regions.get("fluffer00"); - assertEquals("fluffer00", payload.getName()); - assertEquals(10000, payload.getMaxCapacity(), 0); - assertEquals(1000, payload.getCapacity(), 0); - assertEquals(100, payload.getUsed(), 0); - - payload = regions.get("canary"); - assertEquals("canary", payload.getName()); - assertEquals(3, payload.getMaxCapacity(), 0); - assertEquals(2, payload.getCapacity(), 0); - assertEquals(1, payload.getUsed(), 0); - - // the value above all ensure the same scale is used - String tooltip = payload.getName() + ": used: " + payload.getUsed() + " " + - payload.getUsedUnit() + ", capacity: " + - payload.getCapacity() + " " + payload.getUsedUnit() + - ", max capacity: " + payload.getMaxCapacity() + " " + - payload.getUsedUnit(); - - assertEquals(tooltip, payload.getTooltip()); - } - - - @Test - public void testTimerFetchesMemoryDataDeltaOnly() { - ArgumentCaptor<Long> timeStampCaptor = ArgumentCaptor.forClass(Long.class); - - final long DATA_TIMESTAMP = System.currentTimeMillis() + 1000000000; - Space space = new Space(); - space.capacity = 10; - space.maxCapacity = 20; - space.used = 5; - Generation gen = new Generation(); - gen.name = "foobar"; - gen.spaces = Arrays.asList(space); - VmMemoryStat stat = new VmMemoryStat(); - stat.setTimeStamp(DATA_TIMESTAMP); - stat.setGenerations(Arrays.asList(gen)); - - when(memoryStatDao.getLatestVmMemoryStats(isA(VmRef.class), anyLong())).thenReturn(Arrays.asList(stat)); - - Runnable timerAction = controller.getCollector(); - - timerAction.run(); - timerAction.run(); - - verify(memoryStatDao, times(2)).getLatestVmMemoryStats(isA(VmRef.class), timeStampCaptor.capture()); - - long timeStamp1 = timeStampCaptor.getAllValues().get(0); - assertTimeStampIsAround(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1), timeStamp1); - - long timeStamp2 = timeStampCaptor.getAllValues().get(1); - assertTimeStampIsAround(DATA_TIMESTAMP, timeStamp2); - } - - @Test - public void testTimerFetchesMemoryDataDeltaOnlyEvenWithNoData() { - ArgumentCaptor<Long> timeStampCaptor = ArgumentCaptor.forClass(Long.class); - - Runnable timerAction = controller.getCollector(); - - timerAction.run(); - timerAction.run(); - - verify(memoryStatDao, times(2)).getLatestVmMemoryStats(isA(VmRef.class), timeStampCaptor.capture()); - - long timeStamp1 = timeStampCaptor.getAllValues().get(0); - assertTimeStampIsAround(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1), timeStamp1); - - long timeStamp2 = timeStampCaptor.getAllValues().get(1); - assertTimeStampIsAround(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1), timeStamp2); - } - - private void assertTimeStampIsAround(long expected, long actual) { - assertTrue(actual <= expected + 1000); - assertTrue(actual >= expected - 1000); - } - - @After - public void tearDown() { - ApplicationContextUtil.resetApplicationContext(); - } -}
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/MemoryStatsPanelActivatorTest.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * 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.client.stats.memory; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.redhat.thermostat.test.StubBundleContext; - -public class MemoryStatsPanelActivatorTest { - - @Test - public void verifyStartRegistersViewProvider() throws Exception { - StubBundleContext ctx = new StubBundleContext(); - MemoryStatsPanelActivator activator = new MemoryStatsPanelActivator(); - activator.start(ctx); - assertTrue(ctx.isServiceRegistered(MemoryStatsViewProvider.class.getName(), SwingMemoryStatsViewProvider.class)); - assertEquals(1, ctx.getAllServices().size()); - } -}
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/PayloadTest.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * 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.client.stats.memory; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.redhat.thermostat.common.utils.DisplayableValues.Scale; - -public class PayloadTest { - - @Test - public void testClone() { - - StatsModel model = new StatsModel(); - model.setName("fluffModel"); - model.setRange(100); - model.addData(500, 2.0); - model.addData(501, 2.1); - - Payload source = new Payload(); - source.setCapacity(10.0); - source.setName("fluff"); - source.setCapacityUnit(Scale.GiB); - source.setMaxCapacity(100.0); - source.setMaxUsed(5.0); - source.setUsed(3.0); - source.setUsedUnit(Scale.MiB); - source.setModel(model); - source.setTooltip("fluffTooltip"); - - Payload cloned = source.clone(); - assertNotSame(cloned, source); - - assertEquals(source.getName(), cloned.getName()); - assertEquals(source.getCapacity(), cloned.getCapacity(), 0); - assertEquals(source.getCapacityUnit(), cloned.getCapacityUnit()); - assertEquals(source.getMaxCapacity(), cloned.getMaxCapacity(), 0); - assertEquals(source.getMaxUsed(), cloned.getMaxUsed(), 0); - assertEquals(source.getTooltip(), cloned.getTooltip()); - assertEquals(source.getUsed(), cloned.getUsed(), 0); - assertEquals(source.getUsedUnit(), cloned.getUsedUnit()); - assertNotSame(source.getModel(), cloned.getModel()); - - assertEquals(source.getModel().getName(), cloned.getModel().getName()); - } -}
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/RangeModelTest.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * 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.client.stats.memory; - -import static org.junit.Assert.*; -import junit.framework.Assert; - -import org.junit.Test; - -public class RangeModelTest { - - @Test - public void testSameRange() { - RangeModel model = new RangeModel(); - - model.setMaximum(10); - model.setMinimum(0); - model.setValue(5); - - model.setMaxNormalized(10); - model.setMinNormalized(0); - - - Assert.assertEquals((int) model.getValue(), model.getValueNormalized()); - } - - @Test - public void testDoubleRange() { - RangeModel model = new RangeModel(); - - model.setMaximum(10); - model.setMinimum(0); - model.setValue(5); - - model.setMaxNormalized(20); - model.setMinNormalized(0); - - - Assert.assertEquals(10, model.getValueNormalized()); - } - - @Test - public void testRanges() { - RangeModel model = new RangeModel(); - - model.setMaximum(10); - model.setMinimum(0); - model.setValue(5); - - model.setMaxNormalized(40); - model.setMinNormalized(0); - - Assert.assertEquals(20, model.getValueNormalized()); - - model.setMaxNormalized(60); - model.setMinNormalized(0); - - Assert.assertEquals(30, model.getValueNormalized()); - - model.setMaxNormalized(200); - model.setMinNormalized(100); - - Assert.assertEquals(150, model.getValueNormalized()); - - model.setMaximum(100); - model.setMinimum(0); - model.setValue(50); - - model.setMaxNormalized(1); - model.setMinNormalized(0); - - Assert.assertEquals(1, model.getValueNormalized()); - - model.setValue(49); - Assert.assertEquals(0, model.getValueNormalized()); - - model.setMaximum(1.0); - model.setMinimum(0.0); - model.setValue(0.5); - - model.setMaxNormalized(100); - model.setMinNormalized(0); - - Assert.assertEquals(50, model.getValueNormalized()); - - model.setValue(0.72); - Assert.assertEquals(72, model.getValueNormalized()); - } -}
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/StatsModelTest.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * 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.client.stats.memory; - -import static org.junit.Assert.*; - -import org.jfree.data.time.TimeSeries; -import org.junit.Test; - -public class StatsModelTest { - - @Test - public void testClone() { - - StatsModel source = new StatsModel(); - source.setName("fluffModel"); - source.setRange(100); - source.addData(500, 2.0); - source.addData(501, 2.1); - - StatsModel cloned = source.clone(); - - assertNotSame(cloned, source); - - assertEquals(source.getName(), cloned.getName()); - - assertNotSame(cloned.getDataSet(), source.getDataSet()); - - for (Object series : cloned.getDataSet().getItems()) { - assertTrue(source.getDataSet().getItems().contains(series)); - } - - assertEquals(cloned.getDataSet().getItemCount(), - source.getDataSet().getItemCount()); - } - -}
--- a/client/memory-stats-panel/src/test/java/com/redhat/thermostat/client/stats/memory/locale/TranslateTest.java Tue Oct 23 11:21:50 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * 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.client.stats.memory.locale; - -import java.io.IOException; -import java.util.Locale; -import java.util.Properties; - -import junit.framework.Assert; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.redhat.thermostat.common.locale.Translate; - -public class TranslateTest { - - private Locale lang; - - @Before - public void setUp() { - this.lang = Locale.getDefault(); - Locale.setDefault(Locale.US); - } - - @After - public void tearDown() { - Locale.setDefault(lang); - } - - @Test - public void verifyTranslationsAreThere() throws IOException { - - String stringsResource = "/" + LocaleResources.RESOURCE_BUNDLE.replace(".", "/") + ".properties"; - - Properties props = new Properties(); - props.load(getClass().getResourceAsStream(stringsResource)); - - Assert.assertEquals(LocaleResources.values().length, props.values().size()); - Translate<LocaleResources> t = LocaleResources.createLocalizer(); - Assert.assertEquals("Missing translation!", t.localize(LocaleResources.RESOURCE_MISSING)); - Assert.assertEquals("Memory", t.localize(LocaleResources.VM_INFO_TAB_MEMORY)); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/pom.xml Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>thermostat-osgi-memory-stats-panel</artifactId> + <groupId>com.redhat.thermostat</groupId> + <version>0.5.0-SNAPSHOT</version> + </parent> + <artifactId>thermostat-osgi-memory-stats-panel-swing</artifactId> + <packaging>bundle</packaging> + <name>Thermostat Client VM Memory Monitor Swing plugin</name> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Private-Package> + com.redhat.thermostat.client.stats.memory.swing + </Private-Package> + <Bundle-Activator>com.redhat.thermostat.client.stats.memory.swing.MemoryStatsPanelActivator</Bundle-Activator> + <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor> + <Bundle-SymbolicName>com.redhat.thermostat.client.stats.memory.swing</Bundle-SymbolicName> + <!-- Do not autogenerate uses clauses in Manifests --> + <_nouses>true</_nouses> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easytesting</groupId> + <artifactId>fest-swing</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>net.java.openjdk.cacio</groupId> + <artifactId>cacio-tta</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jfree</groupId> + <artifactId>jfreechart</artifactId> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-osgi-memory-stats-panel-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-client-swing</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryGraphPanel.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,85 @@ +/* + * 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.client.stats.memory.swing; + +import java.awt.Dimension; +import java.beans.Transient; + +import javax.swing.BoxLayout; +import javax.swing.JPanel; + +import com.redhat.thermostat.client.stats.memory.core.MemoryMeter; +import com.redhat.thermostat.client.stats.memory.core.Payload; + +@SuppressWarnings("serial") +class MemoryGraphPanel extends JPanel { + + private MemoryMeter meter; + + /** + * Create the panel. + */ + public MemoryGraphPanel() { + setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); + meter = new MemoryMeter(); + add(meter); + } + + public void setMemoryGraphProperties(Payload region) { + + meter.getPrimaryModel().setMinimum(0); + meter.getPrimaryModel().setMaximum(region.getMaxUsed()); + meter.getPrimaryModel().setValue(region.getUsed()); + + meter.getSecondaryModel().setMinimum(0); + meter.getSecondaryModel().setMaximum(region.getMaxCapacity()); + meter.getSecondaryModel().setValue(region.getCapacity()); + + meter.setToolTipText(region.getTooltip()); + + meter.setPrimaryScaleUnit(region.getUsedUnit().toString()); + meter.setSecondayScaleUnit(region.getCapacityUnit().toString()); + + meter.setStats(region.getModel()); + } + + @Override + @Transient + public Dimension getPreferredSize() { + return meter.getPreferredSize(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsPanelActivator.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,91 @@ +/* + * 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.client.stats.memory.swing; + +import java.util.Map; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.client.core.VmInformationService; +import com.redhat.thermostat.client.osgi.service.ApplicationService; +import com.redhat.thermostat.client.stats.memory.core.MemoryStatsService; +import com.redhat.thermostat.client.stats.memory.core.MemoryStatsViewProvider; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.MultipleServiceTracker.Action; +import com.redhat.thermostat.common.dao.VmMemoryStatDAO; + +public class MemoryStatsPanelActivator implements BundleActivator { + + private MultipleServiceTracker tracker; + private ServiceRegistration memoryStatRegistration; + + @Override + public void start(final BundleContext context) throws Exception { + MemoryStatsViewProvider provider = new SwingMemoryStatsViewProvider(); + context.registerService(MemoryStatsViewProvider.class.getName(), provider, null); + + Class<?>[] deps = new Class<?>[] { + ApplicationService.class, + VmMemoryStatDAO.class, + }; + + tracker = new MultipleServiceTracker(context, deps, new Action() { + + @Override + public void dependenciesUnavailable() { + memoryStatRegistration.unregister(); + memoryStatRegistration = null; + } + + @Override + public void dependenciesAvailable(Map<String, Object> services) { + VmMemoryStatDAO memoryStatDao = (VmMemoryStatDAO) services.get(VmMemoryStatDAO.class.getName()); + MemoryStatsService impl = new MemoryStatsService(memoryStatDao); + memoryStatRegistration = context.registerService(VmInformationService.class.getName(), impl , null); + } + }); + tracker.open(); + + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsViewImpl.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,154 @@ +/* + * 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.client.stats.memory.swing; + +import java.awt.Component; +import java.awt.Dimension; +import java.beans.Transient; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.stats.memory.core.MemoryStatsView; +import com.redhat.thermostat.client.stats.memory.core.Payload; +import com.redhat.thermostat.client.swing.SwingComponent; +import com.redhat.thermostat.client.swing.components.HeaderPanel; +import com.redhat.thermostat.client.ui.ComponentVisibleListener; + +public class MemoryStatsViewImpl extends MemoryStatsView implements SwingComponent { + + private static final long REPAINT_DELAY = 500; + private long lastRepaint; + + private HeaderPanel visiblePanel; + private JPanel realPanel; + + private final Map<String, MemoryGraphPanel> regions; + + private Dimension preferredSize; + + public MemoryStatsViewImpl() { + super(); + visiblePanel = new HeaderPanel(); + regions = new HashMap<>(); + + preferredSize = new Dimension(0, 0); + + visiblePanel.setHeader("Memory Regions"); + + visiblePanel.addHierarchyListener(new ComponentVisibleListener() { + @Override + public void componentShown(Component component) { + notifier.fireAction(Action.VISIBLE); + } + + @Override + public void componentHidden(Component component) { + notifier.fireAction(Action.HIDDEN); + } + }); + + realPanel = new JPanel(); + realPanel.setLayout(new BoxLayout(realPanel, BoxLayout.Y_AXIS)); + visiblePanel.setContent(realPanel); + } + + @Transient + public Dimension getPreferredSize() { + return new Dimension(preferredSize); + } + + @Override + public void updateRegion(final Payload region) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + MemoryGraphPanel memoryGraphPanel = regions.get(region.getName()); + memoryGraphPanel.setMemoryGraphProperties(region); + } + }); + } + + @Override + public void addRegion(final Payload region) { + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + MemoryGraphPanel memoryGraphPanel = new MemoryGraphPanel(); + + realPanel.add(memoryGraphPanel); + realPanel.add(Box.createRigidArea(new Dimension(5,5))); + regions.put(region.getName(), memoryGraphPanel); + + // components are stacked up vertically in this panel + Dimension memoryGraphPanelMinSize = memoryGraphPanel.getMinimumSize(); + preferredSize.height += memoryGraphPanelMinSize.height + 5; + if (preferredSize.width < (memoryGraphPanelMinSize.width + 5)) { + preferredSize.width = memoryGraphPanelMinSize.width + 5; + } + + updateRegion(region); + realPanel.revalidate(); + } + }); + } + + @Override + public Component getUiComponent() { + return visiblePanel; + } + + @Override + public void requestRepaint() { + // really only repaint every REPAINT_DELAY milliseconds + long now = System.currentTimeMillis(); + if (now - lastRepaint > REPAINT_DELAY) { + visiblePanel.repaint(); + lastRepaint = System.currentTimeMillis(); + } + } + + public BasicView getView() { + return this; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/src/main/java/com/redhat/thermostat/client/stats/memory/swing/SwingMemoryStatsViewProvider.java Tue Oct 23 11:22:31 2012 -0400 @@ -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.client.stats.memory.swing; + +import com.redhat.thermostat.client.stats.memory.core.MemoryStatsView; +import com.redhat.thermostat.client.stats.memory.core.MemoryStatsViewProvider; + +public class SwingMemoryStatsViewProvider implements MemoryStatsViewProvider { + + @Override + public MemoryStatsView createView() { + return new MemoryStatsViewImpl(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/src/main/resources/com/redhat/thermostat/client/stats/memory/locale/strings.properties Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,2 @@ +RESOURCE_MISSING = Missing translation! +VM_INFO_TAB_MEMORY = Memory \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/memory-stats-panel/swing/src/test/java/com/redhat/thermostat/client/stats/memory/swing/MemoryStatsPanelActivatorTest.java Tue Oct 23 11:22:31 2012 -0400 @@ -0,0 +1,57 @@ +/* + * 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.client.stats.memory.swing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.redhat.thermostat.client.stats.memory.core.MemoryStatsViewProvider; +import com.redhat.thermostat.test.StubBundleContext; + +public class MemoryStatsPanelActivatorTest { + + @Test + public void verifyStartRegistersViewProvider() throws Exception { + StubBundleContext ctx = new StubBundleContext(); + MemoryStatsPanelActivator activator = new MemoryStatsPanelActivator(); + activator.start(ctx); + assertTrue(ctx.isServiceRegistered(MemoryStatsViewProvider.class.getName(), SwingMemoryStatsViewProvider.class)); + assertEquals(1, ctx.getAllServices().size()); + } +}