changeset 228:b2659f4f8bf0

Use a ViewFactory to get the right View implenetation Reviewed-by: rkennke Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-April/000790.html
author Omair Majid <omajid@redhat.com>
date Fri, 13 Apr 2012 11:38:21 -0400
parents c26b63405ae1
children de4e1186ebe0
files client/src/main/java/com/redhat/thermostat/client/Configuration.java client/src/main/java/com/redhat/thermostat/client/DefaultViewFactory.java client/src/main/java/com/redhat/thermostat/client/Main.java client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java client/src/main/java/com/redhat/thermostat/client/SwingViewFactory.java client/src/main/java/com/redhat/thermostat/client/ui/AgentConfigurationView.java client/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationFrame.java client/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationView.java client/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java client/src/main/java/com/redhat/thermostat/client/ui/HostCpuView.java client/src/main/java/com/redhat/thermostat/client/ui/HostMemoryController.java client/src/main/java/com/redhat/thermostat/client/ui/HostMemoryView.java client/src/main/java/com/redhat/thermostat/client/ui/HostOverviewController.java client/src/main/java/com/redhat/thermostat/client/ui/HostOverviewView.java client/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java client/src/main/java/com/redhat/thermostat/client/ui/VmClassStatController.java client/src/main/java/com/redhat/thermostat/client/ui/VmClassStatView.java client/src/main/java/com/redhat/thermostat/client/ui/VmCpuController.java client/src/main/java/com/redhat/thermostat/client/ui/VmCpuView.java client/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java client/src/main/java/com/redhat/thermostat/client/ui/VmGcView.java client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryController.java client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryView.java client/src/main/java/com/redhat/thermostat/client/ui/VmOverviewController.java client/src/main/java/com/redhat/thermostat/client/ui/VmOverviewView.java client/src/test/java/com/redhat/thermostat/client/DefaultViewFactoryTest.java client/src/test/java/com/redhat/thermostat/client/SwingViewFactoryTest.java client/src/test/java/com/redhat/thermostat/client/VmClassStatControllerTest.java client/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java client/src/test/java/com/redhat/thermostat/client/ui/HostMemoryControllerTest.java client/src/test/java/com/redhat/thermostat/client/ui/VmCpuControllerTest.java common/src/main/java/com/redhat/thermostat/common/View.java common/src/main/java/com/redhat/thermostat/common/ViewFactory.java common/src/main/java/com/redhat/thermostat/common/appctx/ApplicationContext.java
diffstat 34 files changed, 509 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/main/java/com/redhat/thermostat/client/Configuration.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/Configuration.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,9 +39,9 @@
 import javax.swing.SwingUtilities;
 
 import com.redhat.thermostat.client.ui.AgentConfigurationController;
-import com.redhat.thermostat.client.ui.AgentConfigurationFrame;
 import com.redhat.thermostat.client.ui.AgentConfigurationModel;
 import com.redhat.thermostat.client.ui.AgentConfigurationView;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
 
 public class Configuration {
 
@@ -49,7 +49,7 @@
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
-                AgentConfigurationView view = new AgentConfigurationFrame();
+                AgentConfigurationView view = ApplicationContext.getInstance().getViewFactory().getView(AgentConfigurationView.class);
                 AgentConfigurationSource agentPrefs = new AgentConfigurationSource();
                 AgentConfigurationModel model = new AgentConfigurationModel(agentPrefs);
                 AgentConfigurationController controller = new AgentConfigurationController(model, view);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/main/java/com/redhat/thermostat/client/DefaultViewFactory.java	Fri Apr 13 11:38:21 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;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.common.View;
+import com.redhat.thermostat.common.ViewFactory;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class DefaultViewFactory implements ViewFactory {
+
+    private static final Logger logger = LoggingUtils.getLogger(SwingViewFactory.class);
+    private final Map<Class<?>, Class<?>> lookupTable = Collections.synchronizedMap(new HashMap<Class<?>, Class<?>>());
+
+    @Override
+    public <T extends View> T getView(Class<T> viewClass) {
+        Class<? extends T> klass = getViewClass(viewClass);
+        if (klass == null) {
+            logger.log(Level.WARNING, "no view class registered for " + viewClass.toString());
+            return null;
+        }
+
+        try {
+            return klass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            logger.log(Level.WARNING, "error instantiaitng" + klass);
+            return null;
+        }
+    }
+
+    @Override
+    public <T extends View> Class<? extends T> getViewClass(Class<T> viewClass) {
+        return (Class<? extends T>) lookupTable.get(viewClass);
+    }
+
+    @Override
+    public <T extends View> void setViewClass(Class<T> viewClass, Class<? extends T> implClass) {
+        lookupTable.put(viewClass, implClass);
+    }
+
+}
\ No newline at end of file
--- a/client/src/main/java/com/redhat/thermostat/client/Main.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/Main.java	Fri Apr 13 11:38:21 2012 -0400
@@ -83,12 +83,14 @@
 
         ClientPreferences prefs = new ClientPreferences();
         StartupConfiguration config = new ConnectionConfiguration(prefs);
-        
+
         StorageProvider connProv = new MongoStorageProvider(config);
         DAOFactory daoFactory = new MongoDAOFactory(connProv);
         ApplicationContext.getInstance().setDAOFactory(daoFactory);
         TimerFactory timerFactory = new ThreadPoolTimerFactory(1);
         ApplicationContext.getInstance().setTimerFactory(timerFactory);
+        SwingViewFactory viewFactory = new SwingViewFactory();
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
     }
 
     private void showGui() {
--- a/client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java	Fri Apr 13 11:38:21 2012 -0400
@@ -41,7 +41,6 @@
 
 import com.redhat.thermostat.client.config.ClientPreferences;
 import com.redhat.thermostat.client.ui.ClientConfigurationController;
-import com.redhat.thermostat.client.ui.ClientConfigurationFrame;
 import com.redhat.thermostat.client.ui.ClientConfigurationView;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
@@ -157,8 +156,9 @@
 
     private void showConfigureClientPreferences() {
         ClientPreferences prefs = new ClientPreferences();
-        ClientConfigurationView view = new ClientConfigurationFrame();
+        ClientConfigurationView view = ApplicationContext.getInstance().getViewFactory().getView(ClientConfigurationView.class);
         ClientConfigurationController controller = new ClientConfigurationController(prefs, view);
         controller.showDialog();
     }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/main/java/com/redhat/thermostat/client/SwingViewFactory.java	Fri Apr 13 11:38:21 2012 -0400
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+
+import com.redhat.thermostat.client.ui.AgentConfigurationFrame;
+import com.redhat.thermostat.client.ui.AgentConfigurationView;
+import com.redhat.thermostat.client.ui.ClientConfigurationFrame;
+import com.redhat.thermostat.client.ui.ClientConfigurationView;
+import com.redhat.thermostat.client.ui.HostCpuPanel;
+import com.redhat.thermostat.client.ui.HostCpuView;
+import com.redhat.thermostat.client.ui.HostMemoryPanel;
+import com.redhat.thermostat.client.ui.HostMemoryView;
+import com.redhat.thermostat.client.ui.HostOverviewPanel;
+import com.redhat.thermostat.client.ui.HostOverviewView;
+import com.redhat.thermostat.client.ui.VmClassStatPanel;
+import com.redhat.thermostat.client.ui.VmClassStatView;
+import com.redhat.thermostat.client.ui.VmCpuPanel;
+import com.redhat.thermostat.client.ui.VmCpuView;
+import com.redhat.thermostat.client.ui.VmGcPanel;
+import com.redhat.thermostat.client.ui.VmGcView;
+import com.redhat.thermostat.client.ui.VmMemoryPanel;
+import com.redhat.thermostat.client.ui.VmMemoryView;
+import com.redhat.thermostat.client.ui.VmOverviewPanel;
+import com.redhat.thermostat.client.ui.VmOverviewView;
+import com.redhat.thermostat.common.ViewFactory;
+
+public class SwingViewFactory extends DefaultViewFactory implements ViewFactory {
+
+    public SwingViewFactory() {
+        setViewClass(AgentConfigurationView.class, AgentConfigurationFrame.class);
+        setViewClass(ClientConfigurationView.class, ClientConfigurationFrame.class);
+
+        setViewClass(HostCpuView.class, HostCpuPanel.class);
+        setViewClass(HostMemoryView.class, HostMemoryPanel.class);
+        setViewClass(HostOverviewView.class, HostOverviewPanel.class);
+
+        setViewClass(VmClassStatView.class, VmClassStatPanel.class);
+        setViewClass(VmCpuView.class, VmCpuPanel.class);
+        setViewClass(VmGcView.class, VmGcPanel.class);
+        setViewClass(VmMemoryView.class, VmMemoryPanel.class);
+        setViewClass(VmOverviewView.class, VmOverviewPanel.class);
+    }
+
+}
--- a/client/src/main/java/com/redhat/thermostat/client/ui/AgentConfigurationView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/AgentConfigurationView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,8 +39,9 @@
 import java.util.Map;
 
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.View;
 
-public interface AgentConfigurationView {
+public interface AgentConfigurationView extends View {
 
     enum ConfigurationAction {
         SWITCH_AGENT,
--- a/client/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationFrame.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationFrame.java	Fri Apr 13 11:38:21 2012 -0400
@@ -151,7 +151,6 @@
 
     @Override
     public void actionPerformed(java.awt.event.ActionEvent e) {
-        System.out.println("swing action performed");
         if (e.getSource() == btnOk) {
             fireAction(new ActionEvent<>(this, Action.CLOSE_ACCEPT));
         } else if (e.getSource() == btnCancel) {
@@ -170,7 +169,6 @@
     }
 
     private void fireAction(ActionEvent<Action> actionEvent) {
-        System.out.println("thermostat-action fired");
         for (ActionListener<Action> listener: listeners) {
             listener.actionPerformed(actionEvent);
         }
--- a/client/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -37,8 +37,9 @@
 package com.redhat.thermostat.client.ui;
 
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.View;
 
-public interface ClientConfigurationView {
+public interface ClientConfigurationView extends View {
 
     enum Action {
         CLOSE_CANCEL,
--- a/client/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -64,7 +64,7 @@
 
     public HostCpuController(HostRef ref) {
         this.ref = ref;
-        view = createView();
+        view = ApplicationContext.getInstance().getViewFactory().getView(HostCpuView.class);
         view.clearCpuLoadData();
         DAOFactory daos = ApplicationContext.getInstance().getDAOFactory();
         hostInfoDAO = daos.getHostInfoDAO();
@@ -72,7 +72,7 @@
 
         backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
         backgroundUpdateTimer.setAction(new Runnable() {
-            
+
             @Override
             public void run() {
                 updateView();
@@ -114,10 +114,6 @@
         view.addCpuLoadData(result);
     }
 
-    protected HostCpuView createView() {
-        return new HostCpuPanel();
-    }
-
     public Component getComponent() {
         return view.getUiComponent();
     }
--- a/client/src/main/java/com/redhat/thermostat/client/ui/HostCpuView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/HostCpuView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,9 +39,10 @@
 import java.awt.Component;
 import java.util.List;
 
+import com.redhat.thermostat.common.View;
 import com.redhat.thermostat.common.model.DiscreteTimeData;
 
-public interface HostCpuView {
+public interface HostCpuView extends View {
 
     void setCpuCount(String count);
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/HostMemoryController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/HostMemoryController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -74,7 +74,7 @@
         hostInfoDAO = daos.getHostInfoDAO();
         memoryStatDAO = daos.getMemoryStatDAO();
 
-        view = createView();
+        view = ApplicationContext.getInstance().getViewFactory().getView(HostMemoryView.class);
 
         view.addMemoryChart(MemoryType.MEMORY_TOTAL.name(), localize(LocaleResources.HOST_MEMORY_TOTAL));
         view.addMemoryChart(MemoryType.MEMORY_FREE.name(), localize(LocaleResources.HOST_MEMORY_FREE));
@@ -117,10 +117,6 @@
         return view.getUiComponent();
     }
 
-    protected HostMemoryView createView() {
-        return new HostMemoryPanel();
-    }
-
     private void doMemoryChartUpdate() {
         List<DiscreteTimeData<? extends Number>> memFree = new LinkedList<>();
         List<DiscreteTimeData<? extends Number>> memTotal = new LinkedList<>();
@@ -128,7 +124,7 @@
         List<DiscreteTimeData<? extends Number>> buf = new LinkedList<>();
         List<DiscreteTimeData<? extends Number>> swapTotal = new LinkedList<>();
         List<DiscreteTimeData<? extends Number>> swapFree = new LinkedList<>();
-        
+
         for (MemoryStat stat : memoryStatDAO.getLatestMemoryStats(ref)) {
             long timeStamp = stat.getTimeStamp();
             memFree.add(new DiscreteTimeData<Long>(timeStamp, stat.getFree()));
--- a/client/src/main/java/com/redhat/thermostat/client/ui/HostMemoryView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/HostMemoryView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,9 +39,10 @@
 import java.awt.Component;
 import java.util.List;
 
+import com.redhat.thermostat.common.View;
 import com.redhat.thermostat.common.model.DiscreteTimeData;
 
-public interface HostMemoryView {
+public interface HostMemoryView extends View {
 
     public interface GraphVisibilityChangeListener {
         public void show(String tag);
--- a/client/src/main/java/com/redhat/thermostat/client/ui/HostOverviewController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/HostOverviewController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -87,15 +87,11 @@
         networkTableColumnVector.add(localize(LocaleResources.NETWORK_IPV6_COLUMN));
 
         backgroundUpdateTimer = new Timer();
-        view = createView();
+        view = ApplicationContext.getInstance().getViewFactory().getView(HostOverviewView.class);
 
         view.setNetworkTableColumns(networkTableColumnVector.toArray());
     }
 
-    public HostOverviewView createView() {
-        return new HostOverviewPanel();
-    }
-
     private void doNetworkTableUpdateAsync() {
         new NetworkTableModelUpdater().execute();
     }
--- a/client/src/main/java/com/redhat/thermostat/client/ui/HostOverviewView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/HostOverviewView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -38,7 +38,9 @@
 
 import java.awt.Component;
 
-public interface HostOverviewView {
+import com.redhat.thermostat.common.View;
+
+public interface HostOverviewView extends View {
 
     void setHostName(String newHostName);
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Fri Apr 13 11:38:21 2012 -0400
@@ -85,8 +85,9 @@
 import javax.swing.tree.TreePath;
 import javax.swing.tree.TreeSelectionModel;
 
+import com.redhat.thermostat.client.AgentConfigurationSource;
+import com.redhat.thermostat.client.ApplicationInfo;
 import com.redhat.thermostat.client.Configuration;
-import com.redhat.thermostat.client.ApplicationInfo;
 import com.redhat.thermostat.client.HostsVMsLoader;
 import com.redhat.thermostat.client.MainView;
 import com.redhat.thermostat.client.UiFacadeFactory;
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmClassStatController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmClassStatController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -75,11 +75,7 @@
     public VmClassStatController(VmRef ref) {
         this.ref = ref;
         dao = ApplicationContext.getInstance().getDAOFactory().getVmClassStatsDAO();
-        classesView = createView();
-    }
-
-    protected VmClassStatView createView() {
-        return new VmClassStatPanel();
+        classesView = ApplicationContext.getInstance().getViewFactory().getView(VmClassStatView.class);
     }
 
     @Override
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmClassStatView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmClassStatView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,9 +39,10 @@
 import java.awt.Component;
 import java.util.List;
 
+import com.redhat.thermostat.common.View;
 import com.redhat.thermostat.common.model.DiscreteTimeData;
 
-public interface VmClassStatView {
+public interface VmClassStatView extends View {
 
     void clearClassCount();
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmCpuController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmCpuController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -61,12 +61,9 @@
     public VmCpuController(VmRef ref) {
         this.ref = ref;
         dao = ApplicationContext.getInstance().getDAOFactory().getVmCpuStatDAO();
-        view = createView();
+        view = ApplicationContext.getInstance().getViewFactory().getView(VmCpuView.class);
     }
 
-    protected VmCpuView createView() {
-        return new VmCpuPanel();
-    }
 
     @Override
     public void start() {
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmCpuView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmCpuView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,9 +39,10 @@
 import java.awt.Component;
 import java.util.List;
 
+import com.redhat.thermostat.common.View;
 import com.redhat.thermostat.common.model.DiscreteTimeData;
 
-public interface VmCpuView {
+public interface VmCpuView extends View {
 
     void addData(List<DiscreteTimeData<? extends Number>> data);
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -75,17 +75,13 @@
 
     public VmGcController(VmRef ref) {
         this.ref = ref;
-        this.view = createView();
+        this.view = ApplicationContext.getInstance().getViewFactory().getView(VmGcView.class);
 
         DAOFactory df = ApplicationContext.getInstance().getDAOFactory();
         gcDao = df.getVmGcStatDAO();
         memDao = df.getVmMemoryStatDAO();
     }
 
-    protected VmGcView createView() {
-        return new VmGcPanel();
-    }
-
     @Override
     public void start() {
         timer.scheduleAtFixedRate(new TimerTask() {
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmGcView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmGcView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -39,9 +39,10 @@
 import java.awt.Component;
 import java.util.List;
 
+import com.redhat.thermostat.common.View;
 import com.redhat.thermostat.common.model.DiscreteTimeData;
 
-public interface VmGcView {
+public interface VmGcView extends View {
 
     void addChart(String tag, String title);
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -61,7 +61,7 @@
     public VmMemoryController(VmRef ref) {
         this.ref = ref;
         dao = ApplicationContext.getInstance().getDAOFactory().getVmMemoryStatDAO();
-        view = createView();
+        view = ApplicationContext.getInstance().getViewFactory().getView(VmMemoryView.class);
     }
 
     @Override
@@ -88,10 +88,6 @@
         timer.cancel();
     }
 
-    protected VmMemoryView createView() {
-        return new VmMemoryPanel();
-    }
-
     public Component getComponent() {
         return view.getUiComponent();
     }
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -38,7 +38,9 @@
 
 import java.awt.Component;
 
-public interface VmMemoryView {
+import com.redhat.thermostat.common.View;
+
+public interface VmMemoryView extends View {
 
     void setMemoryRegionSize(String name, long used, long allocated, long max);
 
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmOverviewController.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmOverviewController.java	Fri Apr 13 11:38:21 2012 -0400
@@ -64,7 +64,7 @@
 
     public VmOverviewController(VmRef vmRef) {
         this.ref = vmRef;
-        this.view = createView();
+        this.view = ApplicationContext.getInstance().getViewFactory().getView(VmOverviewView.class);
 
         dao = ApplicationContext.getInstance().getDAOFactory().getVmInfoDAO();
 
@@ -110,10 +110,6 @@
         timer.cancel();
     }
 
-    protected VmOverviewView createView() {
-        return new VmOverviewPanel();
-    }
-
     public Component getComponent() {
         return view.getUiComponent();
     }
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmOverviewView.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmOverviewView.java	Fri Apr 13 11:38:21 2012 -0400
@@ -38,7 +38,9 @@
 
 import java.awt.Component;
 
-public interface VmOverviewView {
+import com.redhat.thermostat.common.View;
+
+public interface VmOverviewView extends View {
 
     void setVmPid(String pid);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/test/java/com/redhat/thermostat/client/DefaultViewFactoryTest.java	Fri Apr 13 11:38:21 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.common.View;
+
+public class DefaultViewFactoryTest {
+
+    public static class MockView implements View {}
+
+    @Test
+    public void testGetUnknownClasses() {
+        DefaultViewFactory factory = new DefaultViewFactory();
+        assertEquals(null, factory.getView(MockView.class));
+    }
+
+    @Test
+    public void testSetAndGet() {
+        DefaultViewFactory factory = new DefaultViewFactory();
+        factory.setViewClass(MockView.class, MockView.class);
+        assertEquals(MockView.class, factory.getViewClass(MockView.class));
+    }
+
+    @Test
+    public void testInstantiation() {
+        DefaultViewFactory factory = new DefaultViewFactory();
+        factory.setViewClass(MockView.class, MockView.class);
+        MockView view = factory.getView(MockView.class);
+        assertNotNull(view);
+        assertEquals(MockView.class.getName(), view.getClass().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/test/java/com/redhat/thermostat/client/SwingViewFactoryTest.java	Fri Apr 13 11:38:21 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;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.ui.AgentConfigurationView;
+import com.redhat.thermostat.client.ui.ClientConfigurationView;
+import com.redhat.thermostat.client.ui.HostCpuView;
+import com.redhat.thermostat.client.ui.HostMemoryView;
+import com.redhat.thermostat.client.ui.HostOverviewView;
+import com.redhat.thermostat.client.ui.VmClassStatView;
+import com.redhat.thermostat.client.ui.VmCpuView;
+import com.redhat.thermostat.client.ui.VmGcView;
+import com.redhat.thermostat.client.ui.VmMemoryView;
+import com.redhat.thermostat.client.ui.VmOverviewView;
+
+public class SwingViewFactoryTest {
+
+    @Test
+    public void test() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                SwingViewFactory factory = new SwingViewFactory();
+
+                Class[] knownViewClasses = new Class[] {
+                    AgentConfigurationView.class,
+                    ClientConfigurationView.class,
+                    HostCpuView.class,
+                    HostMemoryView.class,
+                    HostOverviewView.class,
+                    VmClassStatView.class,
+                    VmCpuView.class,
+                    VmGcView.class,
+                    VmMemoryView.class,
+                    VmOverviewView.class,
+                };
+
+                for (Class klass: knownViewClasses) {
+                    assertNotNull(factory.getViewClass(klass));
+                    assertNotNull(factory.getView(klass));
+                }
+            }
+
+        });
+
+    }
+}
--- a/client/src/test/java/com/redhat/thermostat/client/VmClassStatControllerTest.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/test/java/com/redhat/thermostat/client/VmClassStatControllerTest.java	Fri Apr 13 11:38:21 2012 -0400
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.client;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -49,6 +50,7 @@
 
 import com.redhat.thermostat.client.ui.VmClassStatController;
 import com.redhat.thermostat.client.ui.VmClassStatView;
+import com.redhat.thermostat.common.ViewFactory;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
 import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.dao.MongoDAOFactory;
@@ -75,15 +77,13 @@
         ApplicationContext.getInstance().setDAOFactory(daoFactory);
         VmRef ref = mock(VmRef.class);
 
-        final VmClassStatView view = mock(VmClassStatView.class);
+        VmClassStatView view = mock(VmClassStatView.class);
+        ViewFactory viewFactory = mock(ViewFactory.class);
+        when(viewFactory.getView(eq(VmClassStatView.class))).thenReturn(view);
 
-        // TODO: Consider to pass the ClassesView or a factory for it to the controller instead.
-        VmClassStatController controller = new VmClassStatController(ref) {
-            @Override
-            protected VmClassStatView createView() {
-                return view;
-            }
-        };
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
+
+        VmClassStatController controller = new VmClassStatController(ref);
 
         controller.start();
 
--- a/client/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java	Fri Apr 13 11:38:21 2012 -0400
@@ -38,6 +38,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNotNull;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
@@ -58,6 +59,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.ViewFactory;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
 import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
 import com.redhat.thermostat.common.dao.CpuStatDAO;
@@ -107,14 +109,13 @@
         ApplicationContext.getInstance().setDAOFactory(daoFactory);
 
         view = mock(HostCpuView.class);
+        ViewFactory viewFactory = mock(ViewFactory.class);
+        when(viewFactory.getView(eq(HostCpuView.class))).thenReturn(view);
+
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
+
         HostRef host = new HostRef("123", "fluffhost");
-        controller = new HostCpuController(host) {
-            // TODO: Reverse dependency.
-            @Override
-            protected HostCpuView createView() {
-                return view;
-            }
-        };
+        controller = new HostCpuController(host);
 
         timerAction = actionCaptor.getValue();
     }
--- a/client/src/test/java/com/redhat/thermostat/client/ui/HostMemoryControllerTest.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/test/java/com/redhat/thermostat/client/ui/HostMemoryControllerTest.java	Fri Apr 13 11:38:21 2012 -0400
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.client.ui;
 
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -45,9 +46,12 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.junit.Before;
 import org.junit.Test;
 
+import com.redhat.thermostat.common.ViewFactory;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
 import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
@@ -58,6 +62,11 @@
 
 public class HostMemoryControllerTest {
 
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
     @SuppressWarnings("unchecked") // any(List.class)
     @Test
     public void testUpdate() {
@@ -77,14 +86,12 @@
         ApplicationContext.getInstance().setDAOFactory(daoFactory);
 
         HostRef ref = mock(HostRef.class);
-        final HostMemoryView view = mock(HostMemoryView.class);
-        // TODO: Consider to pass the ClassesView or a factory for it to the controller instead.
-        HostMemoryController controller = new HostMemoryController(ref) {
-            @Override
-            protected HostMemoryView createView() {
-                return view;
-            }
-        };
+        HostMemoryView view = mock(HostMemoryView.class);
+        ViewFactory viewFactory = mock(ViewFactory.class);
+        when(viewFactory.getView(eq(HostMemoryView.class))).thenReturn(view);
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
+
+        HostMemoryController controller = new HostMemoryController(ref);
 
         controller.start();
 
--- a/client/src/test/java/com/redhat/thermostat/client/ui/VmCpuControllerTest.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/client/src/test/java/com/redhat/thermostat/client/ui/VmCpuControllerTest.java	Fri Apr 13 11:38:21 2012 -0400
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.client.ui;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -45,9 +46,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.junit.Before;
 import org.junit.Test;
 
+import com.redhat.thermostat.common.ViewFactory;
 import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
 import com.redhat.thermostat.common.dao.DAOFactory;
 import com.redhat.thermostat.common.dao.MongoDAOFactory;
 import com.redhat.thermostat.common.dao.VmCpuStatDAO;
@@ -57,6 +61,11 @@
 
 public class VmCpuControllerTest {
 
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
     @SuppressWarnings("unchecked") // any(List.class)
     @Test
     public void testChartUpdate() {
@@ -75,14 +84,12 @@
         VmRef ref = mock(VmRef.class);
 
         final VmCpuView view = mock(VmCpuView.class);
+        ViewFactory viewFactory = mock(ViewFactory.class);
+        when(viewFactory.getView(eq(VmCpuView.class))).thenReturn(view);
 
-        // TODO: Consider to pass the ClassesView or a factory for it to the controller instead.
-        VmCpuController controller = new VmCpuController(ref) {
-            @Override
-            protected VmCpuView createView() {
-                return view;
-            }
-        };
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
+
+        VmCpuController controller = new VmCpuController(ref);
 
         controller.start();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/src/main/java/com/redhat/thermostat/common/View.java	Fri Apr 13 11:38:21 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.common;
+
+/**
+ * An object that is meant to be used as a View in an MVC setup.
+ *
+ * All implementations of this interface must have a no-arg public constructor
+ */
+public interface View {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/src/main/java/com/redhat/thermostat/common/ViewFactory.java	Fri Apr 13 11:38:21 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.common;
+
+public interface ViewFactory {
+
+    public <T extends View> T getView(Class<T> viewClass);
+
+    public <T extends View> Class<? extends T> getViewClass(Class<T> viewClass);
+
+    public <T extends View > void setViewClass(Class<T> viewClass, Class<? extends T> implClass);
+}
--- a/common/src/main/java/com/redhat/thermostat/common/appctx/ApplicationContext.java	Fri Apr 13 10:16:10 2012 -0400
+++ b/common/src/main/java/com/redhat/thermostat/common/appctx/ApplicationContext.java	Fri Apr 13 11:38:21 2012 -0400
@@ -37,6 +37,7 @@
 package com.redhat.thermostat.common.appctx;
 
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.ViewFactory;
 import com.redhat.thermostat.common.dao.DAOFactory;
 
 public class ApplicationContext {
@@ -47,6 +48,8 @@
 
     private TimerFactory timerFactory;
 
+    private ViewFactory viewFactory;
+
     public static ApplicationContext getInstance() {
         return instance;
     }
@@ -76,4 +79,12 @@
         return timerFactory;
     }
 
+    public ViewFactory getViewFactory() {
+        return viewFactory;
+    }
+
+    public void setViewFactory(ViewFactory viewFactory) {
+        this.viewFactory = viewFactory;
+    }
+
 }