From c32a7138d989ed08b1e3b4c808337a7756cd118d Mon Sep 17 00:00:00 2001
From: Nils Christian Ehmke <nie@informatik.uni-kiel.de>
Date: Fri, 22 Jun 2012 20:31:16 +0200
Subject: [PATCH] Added Apache Shiro for test purposes; Replaced toString-IDs
 with Registry-IDs; Added the connections for presentation purposes to the
 analysis editor again;

---
 Kieker.WebGUI/pom.xml                         |  33 ++++-
 .../session/CurrentWorkSpaceProjectBean.java  | 123 +++++++++---------
 .../converter/MIPluginStringConverter.java    |   9 +-
 .../converter/MIPortStringConverter.java      |   9 +-
 .../MIRepositoryStringConverter.java          |   9 +-
 .../src/main/webapp/AnalysisEditor.xhtml      |  34 +++--
 .../src/main/webapp/WEB-INF/shiro.ini         |  17 +++
 Kieker.WebGUI/src/main/webapp/WEB-INF/web.xml |  21 ++-
 8 files changed, 177 insertions(+), 78 deletions(-)
 create mode 100644 Kieker.WebGUI/src/main/webapp/WEB-INF/shiro.ini

diff --git a/Kieker.WebGUI/pom.xml b/Kieker.WebGUI/pom.xml
index 4db2b1b1..15ff01e6 100644
--- a/Kieker.WebGUI/pom.xml
+++ b/Kieker.WebGUI/pom.xml
@@ -25,7 +25,38 @@
         </repository>
     </repositories>
 
-    <dependencies>
+    <dependencies>   
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>1.1.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.6.6</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+            <version>1.2.0</version>
+        </dependency>
         <dependency>
             <groupId>com.ocpsoft</groupId>
             <artifactId>prettyfaces-jsf2</artifactId>
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkSpaceProjectBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkSpaceProjectBean.java
index 8428d428..6a9bd3d0 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkSpaceProjectBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentWorkSpaceProjectBean.java
@@ -29,7 +29,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 import javax.faces.application.FacesMessage;
 import javax.faces.application.FacesMessage.Severity;
@@ -59,6 +58,7 @@ import kieker.analysis.repository.annotation.Repository;
 import kieker.common.configuration.Configuration;
 import kieker.common.logging.Log;
 import kieker.common.logging.LogFactory;
+import kieker.monitoring.core.registry.Registry;
 import kieker.webgui.common.ConnectionFilterToFilter;
 import kieker.webgui.common.ConnectionFilterToRepository;
 import kieker.webgui.common.FSManager;
@@ -121,17 +121,17 @@ public final class CurrentWorkSpaceProjectBean {
 	 */
 	private final List<Class<AbstractReaderPlugin>> availableReaders = Collections.synchronizedList(new ArrayList<Class<AbstractReaderPlugin>>());
 	/**
-	 * This map contains the mapping between the plugins and the result of their toString-method.
+	 * This map contains the mapping between the plugins and their ID.
 	 */
-	private final ConcurrentHashMap<String, MIPlugin> pluginMap = new ConcurrentHashMap<String, MIPlugin>();
+	private Registry<MIPlugin> pluginMap = new Registry<MIPlugin>();
 	/**
-	 * This map contains the mapping between the ports and the result of their toString-method.
+	 * This map contains the mapping between the ports and their ID.
 	 */
-	private final ConcurrentHashMap<String, MIPort> portMap = new ConcurrentHashMap<String, MIPort>();
+	private Registry<MIPort> portMap = new Registry<MIPort>();
 	/**
-	 * This map contains the mapping between the repositories and the result of their toString-method.
+	 * This map contains the mapping between the repositories and their ID.
 	 */
-	private final ConcurrentHashMap<String, MIRepository> repositoryMap = new ConcurrentHashMap<String, MIRepository>();
+	private Registry<MIRepository> repositoryMap = new Registry<MIRepository>();
 	/**
 	 * This field contains the currently selected plugin.
 	 */
@@ -213,26 +213,26 @@ public final class CurrentWorkSpaceProjectBean {
 	private void intializeHashMaps() {
 		synchronized (this) {
 			// Clear all maps
-			this.pluginMap.clear();
-			this.portMap.clear();
-			this.repositoryMap.clear();
+			this.pluginMap = new Registry<MIPlugin>();
+			this.portMap = new Registry<MIPort>();
+			this.repositoryMap = new Registry<MIRepository>();
 
 			// Initialize the plugin map...
 			for (final MIPlugin plugin : this.project.getPlugins()) {
-				this.pluginMap.put(plugin.toString(), plugin);
+				this.pluginMap.get(plugin);
 				// ..and the port map
 				for (final MIPort port : plugin.getOutputPorts()) {
-					this.portMap.put(port.toString(), port);
+					this.portMap.get(port);
 				}
 				if (plugin instanceof MIFilter) {
 					for (final MIPort port : ((MIFilter) plugin).getInputPorts()) {
-						this.portMap.put(port.toString(), port);
+						this.portMap.get(port);
 					}
 				}
 			}
 			// Now initialize the repository map
 			for (final MIRepository repository : this.project.getRepositories()) {
-				this.repositoryMap.put(repository.toString(), repository);
+				this.repositoryMap.get(repository);
 			}
 		}
 	}
@@ -365,7 +365,9 @@ public final class CurrentWorkSpaceProjectBean {
 			this.availableFilters.clear();
 			this.availableReaders.clear();
 			this.availableRepositories.clear();
-			this.pluginMap.clear();
+			this.pluginMap = new Registry<MIPlugin>();
+			this.portMap = new Registry<MIPort>();
+			this.repositoryMap = new Registry<MIRepository>();
 			this.filter2filterConnections.clear();
 			this.filter2repositoryConnections.clear();
 		}
@@ -698,7 +700,7 @@ public final class CurrentWorkSpaceProjectBean {
 		synchronized (this) {
 			// Add it to the project
 			this.project.getRepositories().add(repository);
-			this.repositoryMap.put(repository.toString(), repository);
+			this.repositoryMap.get(repository);
 		}
 	}
 
@@ -726,13 +728,13 @@ public final class CurrentWorkSpaceProjectBean {
 		synchronized (this) {
 			// Add it to the project and don't forget to add the ports.
 			this.project.getPlugins().add(plugin);
-			this.pluginMap.put(plugin.toString(), plugin);
+			this.pluginMap.get(plugin);
 			for (final MIPort port : plugin.getOutputPorts()) {
-				this.portMap.put(port.toString(), port);
+				this.portMap.get(port);
 			}
 			if (plugin instanceof MIFilter) {
 				for (final MIPort port : ((MIFilter) plugin).getInputPorts()) {
-					this.portMap.put(port.toString(), port);
+					this.portMap.get(port);
 				}
 			}
 
@@ -753,8 +755,15 @@ public final class CurrentWorkSpaceProjectBean {
 	public void removeRepository(final MIRepository repository) {
 		synchronized (this) {
 			this.project.getRepositories().remove(repository);
-			// Remove the repository from the map
-			this.repositoryMap.remove(repository.toString());
+
+			// Remove the corresponding connections
+			final List<ConnectionFilterToRepository> fRDelList = new ArrayList<ConnectionFilterToRepository>();
+			for (final ConnectionFilterToRepository conn : this.filter2repositoryConnections) {
+				if (conn.getDestination() == repository) {
+					fRDelList.add(conn);
+				}
+			}
+			this.filter2repositoryConnections.removeAll(fRDelList);
 
 			if (this.selectedRepository == repository) {
 				this.selectedRepository = null; // NOPMD
@@ -771,16 +780,23 @@ public final class CurrentWorkSpaceProjectBean {
 	public void removePlugin(final MIPlugin plugin) {
 		synchronized (this) {
 			this.project.getPlugins().remove(plugin);
-			// Remove the plugin and its ports from the map
-			this.pluginMap.remove(plugin.toString());
-			for (final MIPort port : plugin.getOutputPorts()) {
-				this.portMap.remove(port.toString(), port);
+
+			// Remove the corresponding connections
+			final List<ConnectionFilterToFilter> ffDelList = new ArrayList<ConnectionFilterToFilter>();
+			for (final ConnectionFilterToFilter conn : this.filter2filterConnections) {
+				if ((conn.getSource() == plugin) || (conn.getDestination() == plugin)) {
+					ffDelList.add(conn);
+				}
 			}
-			if (plugin instanceof MIFilter) {
-				for (final MIPort port : ((MIFilter) plugin).getInputPorts()) {
-					this.portMap.remove(port.toString(), port);
+			this.filter2filterConnections.removeAll(ffDelList);
+
+			final List<ConnectionFilterToRepository> fRDelList = new ArrayList<ConnectionFilterToRepository>();
+			for (final ConnectionFilterToRepository conn : this.filter2repositoryConnections) {
+				if (conn.getSource() == plugin) {
+					fRDelList.add(conn);
 				}
 			}
+			this.filter2repositoryConnections.removeAll(fRDelList);
 
 			if (this.selectedPlugin == plugin) {
 				this.selectedPlugin = null; // NOPMD
@@ -945,33 +961,6 @@ public final class CurrentWorkSpaceProjectBean {
 		}
 	}
 
-	/**
-	 * Sets the name of the currently selected plugin/repository. This is only necessary for the correct renaming of the components.
-	 * 
-	 * @param newName
-	 *            The new name of the plugin/repository.
-	 */
-	public void setCurrentPluginName(final String newName) {
-		synchronized (this) {
-			// Rename the plugin/repository and get the old name for the hash map
-			if (this.selectedPlugin != null) {
-				final String oldName = this.selectedPlugin.toString();
-				final MIPlugin plugin = this.pluginMap.get(oldName);
-				this.selectedPlugin.setName(newName);
-
-				// Update the hash map
-				this.pluginMap.put(plugin.toString(), plugin);
-			} else {
-				final String oldName = this.selectedRepository.toString();
-				final MIRepository repository = this.repositoryMap.get(oldName);
-				this.selectedRepository.setName(newName);
-
-				// Update the hash map
-				this.repositoryMap.put(repository.toString(), repository);
-			}
-		}
-	}
-
 	/**
 	 * Delivers the valid connections (between the filters) within the current main project.
 	 * 
@@ -1030,6 +1019,18 @@ public final class CurrentWorkSpaceProjectBean {
 		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(severity, "", msg));
 	}
 
+	public int getPluginID(final MIPlugin plugin) {
+		return this.pluginMap.get(plugin);
+	}
+
+	public int getRepositoryID(final MIRepository repository) {
+		return this.repositoryMap.get(repository);
+	}
+
+	public int getPortID(final MIPort port) {
+		return this.portMap.get(port);
+	}
+
 	/**
 	 * This method searches a plugin by name (the name should be delivered using the toString-method of the object).
 	 * 
@@ -1037,8 +1038,8 @@ public final class CurrentWorkSpaceProjectBean {
 	 *            The name of the plugin.
 	 * @return The plugin with the given name if it exists, null otherwise.
 	 */
-	public MIPlugin getPluginByName(final String string) {
-		return this.pluginMap.get(string);
+	public MIPlugin getPluginByID(final String string) {
+		return this.pluginMap.get(Integer.parseInt(string));
 	}
 
 	/**
@@ -1048,8 +1049,8 @@ public final class CurrentWorkSpaceProjectBean {
 	 *            The name of the port.
 	 * @return The port with the given name if it exists, null otherwise.
 	 */
-	public MIPort getPortByName(final String string) {
-		return this.portMap.get(string);
+	public MIPort getPortByID(final String string) {
+		return this.portMap.get(Integer.parseInt(string));
 	}
 
 	/**
@@ -1059,7 +1060,7 @@ public final class CurrentWorkSpaceProjectBean {
 	 *            The name of the repository.
 	 * @return The plugin with the given name if it exists, null otherwise.
 	 */
-	public MIRepository getRepositoryByName(final String string) {
-		return this.repositoryMap.get(string);
+	public MIRepository getRepositoryByID(final String string) {
+		return this.repositoryMap.get(Integer.parseInt(string));
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPluginStringConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPluginStringConverter.java
index bd9a3f9a..25bbaa1b 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPluginStringConverter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPluginStringConverter.java
@@ -26,6 +26,7 @@ import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.FacesConverter;
 
+import kieker.analysis.model.analysisMetaModel.MIPlugin;
 import kieker.webgui.beans.session.CurrentWorkSpaceProjectBean;
 
 /**
@@ -54,15 +55,19 @@ public class MIPluginStringConverter implements Converter {
 		final CurrentWorkSpaceProjectBean bean = (CurrentWorkSpaceProjectBean) el.getValue(FacesContext.getCurrentInstance().getELContext(), null,
 				"currentWorkSpaceProjectBean");
 
-		return bean.getPluginByName(string);
+		return bean.getPluginByID(string);
 	}
 
 	@Override
 	public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) {
+		final ELResolver el = FacesContext.getCurrentInstance().getApplication().getELResolver();
+		final CurrentWorkSpaceProjectBean bean = (CurrentWorkSpaceProjectBean) el.getValue(FacesContext.getCurrentInstance().getELContext(), null,
+				"currentWorkSpaceProjectBean");
+
 		if (o == null) {
 			return "";
 		} else {
-			return o.toString();
+			return Integer.toString(bean.getPluginID((MIPlugin) o));
 		}
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPortStringConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPortStringConverter.java
index 3f43960a..e8325d8f 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPortStringConverter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPortStringConverter.java
@@ -26,6 +26,7 @@ import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.FacesConverter;
 
+import kieker.analysis.model.analysisMetaModel.MIPort;
 import kieker.webgui.beans.session.CurrentWorkSpaceProjectBean;
 
 /**
@@ -54,15 +55,19 @@ public class MIPortStringConverter implements Converter {
 		final CurrentWorkSpaceProjectBean bean = (CurrentWorkSpaceProjectBean) el.getValue(FacesContext.getCurrentInstance()
 				.getELContext(), null, "currentWorkSpaceProjectBean");
 
-		return bean.getPortByName(string);
+		return bean.getPortByID(string);
 	}
 
 	@Override
 	public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) {
+		final ELResolver el = FacesContext.getCurrentInstance().getApplication().getELResolver();
+		final CurrentWorkSpaceProjectBean bean = (CurrentWorkSpaceProjectBean) el.getValue(FacesContext.getCurrentInstance().getELContext(), null,
+				"currentWorkSpaceProjectBean");
+
 		if (o == null) {
 			return "";
 		} else {
-			return o.toString();
+			return Integer.toString(bean.getPortID((MIPort) o));
 		}
 	}
 }
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIRepositoryStringConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIRepositoryStringConverter.java
index 51b25e76..60a515c2 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIRepositoryStringConverter.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIRepositoryStringConverter.java
@@ -26,6 +26,7 @@ import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.FacesConverter;
 
+import kieker.analysis.model.analysisMetaModel.MIRepository;
 import kieker.webgui.beans.session.CurrentWorkSpaceProjectBean;
 
 /**
@@ -54,15 +55,19 @@ public class MIRepositoryStringConverter implements Converter {
 		final CurrentWorkSpaceProjectBean bean = (CurrentWorkSpaceProjectBean) el.getValue(FacesContext.getCurrentInstance()
 				.getELContext(), null, "currentWorkSpaceProjectBean");
 
-		return bean.getRepositoryByName(string);
+		return bean.getRepositoryByID(string);
 	}
 
 	@Override
 	public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) {
+		final ELResolver el = FacesContext.getCurrentInstance().getApplication().getELResolver();
+		final CurrentWorkSpaceProjectBean bean = (CurrentWorkSpaceProjectBean) el.getValue(FacesContext.getCurrentInstance().getELContext(), null,
+				"currentWorkSpaceProjectBean");
+
 		if (o == null) {
 			return "";
 		} else {
-			return o.toString();
+			return Integer.toString(bean.getRepositoryID((MIRepository) o));
 		}
 	}
 }
diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml
index 3603add5..d7179a7b 100644
--- a/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/AnalysisEditor.xhtml
@@ -4,7 +4,8 @@
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
-      xmlns:p="http://primefaces.org/ui">
+      xmlns:p="http://primefaces.org/ui"
+      xmlns:c="http://java.sun.com/jsp/jstl/core">
 
     <h:head>
         <title>Kieker.WebGUI</title>
@@ -13,12 +14,12 @@
         <script type="text/javascript" src="../js/js-graph-it.js"/> 
         <link rel="stylesheet" type="text/css" href="../css/js-graph-it.css"/>
         <style>
-            .canvas {
-                font-family: tahoma;
-            }
             .block { 
                 position: absolute;
             }
+            .connector {
+                background-color: #FF9900;
+            }
         </style>
     </h:head>
 
@@ -32,9 +33,9 @@
                             <h:outputText styleClass="kieker-title" value="Kieker &raquo; #{stringBean.shortenLongName(currentWorkSpaceProjectBean.projectName, 30)}"/>
                         </p:toolbarGroup>
                         <p:toolbarGroup align="right">
-                            <p:commandButton styleClass="perspective-button" icon="ui-icon-home" disabled="true" />
+                            <p:commandButton styleClass="perspective-button" icon="ui-icon-home" />
                             <p:separator/>
-                            <p:commandButton styleClass="perspective-button" icon="ui-icon-wrench" value="Analysis Editor" style="white-space: none" ajax="false" action="#{currentWorkSpaceProjectBean.setProject(projectsBean.openProject(project), project)}"/>
+                            <p:commandButton styleClass="perspective-button" icon="ui-icon-wrench" value="Analysis Editor" style="white-space: none" disabled="true"  ajax="false" action="#{currentWorkSpaceProjectBean.setProject(projectsBean.openProject(project), project)}"/>
                             <p:commandButton styleClass="perspective-button" icon="ui-icon-circle-triangle-e" value="Analysis" ajax="false" action="#{currentControllerBean.setProject(projectsBean.openProject(project), project)}" />
                             <p:separator/>
                             <p:commandButton styleClass="perspective-button" icon="ui-icon-wrench" value="Cockpit Editor" ajax="false" action="#{currentCockpitEditorBean.setProject(projectsBean.openProject(project), project)}" />
@@ -75,7 +76,7 @@
                         <ui:repeat value="#{currentWorkSpaceProjectBean.project.plugins}" var="plugin" varStatus="counter">
                             <p:remoteCommand name="setPlugin#{counter.index}" action="#{currentWorkSpaceProjectBean.setSelectedPlugin(plugin)}" update=":propertiesForm"/>
                             <!-- Netbeans reports an error here, but the code does still work though... -->
-                            <div onclick="setPlugin#{counter.index}();" style="left: #{counter.index * 90}px; top: #{counter.index * 70}px; position: absolute" class="ui-panel ui-widget ui-widget-content ui-corner-all block draggable" id="#{stringToIDBean.stringToID(plugin)}" >
+                            <div onclick="setPlugin#{counter.index}();" style="left: #{counter.index * 90}px; top: #{counter.index * 70}px; position: absolute" class="ui-panel ui-widget ui-widget-content ui-corner-all block draggable" id="plugin#{currentWorkSpaceProjectBean.getPluginID(plugin)}" >
                                 <div class="ui-panel-titlebar ui-widget-header ui-corner-all">
                                     <h:outputText style="font-weight: bold" value="#{plugin.getName()}"/>
                                 </div>
@@ -85,13 +86,28 @@
                         <ui:repeat value="#{currentWorkSpaceProjectBean.project.repositories}" var="repository" varStatus="counter">
                             <p:remoteCommand name="setRepository#{counter.index}" action="#{currentWorkSpaceProjectBean.setSelectedRepository(repository)}" update=":propertiesForm"/>
                             <!-- Netbeans reports an error here, but the code does still work though... -->
-                            <div onclick="setRepository#{counter.index}();" style="left: #{(currentWorkSpaceProjectBean.project.plugins.size() + counter.index) * 90}px; top: #{counter.index * 70}px; position: absolute" class="ui-panel ui-widget ui-widget-content ui-corner-all block draggable" id="#{stringToIDBean.stringToID(repository)}" >
+                            <div onclick="setRepository#{counter.index}();" style="left: #{(currentWorkSpaceProjectBean.project.plugins.size() + counter.index) * 90}px; top: #{counter.index * 70}px; position: absolute" class="ui-panel ui-widget ui-widget-content ui-corner-all block draggable" id="repository#{currentWorkSpaceProjectBean.getRepositoryID(repository)}" >
                                 <div class="ui-panel-titlebar ui-widget-header ui-corner-all">
                                     <h:outputText style="font-weight: bold" value="#{repository.getName()}"/>
                                 </div>
                                 <p:commandLink ajax="true" value="Remove" action="#{currentWorkSpaceProjectBean.removeRepository(repository)}"  update=":propertiesForm :centerForm"/>
                             </div>
                         </ui:repeat>
+
+                        <ui:repeat value="#{currentWorkSpaceProjectBean.filterConnections}" var="connection">
+                            <div class="connector plugin#{currentWorkSpaceProjectBean.getPluginID(connection.source)} plugin#{currentWorkSpaceProjectBean.getPluginID(connection.destination)}">
+                                <label class="source-label"><h:outputText value="#{connection.outputPort.getName()}"/></label>
+                                <label class="destination-label"><h:outputText value="#{connection.inputPort.getName()}"/></label>
+                                <img src="../img/arrow.gif" class="connector-end"/>
+                            </div>
+                        </ui:repeat>
+
+                        <ui:repeat value="#{currentWorkSpaceProjectBean.repoConnections}" var="connection">
+                            <div class="connector plugin#{currentWorkSpaceProjectBean.getPluginID(connection.source)} repository#{currentWorkSpaceProjectBean.getRepositoryID(connection.destination)}">
+                                <label class="source-label"><h:outputText value="#{connection.outputPort.getName()}"/></label>
+                                <img src="../img/arrow.gif" class="connector-end"/>
+                            </div>
+                        </ui:repeat>
                     </div>
                 </h:form> 
             </p:layoutUnit>                 
@@ -112,7 +128,7 @@
                                 </f:facet>
                                 <f:facet name="input">
                                     <h:inputText value="#{property.value}" rendered="#{not stringBean.checkString(property)}"/>
-                                    <h:inputText value="#{currentWorkSpaceProjectBean.currentPluginName}" rendered="#{stringBean.checkString(property)}"/>
+                                    <h:inputText value="#{currentWorkSpaceProjectBean.selectedPlugin.name}" rendered="#{stringBean.checkString(property)}"/>
                                 </f:facet>  
                             </p:cellEditor>
                         </p:column>
diff --git a/Kieker.WebGUI/src/main/webapp/WEB-INF/shiro.ini b/Kieker.WebGUI/src/main/webapp/WEB-INF/shiro.ini
new file mode 100644
index 00000000..d9c8f025
--- /dev/null
+++ b/Kieker.WebGUI/src/main/webapp/WEB-INF/shiro.ini
@@ -0,0 +1,17 @@
+# =======================
+# Shiro INI configuration
+# =======================
+
+[main]
+
+authc.loginUrl = /Kieker.WebGUI/login
+
+securityManager.rememberMeManager.cookie.name = KiekerWebGuiLoginCookie
+securityManager.rememberMeManager.cookie.maxAge = 10000
+
+[users]
+Nils = kieker
+
+[roles]
+
+[urls]
diff --git a/Kieker.WebGUI/src/main/webapp/WEB-INF/web.xml b/Kieker.WebGUI/src/main/webapp/WEB-INF/web.xml
index e19427b2..3f5fc4d3 100644
--- a/Kieker.WebGUI/src/main/webapp/WEB-INF/web.xml
+++ b/Kieker.WebGUI/src/main/webapp/WEB-INF/web.xml
@@ -26,7 +26,7 @@
     </filter-mapping>
     
     <!-- This here makes sure that the theme chooser of PrimeFaces will work. -->
-   <context-param>
+    <context-param>
         <param-name>primefaces.THEME</param-name>
         <param-value>#{currentThemeBean.theme}</param-value>
     </context-param>
@@ -70,4 +70,23 @@
         <dispatcher>ERROR</dispatcher>
     </filter-mapping>
     
+    <!-- The following is necessary for Apache Shiro. -->
+    <listener>
+        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>ShiroFilter</filter-name>
+        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>ShiroFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher> 
+        <dispatcher>FORWARD</dispatcher> 
+        <dispatcher>INCLUDE</dispatcher> 
+        <dispatcher>ERROR</dispatcher>
+    </filter-mapping>
+    
 </web-app>
-- 
GitLab