Mercurial > hg > release > thermostat-0.4
changeset 586:5786978e31e0
Add icons for host in host/vm tree
Reviewed-by: neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-August/003034.html
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/HostIconDecorator.java Tue Sep 04 16:05:14 2012 -0400 @@ -0,0 +1,105 @@ +/* + * 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.internal; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +import com.redhat.thermostat.client.osgi.service.HostDecorator; +import com.redhat.thermostat.client.osgi.service.HostFilter; +import com.redhat.thermostat.client.ui.Decorator; +import com.redhat.thermostat.client.ui.IconDescriptor; +import com.redhat.thermostat.client.ui.IconResource; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.utils.StreamUtils; + +public class HostIconDecorator implements HostDecorator { + + private final HostFilter anyHost = new AnyHostMatcher(); + + @Override + public Decorator getDecorator() { + return new IconDecorator(); + } + + @Override + public HostFilter getFilter() { + return anyHost; + } + + private static class IconDecorator implements Decorator { + + private final IconDescriptor icon; + + public IconDecorator() { + IconDescriptor icon = null; + try { + InputStream in = new FileInputStream(IconResource.HOST.getPath()); + icon = new IconDescriptor(ByteBuffer.wrap(StreamUtils.readAll(in))); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + this.icon = icon; + } + + @Override + public String getLabel(String originalLabel) { + return originalLabel; + } + + @Override + public IconDescriptor getIconDescriptor() { + return icon; + } + + @Override + public Quadrant getQuadrant() { + return Quadrant.MAIN; + } + + } + + private static class AnyHostMatcher implements HostFilter { + @Override + public boolean matches(HostRef toMatch) { + return true; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/HostTreeDecoratorRegistry.java Tue Sep 04 16:05:14 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.internal; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.InvalidSyntaxException; + +import com.redhat.thermostat.client.osgi.service.HostDecorator; + +class HostTreeDecoratorRegistry extends ThermostatExtensionRegistry<HostDecorator> { + + private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + HostDecorator.class.getName() + ")"; + + public HostTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException { + super(context, FILTER, HostDecorator.class); + } +}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java Tue Sep 04 21:19:29 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java Tue Sep 04 16:05:14 2012 -0400 @@ -94,6 +94,7 @@ private final CopyOnWriteArrayList<HostFilter> hostFilters = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList<VmFilter> vmFilters = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList<HostDecorator> hostTreeDecorators = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList<VmDecorator> vmTreeDecorators = new CopyOnWriteArrayList<>(); private Timer backgroundUpdater; @@ -140,8 +141,10 @@ private ActionListener<ThermostatExtensionRegistry.Action> hostFilterListener = new UpdateListAndTree<>(HostFilter.class, hostFilters); private ActionListener<ThermostatExtensionRegistry.Action> vmFilterListener = new UpdateListAndTree<>(VmFilter.class, vmFilters); - private VMTreeDecoratorRegistry decoratorRegistry; + private HostTreeDecoratorRegistry hostDecoratorRegistry; + private VMTreeDecoratorRegistry vmDecoratorRegistry; + private ActionListener<ThermostatExtensionRegistry.Action> hostDecoratorListener = new UpdateListAndTree<>(HostDecorator.class, hostTreeDecorators); private ActionListener<ThermostatExtensionRegistry.Action> vmDecoratorListener = new UpdateListAndTree<>(VmDecorator.class, vmTreeDecorators); private VMInformationRegistry vmInfoRegistry; @@ -164,7 +167,8 @@ try { vmFilterRegistry = registryFactory.createVmFilterRegistry(); hostFilterRegistry = registryFactory.createHostFilterRegistry(); - decoratorRegistry = registryFactory.createVMTreeDecoratorRegistry(); + hostDecoratorRegistry = registryFactory.createHostTreeDecoratorRegistry(); + vmDecoratorRegistry = registryFactory.createVMTreeDecoratorRegistry(); menuRegistry = registryFactory.createMenuRegistry(); vmInfoRegistry = registryFactory.createVMInformationRegistry(); @@ -193,20 +197,7 @@ updateView(); - menuRegistry.addActionListener(menuListener); - menuRegistry.start(); - - hostFilterRegistry.addActionListener(hostFilterListener); - hostFilterRegistry.start(); - - vmFilterRegistry.addActionListener(vmFilterListener); - vmFilterRegistry.start(); - - decoratorRegistry.addActionListener(vmDecoratorListener); - decoratorRegistry.start(); - - vmInfoRegistry.addActionListener(vmInfoRegistryListener); - vmInfoRegistry.start(); + installListenersAndStartRegistries(); } /** @@ -261,7 +252,7 @@ public void doUpdateTreeAsync() { HostsVMsLoader loader = new DefaultHostsVMsLoader(hostsDAO, vmsDAO, !showHistory); - view.updateTree(hostFilters, vmFilters, Collections.<HostDecorator>emptyList(), vmTreeDecorators, loader); + view.updateTree(hostFilters, vmFilters, hostTreeDecorators, vmTreeDecorators, loader); } private void initView(MainView mainView) { @@ -315,13 +306,57 @@ } private void shutdownApplication() { + uninstallListenersAndStopRegistries(); + + view.hideMainWindow(); + ApplicationContext.getInstance().getTimerFactory().shutdown(); + shutdownOSGiFramework(); + } + + private void installListenersAndStartRegistries() { + menuRegistry.addActionListener(menuListener); + menuRegistry.start(); + + hostFilterRegistry.addActionListener(hostFilterListener); + hostFilterRegistry.start(); + + vmFilterRegistry.addActionListener(vmFilterListener); + vmFilterRegistry.start(); + + hostDecoratorRegistry.addActionListener(hostDecoratorListener); + hostDecoratorRegistry.start(); + + vmDecoratorRegistry.addActionListener(vmDecoratorListener); + vmDecoratorRegistry.start(); + + vmInfoRegistry.addActionListener(vmInfoRegistryListener); + vmInfoRegistry.start(); + } + + private void uninstallListenersAndStopRegistries() { menuRegistry.removeActionListener(menuListener); menuListener = null; menuRegistry.stop(); - view.hideMainWindow(); - ApplicationContext.getInstance().getTimerFactory().shutdown(); - shutdownOSGiFramework(); + hostFilterRegistry.removeActionListener(hostFilterListener); + hostFilterListener = null; + hostFilterRegistry.stop(); + + vmFilterRegistry.removeActionListener(vmFilterListener); + vmFilterListener = null; + vmFilterRegistry.stop(); + + hostDecoratorRegistry.removeActionListener(hostDecoratorListener); + hostDecoratorListener = null; + hostDecoratorRegistry.stop(); + + vmDecoratorRegistry.removeActionListener(vmDecoratorListener); + vmDecoratorListener = null; + vmDecoratorRegistry.stop(); + + vmInfoRegistry.removeActionListener(vmInfoRegistryListener); + vmInfoRegistryListener = null; + vmInfoRegistry.stop(); } private void shutdownOSGiFramework() { @@ -426,7 +461,7 @@ Object payload = actionEvent.getPayload(); if (!extensionClass.isInstance(payload)) { - throw new IllegalArgumentException("invalid payload type"); + throw new IllegalArgumentException("unexpected payload type. expected a " + extensionClass.getName() + " but got " + payload.getClass().getName()); } T filter = (T) payload;
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java Tue Sep 04 21:19:29 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java Tue Sep 04 16:05:14 2012 -0400 @@ -45,6 +45,10 @@ RegistryFactory(BundleContext context) { this.context = context; } + + HostTreeDecoratorRegistry createHostTreeDecoratorRegistry() throws InvalidSyntaxException { + return new HostTreeDecoratorRegistry(context); + } VMTreeDecoratorRegistry createVMTreeDecoratorRegistry() throws InvalidSyntaxException { return new VMTreeDecoratorRegistry(context);
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java Tue Sep 04 21:19:29 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java Tue Sep 04 16:05:14 2012 -0400 @@ -44,8 +44,10 @@ import org.osgi.util.tracker.ServiceTracker; import com.redhat.thermostat.client.internal.GUIClientCommand; +import com.redhat.thermostat.client.internal.HostIconDecorator; import com.redhat.thermostat.client.internal.Main; import com.redhat.thermostat.client.internal.UiFacadeFactoryImpl; +import com.redhat.thermostat.client.osgi.service.HostDecorator; import com.redhat.thermostat.client.ui.UiFacadeFactory; import com.redhat.thermostat.common.cli.CommandRegistry; import com.redhat.thermostat.common.cli.CommandRegistryImpl; @@ -61,6 +63,9 @@ @Override public void start(final BundleContext context) throws Exception { + HostDecorator hostDecorator = new HostIconDecorator(); + context.registerService(HostDecorator.class.getName(), hostDecorator, null); + ServiceTracker tracker = new ServiceTracker(context, Keyring.class.getName(), null) { @Override public Object addingService(ServiceReference reference) {
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/IconResource.java Tue Sep 04 21:19:29 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/IconResource.java Tue Sep 04 16:05:14 2012 -0400 @@ -51,6 +51,7 @@ public static final IconResource MISSING_ICON = null; public static final IconResource JAVA_APPLICATION = new IconResource("duke.png"); + public static final IconResource HOST = new IconResource(ICON_PREFIX + "16x16/devices/computer.png"); public static final IconResource ERROR = new IconResource(ICON_PREFIX + "48x48/status/dialog-error.png"); public static final IconResource QUESTION = new IconResource(ICON_PREFIX + "48x48/status/dialog-question.png");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/HostIconDecoratorTest.java Tue Sep 04 16:05:14 2012 -0400 @@ -0,0 +1,89 @@ +/* + * 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.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import org.junit.Test; + +import com.redhat.thermostat.client.osgi.service.HostFilter; +import com.redhat.thermostat.client.ui.Decorator; +import com.redhat.thermostat.common.dao.HostRef; + +public class HostIconDecoratorTest { + + @Test + public void verifyFilter() { + HostIconDecorator decorator = new HostIconDecorator(); + + HostFilter filter = decorator.getFilter(); + HostRef aHost = mock(HostRef.class); + + assertTrue(filter.matches(aHost)); + } + + @Test + public void verifyHostDecoratorDoesNotModifyLabel() { + HostIconDecorator iconDecorator = new HostIconDecorator(); + + Decorator decorator = iconDecorator.getDecorator(); + + String INPUT = "testfoobarbaz"; + + assertEquals(INPUT, decorator.getLabel(INPUT)); + } + + @Test + public void verifyHostDecoratorHasAnIcon() throws IOException { + HostIconDecorator iconDecorator = new HostIconDecorator(); + + Decorator decorator = iconDecorator.getDecorator(); + + BufferedImage icon = ImageIO.read(new ByteArrayInputStream(decorator.getIconDescriptor().getData().array())); + + assertNotNull(icon); + } +}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java Tue Sep 04 21:19:29 2012 +0200 +++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java Tue Sep 04 16:05:14 2012 -0400 @@ -112,7 +112,8 @@ private HostFilterRegistry hostFilterRegistry; private VmFilterRegistry vmFilterRegistry; - private VMTreeDecoratorRegistry decorators; + private HostTreeDecoratorRegistry hostDecoratorRegistry; + private VMTreeDecoratorRegistry vmDecoratorRegistry; private VMInformationRegistry vmInfoRegistry; private MenuRegistry menus; @@ -152,12 +153,14 @@ RegistryFactory registryFactory = mock(RegistryFactory.class); hostFilterRegistry = mock(HostFilterRegistry.class); vmFilterRegistry = mock(VmFilterRegistry.class); - decorators = mock(VMTreeDecoratorRegistry.class); + hostDecoratorRegistry = mock(HostTreeDecoratorRegistry.class); + vmDecoratorRegistry = mock(VMTreeDecoratorRegistry.class); vmInfoRegistry = mock(VMInformationRegistry.class); menus = mock(MenuRegistry.class); when(registryFactory.createMenuRegistry()).thenReturn(menus); - when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(decorators); + when(registryFactory.createHostTreeDecoratorRegistry()).thenReturn(hostDecoratorRegistry); + when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(vmDecoratorRegistry); when(registryFactory.createHostFilterRegistry()).thenReturn(hostFilterRegistry); when(registryFactory.createVmFilterRegistry()).thenReturn(vmFilterRegistry); when(registryFactory.createVMInformationRegistry()).thenReturn(vmInfoRegistry); @@ -169,7 +172,7 @@ doNothing().when(vmFilterRegistry).addActionListener(grabVmFiltersListener.capture()); ArgumentCaptor<ActionListener> grabDecoratorsListener = ArgumentCaptor.forClass(ActionListener.class); - doNothing().when(decorators).addActionListener(grabDecoratorsListener.capture()); + doNothing().when(vmDecoratorRegistry).addActionListener(grabDecoratorsListener.capture()); ArgumentCaptor<ActionListener> grabInfoRegistry = ArgumentCaptor.forClass(ActionListener.class); doNothing().when(vmInfoRegistry).addActionListener(grabInfoRegistry.capture()); @@ -242,7 +245,7 @@ assertEquals(0, currentDecoratros.size()); ActionEvent<ThermostatExtensionRegistry.Action> event = - new ActionEvent<ThermostatExtensionRegistry.Action>(decorators, + new ActionEvent<ThermostatExtensionRegistry.Action>(vmDecoratorRegistry, ThermostatExtensionRegistry.Action.SERVICE_ADDED); VmDecorator payload = mock(VmDecorator.class);
--- a/common/core/src/main/java/com/redhat/thermostat/common/utils/StreamUtils.java Tue Sep 04 21:19:29 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/utils/StreamUtils.java Tue Sep 04 16:05:14 2012 -0400 @@ -38,7 +38,9 @@ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; public class StreamUtils { @@ -52,4 +54,16 @@ } out.flush(); } + + public static byte[] readAll(InputStream in) throws IOException { + final int TEMPORARY_BUFFER_SIZE = 1024; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[TEMPORARY_BUFFER_SIZE]; + int read; + while ((read = in.read(buffer)) != -1) { + baos.write(buffer, 0, read); + } + + return baos.toByteArray(); + } }
--- a/common/core/src/test/java/com/redhat/thermostat/common/utils/StreamUtilsTest.java Tue Sep 04 21:19:29 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/utils/StreamUtilsTest.java Tue Sep 04 16:05:14 2012 -0400 @@ -44,6 +44,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; +import java.util.Random; import org.junit.Test; @@ -60,4 +61,16 @@ assertArrayEquals(text.getBytes(Charset.forName("UTF-8")), bos.toByteArray()); } + + @Test + public void testReadAll() throws IOException { + Random r = new Random(); + final int ONE_MEGABYTE = 1024 * 1024; + byte[] inputData = new byte[ONE_MEGABYTE]; + r.nextBytes(inputData); + + byte[] read = StreamUtils.readAll(new ByteArrayInputStream(inputData)); + + assertArrayEquals(inputData, read); + } }