From 25608d121dd369dd370ca62a0b9aaca30320c319 Mon Sep 17 00:00:00 2001
From: Nils Christian Ehmke <nie@informatik.uni-kiel.de>
Date: Sat, 5 May 2012 11:37:30 +0200
Subject: [PATCH] Removed unnecessary code; Modified comments; Added observer
 patterns

---
 .../beans/application/DependenciesBean.java   |   5 +-
 .../beans/application/ProjectsBean.java       |  54 ++++++--
 .../webgui/beans/request/StringBean.java      |   7 +
 .../webgui/beans/request/StringToIDBean.java  |   7 +
 .../beans/session/AnalysisControllerBean.java |   6 +-
 .../beans/session/CurrentThemeBean.java       |  12 +-
 .../session/CurrentWorkspaceSizeBean.java     |  60 ---------
 .../beans/session/DependencyUploadBean.java   |   2 +-
 .../session/SelectedMainProjectBean.java      | 125 +++++++++++++++---
 .../beans/session/SelectedPluginBean.java     |   5 +-
 .../beans/session/SelectedProjectBean.java    |  50 +++++--
 .../kieker/webgui/common/FileManager.java     |  46 ++-----
 .../webgui/common/PluginClassLoader.java      |   4 +-
 .../kieker/webgui/common/PluginFinder.java    |  25 +---
 .../MIDependencyToCountPluginsConverter.java  |   4 +-
 .../MIDependencyToStringConverter.java        |   4 +-
 .../converter/MIProjectToStringConverter.java |   4 +-
 Kieker.WebGUI/src/main/webapp/main.xhtml      |   6 +-
 .../src/main/webapp/main/settingsDialog.xhtml |   9 +-
 19 files changed, 250 insertions(+), 185 deletions(-)
 delete mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkspaceSizeBean.java

diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/DependenciesBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/DependenciesBean.java
index 3599c3d4..82b50ba2 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/DependenciesBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/DependenciesBean.java
@@ -82,9 +82,8 @@ public class DependenciesBean {
 		synchronized (this) {
 			final MIDependency dependency = FileManager.getInstance().uploadDependency(file);
 			if (dependency != null) {
-				/*
-				 * Is is possible that we already have a dependency with the same name and have to remove it first.
-				 */
+				// Is is possible that we already have a dependency with the same name and have to remove it first.
+
 				for (final MIDependency dep : this.dependencies) {
 					if (dep.getFilePath().equals(dependency.getFilePath())) {
 						this.dependencies.remove(dep);
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java
index 979d2d9f..5d42d00a 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java
@@ -20,6 +20,7 @@
 package kieker.webgui.beans.application;
 
 import java.util.List;
+import java.util.Observable;
 
 import javax.faces.application.FacesMessage;
 import javax.faces.bean.ApplicationScoped;
@@ -47,7 +48,7 @@ import org.primefaces.model.TreeNode;
  */
 @ManagedBean
 @ApplicationScoped
-public class ProjectsBean {
+public class ProjectsBean extends Observable {
 
 	/**
 	 * A list containing all available projects.
@@ -62,7 +63,7 @@ public class ProjectsBean {
 	 * Creates a new instance of this class.
 	 */
 	public ProjectsBean() {
-		/* Load all projects from the file system. */
+		// Load all projects from the file system.
 		this.projects = FileManager.getInstance().loadAllProjects();
 		this.factory = new MAnalysisMetaModelFactory();
 	}
@@ -75,23 +76,19 @@ public class ProjectsBean {
 	 *            The name of the new project.
 	 */
 	public final void addProject(final String projectName) {
-		/*
-		 * Create a new project.
-		 */
+		// Create a new project.
 		final MIProject project = this.factory.createProject();
 		project.setName(projectName);
 
-		/* The check for an existing project and the potential storage within our list has to be done atomically. */
+		// The check for an existing project and the potential storage within our list has to be done atomically.
 		synchronized (this) {
-			/*
-			 * Try to save the project. If this fails, the project exists already.
-			 */
+			// Try to save the project. If this fails, the project exists already.
 			if (FileManager.getInstance().saveNewProject(project)) {
 				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "", "New Project: " + projectName));
 				this.projects.add(project);
 				RequestContext.getCurrentInstance().addPartialUpdateTarget("projectsForm");
 			} else {
-				/* Inform the user about the fail. */
+				// Inform the user about the fail.
 				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "", "A project with this name exists already."));
 			}
 		}
@@ -111,7 +108,7 @@ public class ProjectsBean {
 				final TreeNode dependenciesNode = new DefaultTreeNode("dependencies", "Dependencies", projectNode);
 				final TreeNode usedPluginsNode = new DefaultTreeNode("usedPlugins", "Used Plugins", projectNode);
 
-				/* Append the used plugins and dependencies. */
+				// Append the used plugins and dependencies.
 				for (final MIPlugin plugin : project.getPlugins()) {
 					new DefaultTreeNode("usedPlugin", plugin.getName(), usedPluginsNode);
 				}
@@ -149,6 +146,9 @@ public class ProjectsBean {
 			final boolean result = FileManager.getInstance().deleteProject(project);
 			if (result) {
 				this.projects.remove(project);
+				// Notify the observers
+				this.setChanged();
+				this.notifyObservers(new MsgProjectRemoved(project));
 			}
 		}
 	}
@@ -170,4 +170,36 @@ public class ProjectsBean {
 		}
 	}
 
+	/**
+	 * This helper class is a wrapper for a project and can be send to the observers as a message that a project just has been removed. It contains
+	 * the removed project.
+	 * 
+	 * @author Nils Christian Ehmke
+	 */
+	public static class MsgProjectRemoved {
+		/**
+		 * The stored project.
+		 */
+		private final MIProject project;
+
+		/**
+		 * Creates a new instance of this class using the given parameters.
+		 * 
+		 * @param project
+		 *            The project to be stored within this class.
+		 */
+		public MsgProjectRemoved(final MIProject project) {
+			this.project = project;
+		}
+
+		/**
+		 * Delivers the stored project within this class.
+		 * 
+		 * @return The instance of {@link MIProject}.
+		 */
+		public MIProject getProject() {
+			return this.project;
+		}
+	}
+
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java
index c79d4472..0fd11aa5 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java
@@ -64,6 +64,13 @@ public class StringBean {
 		this.string = string;
 	}
 
+	/**
+	 * This method verifies whether the given object is an instance of {@link java.lang.String} or not.
+	 * 
+	 * @param object
+	 *            The object to be verified.
+	 * @return true if and only if the given object is an instance of String.
+	 */
 	public boolean checkString(final Object object) {
 		return object instanceof String;
 	}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringToIDBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringToIDBean.java
index 85a27a0f..c842a9c5 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringToIDBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringToIDBean.java
@@ -33,6 +33,13 @@ import javax.faces.bean.RequestScoped;
 @RequestScoped
 public class StringToIDBean {
 
+	/**
+	 * Creates a new instance of this class.
+	 */
+	public StringToIDBean() {
+		// No code necessary.
+	}
+
 	/**
 	 * Modified the given string so that it can be used as an ID. In other words: It removes all space characters.
 	 * 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/AnalysisControllerBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/AnalysisControllerBean.java
index 25ea6178..93481b8a 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/AnalysisControllerBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/AnalysisControllerBean.java
@@ -86,12 +86,12 @@ public class AnalysisControllerBean {
 	public void instantiate(final MIProject mProject) {
 		if (mProject != null) {
 			try {
-				/* Create a temporary file and store the model instance in it. */
+				// Create a temporary file and store the model instance in it.
 				final File tempFile = File.createTempFile("java", ".tmp");
 				AnalysisController.saveToFile(tempFile, mProject);
-				/* Try to create the controller. */
+				// Try to create the controller.
 				this.controller = new AnalysisController(tempFile, PluginClassLoader.getInstance());
-				/* Don't forget to remove the temporary file. */
+				// Don't forget to remove the temporary file.
 				if (!tempFile.delete()) {
 					AnalysisControllerBean.LOG.warn("Could not remove temporary file.");
 				}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentThemeBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentThemeBean.java
index 0fff3ba5..58a90a81 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentThemeBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentThemeBean.java
@@ -28,6 +28,8 @@ import javax.faces.context.FacesContext;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
 
+import kieker.webgui.beans.application.ThemeSwitcherBean;
+
 /**
  * This bean can be used for a single session of a user and stores the currently used theme (look and feel) for this user. Currently the default value being used is
  * the "glass-x"-theme, if none other value can be find within the parameters of the faces context.
@@ -62,17 +64,17 @@ public class CurrentThemeBean {
 	 * Creates a new instance of this class.
 	 */
 	public CurrentThemeBean() {
-		/* Get the parameters within the current context. */
+		// Get the parameters within the current context.
 		final Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
-		/* Try to find the default theme within the parameters. */
+		// Try to find the default theme within the parameters.
 		if (params.containsKey(CurrentThemeBean.KEY_THEME)) {
 			this.theme = params.get(CurrentThemeBean.KEY_THEME);
 		} else {
-			/* Use the default theme. */
+			// Use the default theme.
 			this.theme = CurrentThemeBean.DEFAULT_THEME;
 		}
 
-		/* Try to find the cookie for the theme. */
+		// Try to find the cookie for the theme.
 		final Map<String, Object> cookies = FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap();
 
 		if (cookies.containsKey(CurrentThemeBean.KEY_COOKIE_THEME)) {
@@ -98,7 +100,7 @@ public class CurrentThemeBean {
 	public final void setTheme(final String theme) {
 		this.theme = theme;
 
-		/* Set the cookie theme. */
+		// Set the cookie theme.
 		final Cookie cookie = new Cookie("theme", theme);
 
 		final HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkspaceSizeBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkspaceSizeBean.java
deleted file mode 100644
index aea33f7a..00000000
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkspaceSizeBean.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- * Copyright 2012 by
- *  + Christian-Albrechts-University of Kiel
- *    + Department of Computer Science
- *      + Software Engineering Group 
- *  and others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ***************************************************************************/
-package kieker.webgui.beans.session;
-
-import javax.faces.bean.ManagedBean;
-import javax.faces.bean.SessionScoped;
-
-/**
- * This bean stores the current workspace size of the current user.
- * 
- * @author Nils Christian Ehmke
- */
-@ManagedBean
-@SessionScoped
-public class CurrentWorkspaceSizeBean {
-
-	private int sizeX;
-	private int sizeY;
-
-	/**
-	 * Creates a new instance of this class.
-	 */
-	public CurrentWorkspaceSizeBean() {
-		this.sizeX = 1000;
-		this.sizeY = 1000;
-	}
-
-	public int getSizeX() {
-		return this.sizeX;
-	}
-
-	public void setSizeX(final int sizeX) {
-		this.sizeX = sizeX;
-	}
-
-	public int getSizeY() {
-		return this.sizeY;
-	}
-
-	public void setSizeY(final int sizeY) {
-		this.sizeY = sizeY;
-	}
-}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/DependencyUploadBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/DependencyUploadBean.java
index 5b4ec9b6..dd3714d7 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/DependencyUploadBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/DependencyUploadBean.java
@@ -49,7 +49,7 @@ public class DependencyUploadBean {
 	 * Creates a new instance of this class.
 	 */
 	public DependencyUploadBean() {
-		/* No code necessary. */
+		// No code necessary.
 	}
 
 	/**
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedMainProjectBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedMainProjectBean.java
index 869a43d9..7342da33 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedMainProjectBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedMainProjectBean.java
@@ -25,11 +25,17 @@ import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Observable;
+import java.util.Observer;
 
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.faces.application.FacesMessage;
 import javax.faces.bean.ManagedBean;
 import javax.faces.bean.SessionScoped;
@@ -50,12 +56,14 @@ import kieker.analysis.repository.AbstractRepository;
 import kieker.common.configuration.Configuration;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
+import kieker.webgui.beans.application.ProjectsBean;
 import kieker.webgui.common.Connection;
 import kieker.webgui.common.FileManager;
 import kieker.webgui.common.PluginClassLoader;
 import kieker.webgui.common.PluginFinder;
 
 import org.eclipse.emf.common.util.EList;
+import org.primefaces.context.RequestContext;
 
 /**
  * This session bean stores the currently selected main project of the user and provides different methods to access and manipulate the properties of this project.
@@ -66,7 +74,7 @@ import org.eclipse.emf.common.util.EList;
  */
 @ManagedBean
 @SessionScoped
-public class SelectedMainProjectBean extends Observable {
+public class SelectedMainProjectBean extends Observable implements Observer {
 	/**
 	 * The logger within this class.
 	 */
@@ -87,6 +95,13 @@ public class SelectedMainProjectBean extends Observable {
 	 * This constant is used as a protocol for the dependencies.
 	 */
 	private static final String URL_PROTOCOL_FILE = "file";
+
+	/**
+	 * This collection contains all targets within the current view which will be updated when the selection of the main project changes.
+	 */
+	private static final Collection<String> UPDATE_TARGETS = Collections.unmodifiableCollection(Arrays.asList(new String[] { "projectsForm", "toolpalette",
+		"centerForm", }));
+
 	/**
 	 * The main project of the current user.
 	 */
@@ -96,15 +111,18 @@ public class SelectedMainProjectBean extends Observable {
 	 */
 	private List<Connection> connections;
 
-    public enum UPDATE_MSG {
-        SELECTION_CHANGED
-    }
-    
+	private final ProjectsBean observableBean;
+
 	/**
 	 * Creates a new instance of this class.
 	 */
 	public SelectedMainProjectBean() {
+		// Make sure that the collection for the connection is not empty. This will make the iteration over the collection
 		this.connections = new ArrayList<Connection>();
+
+		// Try to get the projects bean.
+		final FacesContext context = FacesContext.getCurrentInstance();
+		this.observableBean = context.getApplication().evaluateExpressionGet(context, "#{projectsBean}", ProjectsBean.class);
 	}
 
 	/**
@@ -123,14 +141,23 @@ public class SelectedMainProjectBean extends Observable {
 	 *            The new main project of the current user.
 	 */
 	public final void setMainProject(final MIProject mainProject) {
+		// Overtake the main project and its connection.
 		this.mainProject = mainProject;
 		this.connections = this.getConnectionsFromProject();
-		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "", "New main project: " + mainProject.getName()));
-	
-        // Inform the observers
-        setChanged();
-        notifyObservers(UPDATE_MSG.SELECTION_CHANGED);
-    }
+
+		// In the case we haven't set the main project to null, we inform the user about the change.
+		if (this.mainProject != null) {
+			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "", "New main project: " + mainProject.getName()));
+		}
+
+		// Inform the observers
+		this.setChanged();
+		this.notifyObservers(new MsgMainProjectSelection(mainProject));
+
+		// Update the corresponding components
+		final RequestContext requestContext = RequestContext.getCurrentInstance();
+		requestContext.addPartialUpdateTargets(SelectedMainProjectBean.UPDATE_TARGETS);
+	}
 
 	/**
 	 * This method delivers the available reader-plugins for the current main project. The delivered plugins are never abstract.
@@ -140,14 +167,18 @@ public class SelectedMainProjectBean extends Observable {
 	public final List<Class<AbstractReaderPlugin>> getAvailableReaders() {
 		final List<Class<AbstractReaderPlugin>> list = new ArrayList<Class<AbstractReaderPlugin>>();
 
+		// Make sure there is a main project.
 		if (this.mainProject != null) {
+			// Run through all libraries
 			for (final MIDependency lib : this.mainProject.getDependencies()) {
+				// Make sure the plugin class loader knows about the lib
 				try {
 					PluginClassLoader.getInstance().addURL(
 							new URL(SelectedMainProjectBean.URL_PROTOCOL_FILE, SelectedMainProjectBean.URL_LOCALHOST, FileManager.getInstance().getFullPath(lib)));
 				} catch (final MalformedURLException ex) {
 					SelectedMainProjectBean.LOG.warn(SelectedMainProjectBean.ERR_MSG_INVALID_URL, ex);
 				}
+				// Now try to find the plugins within the library and extract the readers.
 				try {
 					final List<Class<AbstractPlugin>> plugins = PluginFinder.getAllPluginsWithinJar(new URL(SelectedMainProjectBean.URL_PROTOCOL_FILE,
 							SelectedMainProjectBean.URL_LOCALHOST, FileManager.getInstance().getFullPath(lib)));
@@ -242,15 +273,15 @@ public class SelectedMainProjectBean extends Observable {
 	 *            The model plugin which will be modified.
 	 */
 	private static void addConfiguration(final AbstractPlugin plugin, final MIPlugin mPlugin) {
-		/* Get the current configuration and use it to initialize the model plugin. */
+		// Get the current configuration and use it to initialize the model plugin.
 		final Configuration configuration = plugin.getCurrentConfiguration();
 		final MAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory();
 
-		/* Run through all entries. */
+		// Run through all entries.
 		final Iterator<Map.Entry<Object, Object>> iterator = configuration.entrySet().iterator();
 		while (iterator.hasNext()) {
 			final Map.Entry<Object, Object> entry = iterator.next();
-			/* Create a property object for the current entry. */
+			// Create a property object for the current entry.
 			final MIProperty property = factory.createProperty();
 			property.setName(entry.getKey().toString());
 			property.setValue(entry.getValue().toString());
@@ -268,7 +299,7 @@ public class SelectedMainProjectBean extends Observable {
 	 *            The model plugin which will be modified.
 	 */
 	private static void addPorts(final AbstractPlugin plugin, final MIPlugin mPlugin) {
-		/* Get the port and use them to initialize the model plugin. */
+		// Get the port and use them to initialize the model plugin.
 		final String[] inputPortNames = plugin.getAllInputPortNames();
 		final String[] outputPortNames = plugin.getAllOutputPortNames();
 
@@ -339,9 +370,10 @@ public class SelectedMainProjectBean extends Observable {
 	 *            The project to be removed.
 	 */
 	public final void removePlugin(final MIPlugin plugin) {
+		// TODO Replace with an observer
 		this.mainProject.getPlugins().remove(plugin);
 
-		/* Get the currently selected plugin bean. */
+		// Get the currently selected plugin bean.
 		final SelectedPluginBean selectedPluginBean = (SelectedPluginBean) FacesContext.getCurrentInstance().getExternalContext()
 				.getSessionMap().get("selectedPluginBean");
 		if (selectedPluginBean != null && selectedPluginBean.getPlugin() == plugin) {
@@ -404,7 +436,6 @@ public class SelectedMainProjectBean extends Observable {
 	 * This method adds an empty connection to the current main project.
 	 */
 	public void addConnection() {
-		System.out.println("new conn.");
 		this.connections.add(new Connection(null, null, null, null));
 	}
 
@@ -437,4 +468,64 @@ public class SelectedMainProjectBean extends Observable {
 
 		return result;
 	}
+
+	/**
+	 * This method is used to initialize the object after creation.
+	 */
+	@PostConstruct
+	@SuppressWarnings("FinalPrivateMethod")
+	private final void postConstruct() {
+		// Register this instance as an observer
+		this.observableBean.addObserver(this);
+	}
+
+	/**
+	 * This method is used to finalize the object before destruction.
+	 */
+	@PreDestroy
+	@SuppressWarnings("FinalPrivateMethod")
+	private final void preDestroy() {
+		// Unregister this instance as an observer
+		this.observableBean.deleteObserver(this);
+	}
+
+	@Override
+	public void update(final Observable o, final Object arg) {
+		// If the current main project has just been removed, we have to set the current main project to null.
+		if (arg instanceof ProjectsBean.MsgProjectRemoved && ((ProjectsBean.MsgProjectRemoved) arg).getProject() == this.mainProject) {
+			this.setMainProject(null);
+		}
+	}
+
+	/**
+	 * This helper class is a wrapper for a project and can be send to the observers as a message that the main project selection just has been changed. It contains
+	 * the newly selected main project.
+	 * 
+	 * @author Nils Christian Ehmke
+	 */
+	public static final class MsgMainProjectSelection {
+		/**
+		 * The stored project.
+		 */
+		private final MIProject project;
+
+		/**
+		 * Creates a new instance of this class using the given parameters.
+		 * 
+		 * @param project
+		 *            The project to be stored within this class.
+		 */
+		public MsgMainProjectSelection(final MIProject project) {
+			this.project = project;
+		}
+
+		/**
+		 * Delivers the stored project within this class.
+		 * 
+		 * @return The instance of {@link MIProject}.
+		 */
+		public MIProject getProject() {
+			return this.project;
+		}
+	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedPluginBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedPluginBean.java
index 94d60148..75a92f88 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedPluginBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedPluginBean.java
@@ -108,7 +108,8 @@ public final class SelectedPluginBean implements Observer {
 	 */
 	public void setPlugin(final MIPlugin plugin) {
 		this.plugin = plugin;
-		// Update the element
+
+		// Update the corresponding components
 		final RequestContext requestContext = RequestContext.getCurrentInstance();
 		requestContext.addPartialUpdateTarget(SelectedPluginBean.UPDATE_TARGET);
 	}
@@ -132,7 +133,7 @@ public final class SelectedPluginBean implements Observer {
 	@Override
 	public void update(final Observable o, final Object arg) {
 		// If the main project has been newly selected, we have to set the current plugin to null
-		if (arg == SelectedMainProjectBean.UPDATE_MSG.SELECTION_CHANGED) {
+		if (arg instanceof SelectedMainProjectBean.MsgMainProjectSelection) {
 			this.setPlugin(null);
 		}
 	}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedProjectBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedProjectBean.java
index 7e0875a8..537a3e18 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedProjectBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/SelectedProjectBean.java
@@ -19,17 +19,17 @@
  ***************************************************************************/
 package kieker.webgui.beans.session;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.faces.bean.ManagedBean;
 import javax.faces.bean.SessionScoped;
-import kieker.analysis.model.analysisMetaModel.MIInputPort;
-import kieker.analysis.model.analysisMetaModel.MIOutputPort;
-import kieker.analysis.model.analysisMetaModel.MIPlugin;
+import javax.faces.context.FacesContext;
 
 import kieker.analysis.model.analysisMetaModel.MIProject;
-import kieker.webgui.common.Connection;
-import org.eclipse.emf.common.util.EList;
+import kieker.webgui.beans.application.ProjectsBean;
 
 import org.primefaces.event.NodeSelectEvent;
 import org.primefaces.model.TreeNode;
@@ -42,7 +42,7 @@ import org.primefaces.model.TreeNode;
  */
 @ManagedBean
 @SessionScoped
-public class SelectedProjectBean {
+public class SelectedProjectBean implements Observer {
 
 	/**
 	 * The currently selected node of the current user.
@@ -53,11 +53,15 @@ public class SelectedProjectBean {
 	 */
 	private MIProject selectedProject;
 
+	private final ProjectsBean observableBean;
+
 	/**
 	 * Creates a new instance of this class.
 	 */
 	public SelectedProjectBean() {
-		// No code necessary
+		// Try to get the projects bean.
+		final FacesContext context = FacesContext.getCurrentInstance();
+		this.observableBean = context.getApplication().evaluateExpressionGet(context, "#{projectsBean}", ProjectsBean.class);
 	}
 
 	/**
@@ -112,4 +116,32 @@ public class SelectedProjectBean {
 			this.setSelectedProject(null);
 		}
 	}
+
+	/**
+	 * This method is used to initialize the object after creation.
+	 */
+	@PostConstruct
+	@SuppressWarnings("FinalPrivateMethod")
+	private final void postConstruct() {
+		// Register this instance as an observer
+		this.observableBean.addObserver(this);
+	}
+
+	/**
+	 * This method is used to finalize the object before destruction.
+	 */
+	@PreDestroy
+	@SuppressWarnings("FinalPrivateMethod")
+	private final void preDestroy() {
+		// Unregister this instance as an observer
+		this.observableBean.deleteObserver(this);
+	}
+
+	@Override
+	public void update(final Observable o, final Object arg) {
+		// If the current main project has just been removed, we have to set the current main project to null.
+		if (arg instanceof ProjectsBean.MsgProjectRemoved && ((ProjectsBean.MsgProjectRemoved) arg).getProject() == this.selectedProject) {
+			this.setSelectedProject(null);
+		}
+	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FileManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FileManager.java
index 5ed7d01e..eec6d153 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FileManager.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FileManager.java
@@ -100,9 +100,7 @@ public final class FileManager {
 	 */
 	private void checkAndCreateDirectories() {
 		synchronized (this) {
-			/*
-			 * Make sure that the directories exist and create them if necessary.
-			 */
+			// Make sure that the directories exist and create them if necessary.
 			final File dirProj = new File(FileManager.PROJECT_DIR);
 			final File dirLib = new File(FileManager.LIB_DIR);
 			boolean couldCreated = true;
@@ -133,9 +131,7 @@ public final class FileManager {
 
 			final File dirProject = new File(FileManager.PROJECT_DIR + File.separator + projectName);
 
-			/*
-			 * Make sure that the directory for the project exists.
-			 */
+			// Make sure that the directory for the project exists.
 			if (dirProject.exists()) {
 				/*
 				 * Try to save the project.
@@ -174,16 +170,11 @@ public final class FileManager {
 			final String projectName = project.getName();
 			final File dirProject = new File(FileManager.PROJECT_DIR + File.separator + projectName);
 
-			/*
-			 * Make sure that the project does not already exist and create the
-			 * project directory.
-			 */
+			// Make sure that the project does not already exist and create the project directory.
 			if (dirProject.exists() || !dirProject.mkdir()) {
 				return false;
 			} else {
-				/*
-				 * The directory should exist now. Store the project.
-				 */
+				// The directory should exist now. Store the project.
 				return this.saveProject(project);
 			}
 		}
@@ -197,22 +188,15 @@ public final class FileManager {
 	public final List<MIProject> loadAllProjects() {
 		final List<MIProject> resultList = new ArrayList<MIProject>();
 		synchronized (this) {
-			/*
-			 * Try to get all directories within the project directory.
-			 */
+			// Try to get all directories within the project directory.
 			final File[] directories = new File(FileManager.PROJECT_DIR).listFiles();
 			if (directories != null) {
 				for (final File directory : directories) {
 					if (directory.isDirectory()) {
-						/*
-						 * If there is a project file within the directory, we know
-						 * the name of it.
-						 */
+						// If there is a project file within the directory, we know the name of it.
 						final File projectFile = new File(directory, directory.getName() + FileManager.EXTENSION);
 						if (projectFile.exists()) {
-							/*
-							 * Try to load the project.
-							 */
+							// Try to load the project.
 							MIProject project;
 							try {
 								project = AnalysisController.loadFromFile(projectFile);
@@ -243,17 +227,13 @@ public final class FileManager {
 			BufferedInputStream in = null;
 			BufferedOutputStream out = null;
 			try {
-				/*
-				 * Get the streams.
-				 */
+				// Get the streams.
 				in = new BufferedInputStream(file.getInputstream());
 				out = new BufferedOutputStream(new FileOutputStream(depFile));
 				final byte[] buf = new byte[FileManager.BUF_SIZE];
 				int count;
 
-				/*
-				 * Transfer the file.
-				 */
+				// Transfer the file.
 				while ((count = in.read(buf)) != -1) {
 					out.write(buf, 0, count);
 				}
@@ -262,9 +242,7 @@ public final class FileManager {
 				FileManager.LOG.error("Could not transfer file '" + file.getFileName() + "'");
 				return null;
 			} finally {
-				/*
-				 * Try to make sure that the streams will be closed.
-				 */
+				// Try to make sure that the streams will be closed.
 				try {
 					if (in != null) {
 						in.close();
@@ -303,9 +281,7 @@ public final class FileManager {
 	public final List<MIDependency> loadAllDependencies() {
 		final List<MIDependency> resultList = new ArrayList<MIDependency>();
 		synchronized (this) {
-			/*
-			 * Try to get all files within the library directory.
-			 */
+			// Try to get all files within the library directory.
 			final File[] files = new File(FileManager.LIB_DIR).listFiles();
 			if (files != null) {
 				for (final File file : files) {
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java
index b05df796..1a3dd57a 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java
@@ -60,7 +60,7 @@ public final class PluginClassLoader extends ClassLoader {
 	 */
 	private PluginClassLoader() {
 		this.classLoader = new URLClassLoader(new URL[] {}, AnalysisController.class.getClassLoader());
-		/* Make sure that all libs are loaded. */
+		// Make sure that all libs are loaded.
 		final List<MIDependency> libs = FileManager.getInstance().loadAllDependencies();
 		for (final MIDependency lib : libs) {
 			try {
@@ -113,7 +113,7 @@ public final class PluginClassLoader extends ClassLoader {
 	 * @return The singleton instance of this class.
 	 */
 	public static final PluginClassLoader getInstance() {
-		/* Create the singleton instance if necessary and use a doPrivileged-block. */
+		// Create the singleton instance if necessary and use a doPrivileged-block.
 		synchronized (PluginClassLoader.class) {
 			if (PluginClassLoader.instance == null) {
 				PluginClassLoader.instance = (PluginClassLoader) AccessController.doPrivileged(new PrivilegedAction<Object>() {
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java
index 5d3619c2..50bf53be 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java
@@ -71,9 +71,7 @@ public final class PluginFinder {
 			return repositoryClasses;
 		}
 		try {
-			/*
-			 * Open the jar file and run through all entries within this file.
-			 */
+			// Open the jar file and run through all entries within this file.
 			final JarFile jarFile = new JarFile(new File(url.getPath()));
 			final List<Class<AbstractRepository>> result = new ArrayList<Class<AbstractRepository>>();
 			final Enumeration<JarEntry> jarEntries = jarFile.entries();
@@ -83,16 +81,14 @@ public final class PluginFinder {
 					String name = jarEntry.toString();
 					name = name.replace('/', '.');
 					name = name.replace(".class", "");
-					/*
-					 * Try to find a class with the same name.
-					 */
+					// Try to find a class with the same name.
 					final Class<?> c = PluginClassLoader.getInstance().loadClass(name);
 
 					if (AbstractRepository.class.isAssignableFrom(c)) {
 						result.add((Class<AbstractRepository>) c);
 					}
 				} catch (final Throwable ex) { // NOCS (IllegalCatchCheck)
-					/* Ignore error. */
+					// Ignore error.
 				}
 			}
 			jarFile.close();
@@ -118,9 +114,7 @@ public final class PluginFinder {
 			return pluginClasses;
 		}
 		try {
-			/*
-			 * Open the jar file and run through all entries within this file.
-			 */
+			// Open the jar file and run through all entries within this file.
 			final JarFile jarFile = new JarFile(new File(url.getPath()));
 			final List<Class<AbstractPlugin>> result = new ArrayList<Class<AbstractPlugin>>();
 			final Enumeration<JarEntry> jarEntries = jarFile.entries();
@@ -130,19 +124,14 @@ public final class PluginFinder {
 					String name = jarEntry.toString();
 					name = name.replace('/', '.');
 					name = name.replace(".class", "");
-					/*
-					 * Try to find a class with the same name.
-					 */
+					// Try to find a class with the same name.
 					final Class<?> c = PluginClassLoader.getInstance().loadClass(name);
-					/*
-					 * If it is a class and has the annotation - put it into our
-					 * list.
-					 */
+					// If it is a class and has the annotation - put it into our list.
 					if (c.isAnnotationPresent(Plugin.class) && AbstractPlugin.class.isAssignableFrom(c)) {
 						result.add((Class<AbstractPlugin>) c);
 					}
 				} catch (final Throwable ex) { // NOCS (IllegalCatchCheck)
-					/* Ignore error. */
+					// Ignore error.
 				}
 			}
 			jarFile.close();
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToCountPluginsConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToCountPluginsConverter.java
index 59080212..3883b0cf 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToCountPluginsConverter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToCountPluginsConverter.java
@@ -102,11 +102,11 @@ public class MIDependencyToCountPluginsConverter implements Converter {
 		if (!(o instanceof MIDependency)) {
 			return "";
 		} else {
-			/* Try to find the library within the cache. */
+			// Try to find the library within the cache.
 			if (this.cache.containsKey(o)) {
 				return this.cache.get(o);
 			}
-			/* If the cache is too big, remove one of the objects. */
+			// If the cache is too big, remove one of the objects.
 			if (this.cache.size() > MIDependencyToCountPluginsConverter.MAX_CACHE_SIZE) {
 				this.cache.remove(this.cache.keySet().iterator().next());
 			}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToStringConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToStringConverter.java
index e528e267..004e0185 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToStringConverter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToStringConverter.java
@@ -87,9 +87,7 @@ public class MIDependencyToStringConverter implements Converter {
 	 */
 	@Override
 	public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) {
-		/*
-		 * Make sure that the given object is well-defined.
-		 */
+		// Make sure that the given object is well-defined.
 		if (!(o instanceof MIDependency)) {
 			return "";
 		} else {
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIProjectToStringConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIProjectToStringConverter.java
index 06ba39a5..8b98d93c 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIProjectToStringConverter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIProjectToStringConverter.java
@@ -80,9 +80,7 @@ public class MIProjectToStringConverter implements Converter {
 	 */
 	@Override
 	public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) {
-		/*
-		 * Make sure that the given object is well-defined.
-		 */
+		// Make sure that the given object is well-defined.
 		if (!(o instanceof MIProject)) {
 			return "";
 		} else {
diff --git a/Kieker.WebGUI/src/main/webapp/main.xhtml b/Kieker.WebGUI/src/main/webapp/main.xhtml
index dd046438..af45224a 100644
--- a/Kieker.WebGUI/src/main/webapp/main.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/main.xhtml
@@ -43,7 +43,7 @@
                             <!-- This is the submenu for the current project, for example if someone doesn't want to use the context menu within the browser. -->
                             <p:submenu label="Current Project">
                                 <p:menuitem value="Save Project" ajax="true" action="#{projectsBean.saveProject(selectedProjectBean.getSelectedProject())}" update=":projectsForm" />  
-                                <p:menuitem value="Set as Main Project" ajax="true" action="#{selectedMainProjectBean.setMainProject(selectedProjectBean.getSelectedProject())}" update=":projectsForm" />
+                                <p:menuitem value="Set as Main Project" ajax="true" action="#{selectedMainProjectBean.setMainProject(selectedProjectBean.getSelectedProject())}"/>
                                 <p:separator />
                                 <p:menuitem value="Delete Project" ajax="true" onclick="deleteProjectDialog.show()" />
                                 <p:menuitem value="Reset Project" ajax="true" onclick="resetProjectDialog.show()" />
@@ -88,7 +88,7 @@
 
                         <p:contextMenu for="projectsTree" nodeType="project">
                             <p:menuitem value="Save Project" ajax="true" action="#{projectsBean.saveProject(selectedProjectBean.getSelectedProject())}" update=":projectsForm" />
-                            <p:menuitem value="Set as Main Project" ajax="true" action="#{selectedMainProjectBean.setMainProject(selectedProjectBean.getSelectedProject())}" update=":projectsForm :toolpalette :centerForm" />
+                            <p:menuitem value="Set as Main Project" ajax="true" action="#{selectedMainProjectBean.setMainProject(selectedProjectBean.getSelectedProject())}" />
                             <p:separator />
                             <p:menuitem value="Delete Project" ajax="true" onclick="deleteProjectDialog.show()" />
 
@@ -113,7 +113,7 @@
                 <!-- The following layout unit is within the center and used for the graph. -->
                 <p:layoutUnit position="center" id="centerLayout">
                     <h:form id="centerForm" style="height: 100%">
-                        <div class="canvas" id="mainCanvas" style="width : #{currentWorkspaceSizeBean.sizeX}px;height: #{currentWorkspaceSizeBean.sizeY}px">
+                        <div class="canvas" id="mainCanvas" style="width : 500px;height: 500px">
                             <c:forEach items="#{selectedMainProjectBean.mainProject.plugins}" var="plugin" varStatus="counter">
                                 <p:remoteCommand name="setPlugin#{counter.index}" action="#{selectedPluginBean.setPlugin(plugin)}"/>
                                 <!-- Netbeans reports an error here, but the code does still work though... -->
diff --git a/Kieker.WebGUI/src/main/webapp/main/settingsDialog.xhtml b/Kieker.WebGUI/src/main/webapp/main/settingsDialog.xhtml
index 7d7dfafc..8b3035af 100644
--- a/Kieker.WebGUI/src/main/webapp/main/settingsDialog.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/main/settingsDialog.xhtml
@@ -10,20 +10,13 @@
     <p:dialog id="settingsDialog" header="Settings" resizable="false"
               modal="true" widgetVar="settingsDialog">
         <h:form>
-            <h:panelGrid columns="4" cellpadding="10">
+            <h:panelGrid columns="2" cellpadding="10">
                 <h:outputText value="Look and Feel:" />
                 <p:themeSwitcher value="#{currentThemeBean.theme}"
                                  style="width:150px" effect="fade">
                     <f:selectItem itemLabel="Choose Theme" itemValue="" />
                     <f:selectItems value="#{themeSwitcherBean.themes}" />
                 </p:themeSwitcher>
-                <h:outputText value=""/>
-                <h:outputText value=""/>
-
-                <h:outputText value="Graph Workspace Size:"/>
-                <p:spinner value="#{currentWorkspaceSizeBean.sizeX}" suffix=" px"/>
-                <h:outputText value=" x "/>
-                <p:spinner value="#{currentWorkspaceSizeBean.sizeY}" suffix=" px"/>
             </h:panelGrid>
             <hr/>
             <div style="text-align: right">
-- 
GitLab