changeset 814:84e6878eb77e

Add priority to InformationServices to order views This commit adds a getPriority method to the InformationService interface. The InformationServiceControllers then use this information to sort their services. Then they add child views in the order determined by the priorities. This ensures the views are added in a predetermined order. Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-November/004329.html
author Elliott Baron <ebaron@redhat.com>
date Mon, 03 Dec 2012 15:31:44 -0500
parents 48fdf038ff96
children 5917cd87fdb4
files client/core/pom.xml client/core/src/main/java/com/redhat/thermostat/client/core/HostInformationService.java client/core/src/main/java/com/redhat/thermostat/client/core/InformationService.java client/core/src/main/java/com/redhat/thermostat/client/core/VmInformationService.java client/core/src/main/java/com/redhat/thermostat/client/core/internal/InformationServiceComparator.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java client/core/src/main/java/com/redhat/thermostat/client/ui/UiFacadeFactory.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java client/core/src/test/java/com/redhat/thermostat/client/core/internal/InformationServiceComparatorTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/HostInformationControllerTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/VmInformationControllerTest.java client/heapdumper/core/src/main/java/com/redhat/thermostat/client/heap/HeapDumperService.java client/heapdumper/core/src/main/resources/com/redhat/thermostat/client/heap/strings.properties client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuService.java host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryService.java host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewService.java thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadInformationService.java vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/VmClassStatService.java vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuService.java vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewService.java
diffstat 23 files changed, 532 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/pom.xml	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/pom.xml	Mon Dec 03 15:31:44 2012 -0500
@@ -121,6 +121,9 @@
               com.redhat.thermostat.client.core.controllers,
               com.redhat.thermostat.client.core.views
             </Export-Package>
+            <Private-Package>
+              com.redhat.thermostat.client.core.internal
+            </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
           </instructions>
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/HostInformationService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/HostInformationService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -41,7 +41,6 @@
 
 public interface HostInformationService extends InformationService {
 
-    @Override
     public HostFilter getFilter();
 
     public HostInformationServiceController getInformationServiceController(HostRef ref);
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/InformationService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/InformationService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -42,7 +42,55 @@
  *
  */
 public interface InformationService {
+    
+    /**
+     * Priority group for services that provide generic overview information
+     * about a Host or VM.
+     */
+    public static final int PRIORITY_DEFAULT_GROUP = 0;
+    /**
+     * Priority group for services that provide information about a Host
+     * or VM's CPU usage.
+     */
+    public static final int PRIORITY_CPU_GROUP = 100;
+    /**
+     * Priority group for services that provide information about a Host
+     * or VM's memory usage.
+     */
+    public static final int PRIORITY_MEMORY_GROUP = 200;
+    /**
+     * Priority group for services that provide information about a Host
+     * or VM's network usage.
+     */
+    public static final int PRIORITY_NETWORK_GROUP = 300;
+    /**
+     * Priority group for services that provide information about a Host
+     * or VM's I/O usage.
+     */
+    public static final int PRIORITY_IO_GROUP = 400;
+    /**
+     * Priority group for services that provide information about a Host
+     * or VM's threads.
+     */
+    public static final int PRIORITY_THREAD_GROUP = 500;
+    /**
+     * Priority group for user-defined services. This should always be
+     * the last priority group.
+     */
+    public static final int PRIORITY_USER_GROUP = 5000;
 
-    Filter getFilter();
+    /**
+     * Defines a priority to be used for assigning an order to
+     * InformationServices. A service with a lower-valued priority will
+     * be processed before a service of a higher-valued priority. This
+     * ordering is used, for example, to sort views in a client's UI.
+     * 
+     * The priority value should be offset from one of the provided
+     * constants in this class. Such as {@link #PRIORITY_DEFAULT_GROUP}.
+     * @return the priority value
+     */
+    public int getPriority();
+
+    public Filter getFilter();
 
 }
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/VmInformationService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/VmInformationService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -41,7 +41,6 @@
 
 public interface VmInformationService extends InformationService {
 
-    @Override
     public VmFilter getFilter();
 
     public VmInformationServiceController getInformationServiceController(VmRef ref);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/internal/InformationServiceComparator.java	Mon Dec 03 15:31:44 2012 -0500
@@ -0,0 +1,63 @@
+/*
+ * 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.core.internal;
+
+import java.util.Comparator;
+
+import com.redhat.thermostat.client.core.InformationService;
+
+public class InformationServiceComparator<T extends InformationService>
+        implements Comparator<T> {
+
+    @Override
+    public int compare(T o1, T o2) {
+        int result = o1.getPriority() - o2.getPriority();
+        // Break ties using class name
+        if (result == 0) {
+            result = getName(o1).compareTo(getName(o2));
+        }
+        return result;
+    }
+    
+    /*
+     * Extracted for testing purposes.
+     */
+    String getName(T object) {
+        return object.getClass().getName();
+    }
+
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java	Mon Dec 03 15:31:44 2012 -0500
@@ -36,10 +36,12 @@
 
 package com.redhat.thermostat.client.ui;
 
-import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 import com.redhat.thermostat.client.core.HostInformationService;
 import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+import com.redhat.thermostat.client.core.internal.InformationServiceComparator;
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.HostInformationView;
 import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
@@ -52,7 +54,8 @@
     public HostInformationController(UiFacadeFactory uiFacadeFactory, HostRef ref, HostInformationViewProvider provider) {
         view = provider.createView();
 
-        Collection<HostInformationService> hostInfoServices = uiFacadeFactory.getHostInformationServices();
+        List<HostInformationService> hostInfoServices = uiFacadeFactory.getHostInformationServices();
+        Collections.sort(hostInfoServices, new InformationServiceComparator<HostInformationService>());
         for (HostInformationService hostInfoService : hostInfoServices) {
             if (hostInfoService.getFilter().matches(ref)) {
                 HostInformationServiceController ctrl = hostInfoService.getInformationServiceController(ref);
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/UiFacadeFactory.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/UiFacadeFactory.java	Mon Dec 03 15:31:44 2012 -0500
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.client.ui;
 
 import java.util.Collection;
+import java.util.List;
 
 import com.redhat.thermostat.client.core.HostInformationService;
 import com.redhat.thermostat.client.core.VmInformationService;
@@ -58,7 +59,7 @@
 
     public HostInformationController getHostController(HostRef ref);
     
-    Collection<HostInformationService> getHostInformationServices();
+    List<HostInformationService> getHostInformationServices();
 
     void addHostInformationService(HostInformationService hostInfoService);
 
@@ -66,7 +67,7 @@
 
     public VmInformationController getVmController(VmRef ref);
 
-    Collection<VmInformationService> getVmInformationServices();
+    List<VmInformationService> getVmInformationServices();
 
     void addVmInformationService(VmInformationService vmInfoService);
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Mon Dec 03 15:31:44 2012 -0500
@@ -36,10 +36,12 @@
 
 package com.redhat.thermostat.client.ui;
 
-import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 import com.redhat.thermostat.client.core.VmInformationService;
 import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.core.internal.InformationServiceComparator;
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.VmInformationView;
 import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
@@ -57,7 +59,8 @@
     VmInformationController(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, VmRef vmRef, VmInformationViewProvider provider) {
         view = provider.createView();
 
-        Collection<VmInformationService> vmInfoServices = uiFacadeFactory.getVmInformationServices();
+        List<VmInformationService> vmInfoServices = uiFacadeFactory.getVmInformationServices();
+        Collections.sort(vmInfoServices, new InformationServiceComparator<VmInformationService>());
         for (VmInformationService vmInfoService : vmInfoServices) {
             if (vmInfoService.getFilter().matches(vmRef)) {
                 VmInformationServiceController ctrl = vmInfoService.getInformationServiceController(vmRef);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/core/internal/InformationServiceComparatorTest.java	Mon Dec 03 15:31:44 2012 -0500
@@ -0,0 +1,99 @@
+/*
+ * 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.core.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.InformationService;
+
+public class InformationServiceComparatorTest {
+
+    @Test
+    public void testServiceOrderTie() {
+        int[] priorities = { 45, 20, 0, 90, 20 };
+
+        final List<InformationService> services = mockServices(priorities);
+        
+        // Override the getName method to give predetermined class names to
+        // the services with equal priority
+        InformationServiceComparator<InformationService> comparator = new InformationServiceComparator<InformationService>() {
+            @Override
+            String getName(InformationService object) {
+                String result;
+                if (object.equals(services.get(1))) {
+                    result = "TheirService";
+                }
+                else if (object.equals(services.get(4))) {
+                    result = "MyService";
+                }
+                else {
+                    result = super.getName(object); 
+                }
+                return result;
+            }
+        };
+        
+        List<InformationService> sorted = new ArrayList<>(services);
+        Collections.sort(sorted, comparator);
+        
+        // Ensure MyService comes before TheirService
+        assertEquals(services.get(2), sorted.get(0));
+        assertEquals(services.get(4), sorted.get(1));
+        assertEquals(services.get(1), sorted.get(2));
+        assertEquals(services.get(0), sorted.get(3));
+        assertEquals(services.get(3), sorted.get(4));
+    }
+
+    private List<InformationService> mockServices(int[] priorities) {
+        List<InformationService> services = new ArrayList<>();
+        for (int priority : priorities) {
+            InformationService service = mock(InformationService.class);
+            when(service.getPriority()).thenReturn(priority);
+            services.add(service);
+        }
+        return services;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/ui/HostInformationControllerTest.java	Mon Dec 03 15:31:44 2012 -0500
@@ -0,0 +1,119 @@
+/*
+ * 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.ui;
+
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+import com.redhat.thermostat.client.core.views.HostInformationView;
+import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
+import com.redhat.thermostat.common.dao.HostRef;
+
+public class HostInformationControllerTest {
+
+    private static final HostFilter FILTER = new HostFilter() {
+
+        @Override
+        public boolean matches(HostRef toMatch) {
+            return true;
+        }
+    };
+
+    private UiFacadeFactory uiFacadeFactory;
+    private HostRef ref;
+    private HostInformationViewProvider provider;
+    private HostInformationView view;
+
+    @Before
+    public void setup() {
+        uiFacadeFactory = mock(UiFacadeFactory.class);
+        ref = mock(HostRef.class);
+        provider = mock(HostInformationViewProvider.class);
+        view = mock(HostInformationView.class);
+        when(provider.createView()).thenReturn(view);
+    }
+
+    @Test
+    public void testServiceOrder() {
+        int[] priorities = { 45, 20, 0, 90, 53 };
+
+        // Mock services
+        List<HostInformationService> services = mockServices(priorities);
+
+        new HostInformationController(uiFacadeFactory, ref, provider);
+
+        InOrder order = inOrder(services.get(0), services.get(1),
+                services.get(2), services.get(3), services.get(4));
+        verifyService(services.get(2), order);
+        verifyService(services.get(1), order);
+        verifyService(services.get(0), order);
+        verifyService(services.get(4), order);
+        verifyService(services.get(3), order);
+    }
+
+    private List<HostInformationService> mockServices(int[] priorities) {
+        List<HostInformationService> services = new ArrayList<>();
+        for (int priority : priorities) {
+            HostInformationService service = mock(HostInformationService.class);
+            HostInformationServiceController controller = mock(HostInformationServiceController.class);
+            when(service.getFilter()).thenReturn(FILTER);
+            when(service.getInformationServiceController(ref)).thenReturn(
+                    controller);
+            when(service.getPriority()).thenReturn(priority);
+            services.add(service);
+        }
+        // Return copy
+        when(uiFacadeFactory.getHostInformationServices()).thenReturn(new ArrayList<>(services));
+        return services;
+    }
+
+    private void verifyService(HostInformationService service, InOrder order) {
+        order.verify(service).getInformationServiceController(ref);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/ui/VmInformationControllerTest.java	Mon Dec 03 15:31:44 2012 -0500
@@ -0,0 +1,119 @@
+/*
+ * 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.ui;
+
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+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.core.views.VmInformationView;
+import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
+import com.redhat.thermostat.common.dao.VmRef;
+
+public class VmInformationControllerTest {
+
+    private static final VmFilter FILTER = new VmFilter() {
+        
+        @Override
+        public boolean matches(VmRef toMatch) {
+            return true;
+        }
+    };
+
+    private UiFacadeFactory uiFacadeFactory;
+    private VmRef ref;
+    private VmInformationViewProvider provider;
+    private VmInformationView view;
+
+    @Before
+    public void setup() {
+        uiFacadeFactory = mock(UiFacadeFactory.class);
+        ref = mock(VmRef.class);
+        provider = mock(VmInformationViewProvider.class);
+        view = mock(VmInformationView.class);
+        when(provider.createView()).thenReturn(view);
+    }
+
+    @Test
+    public void testServiceOrder() {
+        int[] priorities = { 45, 20, 0, 90, 53 };
+
+        // Mock services
+        List<VmInformationService> services = mockServices(priorities);
+
+        new VmInformationController(uiFacadeFactory, ref, provider);
+
+        InOrder order = inOrder(services.get(0), services.get(1),
+                services.get(2), services.get(3), services.get(4));
+        verifyService(services.get(2), order);
+        verifyService(services.get(1), order);
+        verifyService(services.get(0), order);
+        verifyService(services.get(4), order);
+        verifyService(services.get(3), order);
+    }
+
+    private List<VmInformationService> mockServices(int[] priorities) {
+        List<VmInformationService> services = new ArrayList<>();
+        for (int priority : priorities) {
+            VmInformationService service = mock(VmInformationService.class);
+            VmInformationServiceController controller = mock(VmInformationServiceController.class);
+            when(service.getFilter()).thenReturn(FILTER);
+            when(service.getInformationServiceController(ref)).thenReturn(
+                    controller);
+            when(service.getPriority()).thenReturn(priority);
+            services.add(service);
+        }
+        // Return copy
+        when(uiFacadeFactory.getVmInformationServices()).thenReturn(new ArrayList<>(services));
+        return services;
+    }
+
+    private void verifyService(VmInformationService service, InOrder order) {
+        order.verify(service).getInformationServiceController(ref);
+    }
+
+}
--- a/client/heapdumper/core/src/main/java/com/redhat/thermostat/client/heap/HeapDumperService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/heapdumper/core/src/main/java/com/redhat/thermostat/client/heap/HeapDumperService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class HeapDumperService implements VmInformationService {
     
+    private static final int PRIORITY = PRIORITY_MEMORY_GROUP + 60;
     private ApplicationService appService;
     private AgentInfoDAO agentInfoDao;
     private VmMemoryStatDAO vmMemoryStatDao;
@@ -81,4 +82,9 @@
     public VmFilter getFilter() {
         return filter;
     }
+
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
 }
--- a/client/heapdumper/core/src/main/resources/com/redhat/thermostat/client/heap/strings.properties	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/heapdumper/core/src/main/resources/com/redhat/thermostat/client/heap/strings.properties	Mon Dec 03 15:31:44 2012 -0500
@@ -32,7 +32,7 @@
 COMMAND_SAVE_HEAP_DUMP_ERROR_SAVING = error saving heap to file: {0}
 COMMAND_SAVE_HEAP_DUMP_ERROR_CLOSING_STREAM = error closing heap stream: {0}
 
-HEAP_SECTION_TITLE = Memory Analyzer
+HEAP_SECTION_TITLE = Heap Analyzer
 HEAP_OVERVIEW_TITLE = Heap Usage Overview
 HEAP_CHART_TITLE = Used Heap vs. Heap Capacity
 HEAP_CHART_TIME_AXIS = Time
--- a/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/memory-stats-panel/core/src/main/java/com/redhat/thermostat/client/stats/memory/core/MemoryStatsService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -49,6 +49,7 @@
 
 public class MemoryStatsService implements VmInformationService {
     
+    private static final int PRIORITY = PRIORITY_MEMORY_GROUP + 40;
     private VmFilter filter = new AlwaysMatchFilter();
 
     private ApplicationService appSvc;
@@ -73,4 +74,9 @@
     public VmFilter getFilter() {
         return filter;
     }
+
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java	Mon Dec 03 15:31:44 2012 -0500
@@ -38,6 +38,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 import org.osgi.framework.BundleContext;
@@ -65,8 +66,8 @@
 
     private CountDownLatch shutdown = new CountDownLatch(1);
 
-    private Collection<HostInformationService> hostInformationServices = new ArrayList<>();
-    private Collection<VmInformationService> vmInformationServices = new ArrayList<>();
+    private List<HostInformationService> hostInformationServices = new ArrayList<>();
+    private List<VmInformationService> vmInformationServices = new ArrayList<>();
     private Collection<VMContextAction> contextAction = new ArrayList<>();
 
     private BundleContext context;
@@ -122,7 +123,7 @@
     }
 
     @Override
-    public Collection<VmInformationService> getVmInformationServices() {
+    public List<VmInformationService> getVmInformationServices() {
         return vmInformationServices;
     }
 
@@ -163,7 +164,7 @@
     }
 
     @Override
-    public Collection<HostInformationService> getHostInformationServices() {
+    public List<HostInformationService> getHostInformationServices() {
         return hostInformationServices;
     }
 
--- a/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class HostCpuService implements HostInformationService {
     
+    private static final int PRIORITY = PRIORITY_CPU_GROUP;
     private static final HostFilter FILTER = new HostFilter() {
         @Override
         public boolean matches(HostRef toMatch) {
@@ -77,4 +78,9 @@
         return new HostCpuController(appSvc, hostInfoDAO, cpuStatDAO, ref, provider);
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }
--- a/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class HostMemoryService implements HostInformationService {
     
+    private static final int PRIORITY = PRIORITY_MEMORY_GROUP;
     private static final HostFilter FILTER = new HostFilter() {
         @Override
         public boolean matches(HostRef toMatch) {
@@ -77,4 +78,9 @@
         return new HostMemoryController(appSvc, hostInfoDAO, memoryStatDAO, ref, provider);
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }
--- a/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class HostOverviewService implements HostInformationService {
     
+    private static final int PRIORITY = PRIORITY_DEFAULT_GROUP;
     private static final HostFilter FILTER = new HostFilter() {
         @Override
         public boolean matches(HostRef toMatch) {
@@ -77,4 +78,9 @@
         return new HostOverviewController(appSvc, hostInfoDAO, networkInfoDAO, ref, provider);
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }
--- a/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadInformationService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadInformationService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -38,17 +38,17 @@
 
 import com.redhat.thermostat.client.core.VmFilter;
 import com.redhat.thermostat.client.core.VmInformationService;
-import com.redhat.thermostat.client.core.controllers.InformationServiceController;
 import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
 import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter;
 import com.redhat.thermostat.common.ApplicationService;
-import com.redhat.thermostat.common.dao.Ref;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.thread.client.common.ThreadViewProvider;
 import com.redhat.thermostat.thread.client.common.collector.ThreadCollectorFactory;
 
 public class ThreadInformationService implements VmInformationService {
 
+    private static final int PRIORITY = PRIORITY_THREAD_GROUP;
+    
     private VmFilter filter = new AlwaysMatchFilter();
     private ApplicationService service;
     private ThreadCollectorFactory collectorFactory;
@@ -72,4 +72,9 @@
         return new ThreadInformationController(ref, service, collectorFactory, viewFactory);
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }
--- a/vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/VmClassStatService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/VmClassStatService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class VmClassStatService implements VmInformationService {
 
+    private static final int PRIORITY = PRIORITY_MEMORY_GROUP + 20;
     private VmFilter filter = new AlwaysMatchFilter();
 
     private ApplicationService appSvc;
@@ -68,4 +69,9 @@
     public VmFilter getFilter() {
         return filter;
     }
+
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
 }
--- a/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class VmCpuService implements VmInformationService {
     
+    private static final int PRIORITY = PRIORITY_CPU_GROUP;
     private static final VmFilter FILTER = new AlwaysMatchFilter();
 
     private ApplicationService appSvc;
@@ -70,4 +71,9 @@
         return FILTER;
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }
--- a/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -49,6 +49,7 @@
 
 public class VmGcService implements VmInformationService {
     
+    private static final int PRIORITY = PRIORITY_MEMORY_GROUP;
     private static final VmFilter FILTER = new AlwaysMatchFilter();
 
     private ApplicationService appSvc;
@@ -73,4 +74,9 @@
         return FILTER;
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }
--- a/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewService.java	Fri Nov 30 17:30:25 2012 -0500
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewService.java	Mon Dec 03 15:31:44 2012 -0500
@@ -48,6 +48,7 @@
 
 public class VmOverviewService implements VmInformationService {
     
+    private static final int PRIORITY = PRIORITY_DEFAULT_GROUP;
     private static final VmFilter FILTER = new AlwaysMatchFilter();
 
     private ApplicationService appSvc;
@@ -70,4 +71,9 @@
         return FILTER;
     }
 
+    @Override
+    public int getPriority() {
+        return PRIORITY;
+    }
+
 }