From 9448e2a0113c24904aad8dab1cbb26591071680c Mon Sep 17 00:00:00 2001
From: Nils Christian Ehmke <nie@informatik.uni-kiel.de>
Date: Sun, 17 Mar 2013 16:38:34 +0100
Subject: [PATCH] Added some comments; Modified the visual appearance.

---
 .../webgui/persistence/IProjectDAO.java       | 10 +++
 .../persistence/impl/FSProjectDAOImpl.java    | 67 +++++++++----------
 .../webgui/service/IProjectService.java       | 15 +++++
 .../service/impl/ProjectServiceImpl.java      |  1 +
 .../web/beans/application/ProjectsBean.java   |  3 +
 .../beans/view/CurrentAnalysisEditorBean.java |  4 ++
 .../beans/view/CurrentCockpitEditorBean.java  |  6 ++
 .../main/webapp/pages/CockpitEditorPage.xhtml | 42 +++++++-----
 8 files changed, 93 insertions(+), 55 deletions(-)

diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java
index 527e34e2..7b6494a5 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java
@@ -55,6 +55,16 @@ public interface IProjectDAO {
 	@PreAuthorize("hasAnyRole('User', 'Administrator')")
 	public abstract void addProject(String projectName, final String username) throws ProjectAlreadyExistingException, IOException;
 
+	/**
+	 * This method removes the given project from the application. This is done by simply removing the whole project directory. It is possible that this action fails
+	 * for various reasons - in this cases it is not guaranteed that the project is still in a valid state.
+	 * 
+	 * @param projectName
+	 *            The name of the project.
+	 * 
+	 * @throws IOException
+	 *             If something went wrong during the removing.
+	 */
 	@PreAuthorize("hasAnyRole('User', 'Administrator')")
 	public abstract void removeProject(String projectName) throws IOException;
 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java
index 222a3e97..d831a6f9 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java
@@ -723,14 +723,42 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 	 */
 	@Override
 	public String getLayout(final String projectName) {
+		return FSProjectDAOImpl.getProperty(projectName, FSProjectDAOImpl.PROPERTY_KEY_LAYOUT, null);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see kieker.webgui.persistence.IProjectDAO#getOwner(java.lang.String)
+	 */
+	@Override
+	public String getOwner(final String projectName) {
+		return FSProjectDAOImpl.getProperty(projectName, FSProjectDAOImpl.PROPERTY_KEY_OWNER, "N/A");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see kieker.webgui.persistence.IProjectDAO#getLastUser(java.lang.String)
+	 */
+	@Override
+	public String getLastUser(final String projectName) {
+		return FSProjectDAOImpl.getProperty(projectName, FSProjectDAOImpl.PROPERTY_KEY_LAST_USER, "N/A");
+	}
+
+	private static String getProperty(final String projectName, final String propertyKey, final String defaultValue) {
 		try {
 			final Properties properties = FSProjectDAOImpl.loadPropertiesFile(projectName);
-			return properties.getProperty(FSProjectDAOImpl.PROPERTY_KEY_LAYOUT);
+			final String value = properties.getProperty(propertyKey);
+
+			if (value != null) {
+				return value;
+			}
 		} catch (final IOException ex) {
 			FSProjectDAOImpl.LOG.warn("Could not open meta file.", ex);
 		}
 
-		return null;
+		return defaultValue;
 	}
 
 	/*
@@ -782,45 +810,10 @@ public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener {
 		}
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see kieker.webgui.persistence.IProjectDAO#getOwner(java.lang.String)
-	 */
-	@Override
-	public String getOwner(final String projectName) {
-		try {
-			final Properties properties = FSProjectDAOImpl.loadPropertiesFile(projectName);
-			return properties.getProperty(FSProjectDAOImpl.PROPERTY_KEY_OWNER);
-		} catch (final IOException ex) {
-			FSProjectDAOImpl.LOG.warn("Could not open meta file.", ex);
-		}
-
-		return "N/A";
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see kieker.webgui.persistence.IProjectDAO#getLastUser(java.lang.String)
-	 */
-	@Override
-	public String getLastUser(final String projectName) {
-		try {
-			final Properties properties = FSProjectDAOImpl.loadPropertiesFile(projectName);
-			return properties.getProperty(FSProjectDAOImpl.PROPERTY_KEY_LAST_USER);
-		} catch (final IOException ex) {
-			FSProjectDAOImpl.LOG.warn("Could not open meta file.", ex);
-		}
-
-		return "N/A";
-	}
-
 	/**
 	 * This helper class is responsible for creating a classloader as a privileged action. This is recommended due to the java security manager.
 	 * 
 	 * @author Nils Christian Ehmke
-	 * @version 1.0
 	 */
 	private static class PrivilegedClassLoaderAction implements PrivilegedAction<CloseableURLClassLoader> {
 		/**
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java
index 9c26f018..9b371f5d 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java
@@ -52,6 +52,7 @@ public interface IProjectService {
 	 *            The name of the new project.
 	 * @param username
 	 *            The name of the user who created the project.
+	 * 
 	 * @throws ProjectAlreadyExistingException
 	 *             If a project with the same name exists already.
 	 * @throws IOException
@@ -60,6 +61,18 @@ public interface IProjectService {
 	@PreAuthorize("hasAnyRole('User', 'Administrator')")
 	public void addProject(final String projectName, final String username) throws ProjectAlreadyExistingException, IOException;
 
+	/**
+	 * This method removes the given project from the application. This is done by simply removing the whole project directory. It is possible that this action fails
+	 * for various reasons - in this cases it is not guaranteed that the project is still in a valid state.
+	 * 
+	 * @param projectName
+	 *            The name of the project.
+	 * 
+	 * @throws ProjectNotExistingException
+	 *             If a project with the given name doesn't exist.
+	 * @throws IOException
+	 *             If something went wrong during the removing.
+	 */
 	@PreAuthorize("hasAnyRole('User', 'Administrator')")
 	public void delProject(final String projectName) throws ProjectNotExistingException, IOException;
 
@@ -73,6 +86,7 @@ public interface IProjectService {
 	 *            The name of the user who imported the project.
 	 * @param file
 	 *            The kax file to be uploaded.
+	 * 
 	 * @throws ProjectAlreadyExistingException
 	 *             If a project with the same name exists already.
 	 * @throws IOException
@@ -89,6 +103,7 @@ public interface IProjectService {
 	 *            The name of the source project.
 	 * @param newProjectName
 	 *            The name of the target project.
+	 * 
 	 * @throws ProjectNotExistingException
 	 *             If a project with the given (source) name doesn't exist.
 	 * @throws ProjectAlreadyExistingException
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java
index e8d03685..dc9f4e5b 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java
@@ -45,6 +45,7 @@ import org.primefaces.model.UploadedFile;
  * 
  * @author Nils Christian Ehmke
  */
+// TODO Remove the lock objects for removed projects as well (take a look at #591).
 @Service
 public final class ProjectServiceImpl implements IProjectService {
 
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java
index f4287206..10ad8129 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java
@@ -117,6 +117,9 @@ public final class ProjectsBean {
 		}
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public void delProject(final String project, final CurrentProjectOverviewBean currentProjectOverviewBean) {
 		try {
 			// Try and use the project service to delete the project atomically.
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java
index d099f388..5111c21d 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java
@@ -125,10 +125,14 @@ public final class CurrentAnalysisEditorBean {
 			}
 		} catch (final ProjectLoadException ex) {
 			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex);
+			// FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), null,
+			// "projectOverview");
 			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException());
 		} catch (final NullPointerException ex) {
 			// This exception can occur, when a property has not been initialized
 			CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex);
+			// FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), null,
+			// "projectOverview");
 			GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException());
 		}
 	}
diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
index f0705521..ad9ec6f0 100644
--- a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
+++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java
@@ -334,6 +334,12 @@ public final class CurrentCockpitEditorBean {
 		return this.activeView;
 	}
 
+	/**
+	 * Sets the active view and updates the dashboard.
+	 * 
+	 * @param view
+	 *            The new view.
+	 */
 	public synchronized void setActiveView(final MIView view) {
 		this.activeView = view;
 
diff --git a/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml
index 4bc16393..69baecb4 100644
--- a/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml
+++ b/Kieker.WebGUI/src/main/webapp/pages/CockpitEditorPage.xhtml
@@ -63,31 +63,37 @@
                                 nodeSelected([{name : 'id', value : event.currentTarget.id}]);
                             });
                         </script>
-                        <h:outputText value="Description: "/>  
-                        <p:inplace id="basic" editor="true">  
-                            <p:inputText value="#{currentCockpitEditorBean.activeView.description}" />  
-                        </p:inplace>  
-                        <br/>
-                        <hr/>
                         <p:dashboard id="dynamicDashboard" binding="#{currentCockpitEditorBean.dashboard}"/>
                     </ui:fragment>
                 </h:form>
             </ui:define>
 
             <ui:define name="furtherLayoutUnits">
-                <p:layoutUnit position="west" resizable="true" size="300" collapsible="true" header="Available Views">
+                <p:layoutUnit position="west" resizable="true" maxSize="350" collapsible="true">
                     <h:form id="availableViewsForm">
-                        <p:dataList value="#{currentCockpitEditorBean.project.views}" var="viewElem"> 
-                            <p:commandLink id="dynaButton" value="#{viewElem.name}"/>
-
-                            <p:menu overlay="true" trigger="dynaButton" my="left top" at="left bottom" style="width:210px">        
-                                <p:menuitem icon="ui-icon-analysisEditor" value="  #{localizedCockpitEditorPageMessages.selectView}" action="#{currentCockpitEditorBean.setActiveView(viewElem)}" styleClass="element-with-whitespace" update=":messages :centerForm"/>
-                                <p:separator/>
-                                <p:menuitem  icon="ui-icon-copy"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.copyView}" />
-                                <p:menuitem  icon="ui-icon-edit"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.renameView}"/>
-                                <p:menuitem  icon="ui-icon-delete"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.deleteView}" action="#{currentCockpitEditorBean.deleteView(viewElem)}"/> 
-                            </p:menu>
-                        </p:dataList>
+                        <p:dataTable value="#{currentCockpitEditorBean.project.views}" var="viewElem">
+                            <p:column headerText="View">
+                                <div align="center">
+                                    <p:commandLink id="dynaButton" value="#{viewElem.name}"/>
+
+                                    <p:menu overlay="true" trigger="dynaButton" my="left top" at="left bottom" style="width:210px">        
+                                        <p:menuitem icon="ui-icon-analysisEditor" value="  #{localizedCockpitEditorPageMessages.selectView}" action="#{currentCockpitEditorBean.setActiveView(viewElem)}" styleClass="element-with-whitespace" update=":messages :centerForm"/>
+                                        <p:separator/>
+                                        <p:menuitem  icon="ui-icon-copy"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.copyView}" />
+                                        <p:menuitem  icon="ui-icon-edit"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.renameView}"/>
+                                        <p:menuitem  icon="ui-icon-delete"  styleClass="element-with-whitespace" value="  #{localizedCockpitEditorPageMessages.deleteView}" action="#{currentCockpitEditorBean.deleteView(viewElem)}"/> 
+                                    </p:menu>
+                                </div>
+                            </p:column>
+                            <p:column headerText="# Elements"><div align="center">#{viewElem.displayConnectors.size()}</div></p:column>
+                            <p:column headerText="Description">
+                                <div align="center">
+                                    <p:inplace id="normalEditor" editor="true">  
+                                        <p:inputText value="#{viewElem.description}" />
+                                    </p:inplace>  
+                                </div>
+                            </p:column>  
+                        </p:dataTable>
                     </h:form>
                 </p:layoutUnit>
 
-- 
GitLab