From 37ee2ab2c947a3fa6e6a7150d28b6bdd67a8093c Mon Sep 17 00:00:00 2001 From: Nils Christian Ehmke <nie@informatik.uni-kiel.de> Date: Mon, 4 Jun 2012 11:38:29 +0200 Subject: [PATCH] Added synchronizations within session-beans; Repositories can now be removed; Corrected some hash map bugs within CurrentWorkSpaceProjectBean; Made sure that the converters deliver a valid string in case of null; Renamed some xhtml-components; Started with the AnalysisViewWorkSpace --- .../beans/session/CurrentThemeBean.java | 20 +- .../session/CurrentWorkSpaceProjectBean.java | 402 +++++++++++------- .../java/kieker/webgui/common/ACManager.java | 55 +++ .../java/kieker/webgui/common/FSManager.java | 4 +- .../converter/MIPluginStringConverter.java | 6 +- .../converter/MIPortStringConverter.java | 6 +- .../MIRepositoryStringConverter.java | 6 +- .../src/main/webapp/AnalysisCockpit.xhtml | 4 +- .../src/main/webapp/AnalysisController.xhtml | 4 +- .../main/webapp/AnalysisViewWorkSpace.xhtml | 80 ++++ .../src/main/webapp/ProjectOverview.xhtml | 20 +- .../src/main/webapp/ProjectWorkSpace.xhtml | 6 +- .../src/main/webapp/dialogs/aboutDialog.xhtml | 4 +- .../dialogs/manageLibrariesDialog.xhtml | 2 +- .../main/webapp/dialogs/projectDialogs.xhtml | 8 +- .../main/webapp/dialogs/settingsDialog.xhtml | 4 +- 16 files changed, 428 insertions(+), 203 deletions(-) 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 694976cf..99e7a72a 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 @@ -97,15 +99,17 @@ public final class CurrentThemeBean { * The new theme to be stored within this instance. */ public final void setTheme(final String theme) { - this.theme = theme; + synchronized (this) { + this.theme = theme; - // Set the theme cookie. - final Cookie cookie = new Cookie(CurrentThemeBean.KEY_COOKIE_THEME, theme); - // Try to save it for a year (maximum age) - cookie.setMaxAge(60 * 60 * 24 * 365); + // Set the theme cookie. + final Cookie cookie = new Cookie(CurrentThemeBean.KEY_COOKIE_THEME, theme); + // Try to save it for a year (maximum age) + cookie.setMaxAge(60 * 60 * 24 * 365); - // Deliver the cookie - final HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); - response.addCookie(cookie); + // Deliver the cookie + final HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); + response.addCookie(cookie); + } } } 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 df40ff44..955519a8 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 @@ -75,7 +75,7 @@ import org.eclipse.emf.ecore.EObject; * @author Nils Christian Ehmke * @version 1.0 */ -// TODO Update port map and repository map on add/delete +// TODO Clean the connections when someone removes a plugin/repository @ManagedBean @SessionScoped public final class CurrentWorkSpaceProjectBean { @@ -175,59 +175,63 @@ public final class CurrentWorkSpaceProjectBean { * @return The name of the page for the project work space, if the project has been accepted, '' if it is null. */ public String setProject(final MIProject newProject, final String newName) { - // Remember the given parameters - this.project = newProject; - this.projectName = newName; - this.getConnectionsFromProject(); - - if (this.project != null) { - // Remember the current time! This is important for the later comparison of the time stamps. - this.resetTimeStamp(); - // Update the class loader - this.reloadClassLoader(); - // Add the libraries within the lib-folder to the current model - this.addLibrariesToModel(); - // Load the available readers, filters and repositories - this.loadToolPalette(); - // Load the hashmaps to get the plugins and ports - this.intializeHashMaps(); - } + synchronized (this) { + // Remember the given parameters + this.project = newProject; + this.projectName = newName; + this.getConnectionsFromProject(); + + if (this.project != null) { + // Remember the current time! This is important for the later comparison of the time stamps. + this.resetTimeStamp(); + // Update the class loader + this.reloadClassLoader(); + // Add the libraries within the lib-folder to the current model + this.addLibrariesToModel(); + // Load the available readers, filters and repositories + this.loadToolPalette(); + // Load the hashmaps to get the plugins and ports + this.intializeHashMaps(); + } - // Now deliver the correct navigation page - final String navigationPage; - if (this.project != null) { - navigationPage = CurrentWorkSpaceProjectBean.PAGE_PROJECT_WORK_SPACE; - } else { - navigationPage = ""; + // Now deliver the correct navigation page + final String navigationPage; + if (this.project != null) { + navigationPage = CurrentWorkSpaceProjectBean.PAGE_PROJECT_WORK_SPACE; + } else { + navigationPage = ""; + } + return navigationPage; } - return navigationPage; } /** * This method initializes the hash maps of the plugins, the ports and the repositories. The maps are cleaned beforehand. */ private void intializeHashMaps() { - // Clear all maps - this.pluginMap.clear(); - this.portMap.clear(); - this.repositoryMap.clear(); - - // Initialize the plugin map... - for (final MIPlugin plugin : this.project.getPlugins()) { - this.pluginMap.put(plugin.toString(), plugin); - // ..and the port map - for (final MIPort port : plugin.getOutputPorts()) { - this.portMap.put(port.toString(), port); - } - if (plugin instanceof MIFilter) { - for (final MIPort port : ((MIFilter) plugin).getInputPorts()) { + synchronized (this) { + // Clear all maps + this.pluginMap.clear(); + this.portMap.clear(); + this.repositoryMap.clear(); + + // Initialize the plugin map... + for (final MIPlugin plugin : this.project.getPlugins()) { + this.pluginMap.put(plugin.toString(), plugin); + // ..and the port map + for (final MIPort port : plugin.getOutputPorts()) { this.portMap.put(port.toString(), port); } + if (plugin instanceof MIFilter) { + for (final MIPort port : ((MIFilter) plugin).getInputPorts()) { + this.portMap.put(port.toString(), port); + } + } + } + // Now initialize the repository map + for (final MIRepository repository : this.project.getRepositories()) { + this.repositoryMap.put(repository.toString(), repository); } - } - // Now initialize the repository map - for (final MIRepository repository : this.project.getRepositories()) { - this.repositoryMap.put(repository.toString(), repository); } } @@ -235,16 +239,18 @@ public final class CurrentWorkSpaceProjectBean { * This method loads the list of available readers, filters and repositories, using the current libraries within the model. */ private void loadToolPalette() { - // Clean our tool palette - this.availableFilters.clear(); - this.availableReaders.clear(); - this.availableRepositories.clear(); - - // Make sure there is a project. - if (this.project != null) { - // Run through all libraries - for (final MIDependency lib : this.project.getDependencies()) { - this.addToToolPalette(lib); + synchronized (this) { + // Clean our tool palette + this.availableFilters.clear(); + this.availableReaders.clear(); + this.availableRepositories.clear(); + + // Make sure there is a project. + if (this.project != null) { + // Run through all libraries + for (final MIDependency lib : this.project.getDependencies()) { + this.addToToolPalette(lib); + } } } } @@ -256,30 +262,32 @@ public final class CurrentWorkSpaceProjectBean { * The library used to load the plugins and repositories. */ private void addToToolPalette(final MIDependency lib) { - try { - final List<Class<AbstractRepository>> repositories = PluginFinder.getAllRepositoriesWithinJar(FSManager.getInstance().getURL(lib, this.projectName), - this.classLoader); - final List<Class<AbstractPlugin>> plugins = PluginFinder.getAllPluginsWithinJar(FSManager.getInstance().getURL(lib, this.projectName), - this.classLoader); - // Now run through the available classes and add all non-abstract classes to our lists - for (final Class<AbstractRepository> repository : repositories) { - if (!Modifier.isAbstract(repository.getModifiers())) { - this.availableRepositories.add(repository); + synchronized (this) { + try { + final List<Class<AbstractRepository>> repositories = PluginFinder.getAllRepositoriesWithinJar(FSManager.getInstance().getURL(lib, this.projectName), + this.classLoader); + final List<Class<AbstractPlugin>> plugins = PluginFinder.getAllPluginsWithinJar(FSManager.getInstance().getURL(lib, this.projectName), + this.classLoader); + // Now run through the available classes and add all non-abstract classes to our lists + for (final Class<AbstractRepository> repository : repositories) { + if (!Modifier.isAbstract(repository.getModifiers())) { + this.availableRepositories.add(repository); + } } - } - for (final Class<? extends AbstractPlugin> plugin : plugins) { - if (!Modifier.isAbstract(plugin.getModifiers())) { - if (AbstractFilterPlugin.class.isAssignableFrom(plugin)) { - this.availableFilters.add((Class<AbstractFilterPlugin>) plugin); - } else { - if (AbstractReaderPlugin.class.isAssignableFrom(plugin)) { - this.availableReaders.add((Class<AbstractReaderPlugin>) plugin); + for (final Class<? extends AbstractPlugin> plugin : plugins) { + if (!Modifier.isAbstract(plugin.getModifiers())) { + if (AbstractFilterPlugin.class.isAssignableFrom(plugin)) { + this.availableFilters.add((Class<AbstractFilterPlugin>) plugin); + } else { + if (AbstractReaderPlugin.class.isAssignableFrom(plugin)) { + this.availableReaders.add((Class<AbstractReaderPlugin>) plugin); + } } } } + } catch (final MalformedURLException ex) { + ex.printStackTrace(); } - } catch (final MalformedURLException ex) { - ex.printStackTrace(); } } @@ -287,11 +295,13 @@ public final class CurrentWorkSpaceProjectBean { * This method takes all libraries from the lib-folder and adds them to the in-memory-model. */ private void addLibrariesToModel() { - final List<MIDependency> libs = FSManager.getInstance().getModelLibraries(this.projectName); - // Add them, but remove all existing dependencies so far to avoid double entries. This also makes sure that the model - after it has been opened - points - // just to valid dependencies (and to all of them). - this.project.getDependencies().clear(); - this.project.getDependencies().addAll(libs); + synchronized (this) { + final List<MIDependency> libs = FSManager.getInstance().getModelLibraries(this.projectName); + // Add them, but remove all existing dependencies so far to avoid double entries. This also makes sure that the model - after it has been opened - points + // just to valid dependencies (and to all of them). + this.project.getDependencies().clear(); + this.project.getDependencies().addAll(libs); + } } /** @@ -333,14 +343,16 @@ public final class CurrentWorkSpaceProjectBean { * @return The name of the page of the project overview. */ public String clearProject() { - this.project = null; - this.projectName = null; - this.classLoader = null; - this.selectedPlugin = null; - this.timeStamp = 0; - this.pluginMap.clear(); - this.filter2filterConnections.clear(); - this.filter2repositoryConnections.clear(); + synchronized (this) { + this.project = null; + this.projectName = null; + this.classLoader = null; + this.selectedPlugin = null; + this.timeStamp = 0; + this.pluginMap.clear(); + this.filter2filterConnections.clear(); + this.filter2repositoryConnections.clear(); + } return CurrentWorkSpaceProjectBean.PAGE_PROJECT_OVERVIEW; } @@ -463,41 +475,43 @@ public final class CurrentWorkSpaceProjectBean { * The plugin to be filled. */ private void fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin plugin) { - try { - // Try to instantiate the given class, using the special constructor of Kieker. - final AbstractPlugin pluginInstance = clazz.getConstructor(Configuration.class).newInstance(new Configuration()); - - // Get the port and use them to initialize the model plugin. - final String[] inputPortNames = pluginInstance.getAllInputPortNames(); - final String[] outputPortNames = pluginInstance.getAllOutputPortNames(); - final String[] repositoryPortNames = pluginInstance.getAllRepositoryPortNames(); + synchronized (this) { + try { + // Try to instantiate the given class, using the special constructor of Kieker. + final AbstractPlugin pluginInstance = clazz.getConstructor(Configuration.class).newInstance(new Configuration()); + + // Get the port and use them to initialize the model plugin. + final String[] inputPortNames = pluginInstance.getAllInputPortNames(); + final String[] outputPortNames = pluginInstance.getAllOutputPortNames(); + final String[] repositoryPortNames = pluginInstance.getAllRepositoryPortNames(); + + // Add input ports + if (plugin instanceof MIFilter) { + for (final String inputPortName : inputPortNames) { + final MIInputPort mInputPort = this.factory.createInputPort(); + mInputPort.setName(inputPortName); + mInputPort.setParent((MIFilter) plugin); + } + } - // Add input ports - if (plugin instanceof MIFilter) { - for (final String inputPortName : inputPortNames) { - final MIInputPort mInputPort = this.factory.createInputPort(); - mInputPort.setName(inputPortName); - mInputPort.setParent((MIFilter) plugin); + // Add output ports. + for (final String outputPortName : outputPortNames) { + final MIOutputPort mOutputPort = this.factory.createOutputPort(); + mOutputPort.setName(outputPortName); + mOutputPort.setParent(plugin); } - } - // Add output ports. - for (final String outputPortName : outputPortNames) { - final MIOutputPort mOutputPort = this.factory.createOutputPort(); - mOutputPort.setName(outputPortName); - mOutputPort.setParent(plugin); - } + // Add repository ports. + for (final String repositoryPortName : repositoryPortNames) { + final MIRepositoryConnector mConnector = this.factory.createRepositoryConnector(); + mConnector.setName(repositoryPortName); + plugin.getRepositories().add(mConnector); + } - // Add repository ports. - for (final String repositoryPortName : repositoryPortNames) { - final MIRepositoryConnector mConnector = this.factory.createRepositoryConnector(); - mConnector.setName(repositoryPortName); - plugin.getRepositories().add(mConnector); + } catch (final Exception ex) { + // Inform the user about the fail! + CurrentWorkSpaceProjectBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the ports of the plugin."); } - - } catch (final Exception ex) { - // Inform the user about the fail! - CurrentWorkSpaceProjectBean.showMessage(FacesMessage.SEVERITY_ERROR, "An errcor occured while loading the ports of the plugin."); } } @@ -586,8 +600,12 @@ public final class CurrentWorkSpaceProjectBean { repository.setName(clazz.getSimpleName()); this.fillProperties(clazz, repository); - // Add it to the project - this.project.getRepositories().add(repository); + + synchronized (this) { + // Add it to the project + this.project.getRepositories().add(repository); + this.repositoryMap.put(repository.toString(), repository); + } } /** @@ -609,9 +627,44 @@ public final class CurrentWorkSpaceProjectBean { this.fillProperties(clazz, plugin); this.fillPorts(clazz, plugin); - // Add it to the project - this.project.getPlugins().add(plugin); - this.pluginMap.put(plugin.toString(), plugin); + + 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); + for (final MIPort port : plugin.getOutputPorts()) { + this.portMap.put(port.toString(), port); + } + if (plugin instanceof MIFilter) { + for (final MIPort port : ((MIFilter) plugin).getInputPorts()) { + this.portMap.put(port.toString(), port); + } + } + + // Make sure the user can edit the repository connections. + final EList<MIRepositoryConnector> mConnectors = plugin.getRepositories(); + for (final MIRepositoryConnector mConnector : mConnectors) { + this.filter2repositoryConnections.add(new ConnectionFilterToRepository(plugin, mConnector.getRepository(), mConnector)); + } + } + } + + /** + * This method removes the given repository from the project. If it is also the currently selected repository, it will be deselected. + * + * @param repository + * The repository to be removed from the project. + */ + public void removeRepository(final MIRepository repository) { + synchronized (this) { + this.project.getRepositories().remove(repository); + // Remove the repository from the map + this.repositoryMap.remove(repository.toString()); + + if (this.selectedRepository == repository) { + this.selectedRepository = null; + } + } } /** @@ -621,10 +674,22 @@ public final class CurrentWorkSpaceProjectBean { * The plugin to be removed from the project. */ public void removePlugin(final MIPlugin plugin) { - this.project.getPlugins().remove(plugin); - this.pluginMap.remove(plugin.toString()); - if (this.selectedPlugin == plugin) { - this.selectedPlugin = null; + 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); + } + if (plugin instanceof MIFilter) { + for (final MIPort port : ((MIFilter) plugin).getInputPorts()) { + this.portMap.remove(port.toString(), port); + } + } + + if (this.selectedPlugin == plugin) { + this.selectedPlugin = null; + } } } @@ -634,10 +699,12 @@ public final class CurrentWorkSpaceProjectBean { * @return The currently selected plugin or repository. */ public EObject getSelectedPlugin() { - if (this.selectedPlugin != null) { - return this.selectedPlugin; - } else { - return this.selectedRepository; + synchronized (this) { + if (this.selectedPlugin != null) { + return this.selectedPlugin; + } else { + return this.selectedRepository; + } } } @@ -648,8 +715,11 @@ public final class CurrentWorkSpaceProjectBean { * The new selection. */ public void setSelectedPlugin(final MIPlugin selectedPlugin) { - this.selectedPlugin = selectedPlugin; - this.selectedRepository = null; + synchronized (this) { + this.selectedPlugin = selectedPlugin; + this.selectedRepository = null; + System.out.println(this); + } } /** @@ -659,8 +729,10 @@ public final class CurrentWorkSpaceProjectBean { * The new selection. */ public void setSelectedRepository(final MIRepository selectedRepository) { - this.selectedRepository = selectedRepository; - this.selectedPlugin = null; + synchronized (this) { + this.selectedRepository = selectedRepository; + this.selectedPlugin = null; + } } /** @@ -706,24 +778,26 @@ public final class CurrentWorkSpaceProjectBean { * This method extracts the connections between the filters from the current main project. */ private void getConnectionsFromProject() { - this.filter2filterConnections.clear(); - this.filter2repositoryConnections.clear(); - - if (this.project != null) { - final EList<MIPlugin> mPlugins = this.project.getPlugins(); - - for (final MIPlugin mPlugin : mPlugins) { - final EList<MIOutputPort> mOutputPorts = mPlugin.getOutputPorts(); - for (final MIOutputPort mOutputPort : mOutputPorts) { - final EList<MIInputPort> mInputPorts = mOutputPort.getSubscribers(); - for (final MIInputPort mInputPort : mInputPorts) { - this.filter2filterConnections.add(new ConnectionFilterToFilter(mPlugin, mInputPort.getParent(), mInputPort, mOutputPort)); + synchronized (this) { + this.filter2filterConnections.clear(); + this.filter2repositoryConnections.clear(); + + if (this.project != null) { + final EList<MIPlugin> mPlugins = this.project.getPlugins(); + + for (final MIPlugin mPlugin : mPlugins) { + final EList<MIOutputPort> mOutputPorts = mPlugin.getOutputPorts(); + for (final MIOutputPort mOutputPort : mOutputPorts) { + final EList<MIInputPort> mInputPorts = mOutputPort.getSubscribers(); + for (final MIInputPort mInputPort : mInputPorts) { + this.filter2filterConnections.add(new ConnectionFilterToFilter(mPlugin, mInputPort.getParent(), mInputPort, mOutputPort)); + } } - } - final EList<MIRepositoryConnector> mConnectors = mPlugin.getRepositories(); - for (final MIRepositoryConnector mConnector : mConnectors) { - this.filter2repositoryConnections.add(new ConnectionFilterToRepository(mPlugin, mConnector.getRepository(), mConnector)); + final EList<MIRepositoryConnector> mConnectors = mPlugin.getRepositories(); + for (final MIRepositoryConnector mConnector : mConnectors) { + this.filter2repositoryConnections.add(new ConnectionFilterToRepository(mPlugin, mConnector.getRepository(), mConnector)); + } } } } @@ -762,16 +836,18 @@ public final class CurrentWorkSpaceProjectBean { * @return A list containing all available and valid connections. */ public List<ConnectionFilterToFilter> getValidConnections() { - final List<ConnectionFilterToFilter> validConnections = new ArrayList<ConnectionFilterToFilter>(); - final List<ConnectionFilterToFilter> availableConnections = this.getFilterConnections(); + synchronized (this) { + final List<ConnectionFilterToFilter> validConnections = new ArrayList<ConnectionFilterToFilter>(); + final List<ConnectionFilterToFilter> availableConnections = this.getFilterConnections(); - for (final ConnectionFilterToFilter connection : availableConnections) { - if (connection.isValid()) { - validConnections.add(connection); + for (final ConnectionFilterToFilter connection : availableConnections) { + if (connection.isValid()) { + validConnections.add(connection); + } } - } - return validConnections; + return validConnections; + } } /** @@ -785,15 +861,17 @@ public final class CurrentWorkSpaceProjectBean { * This method "submits" the current connections to the main project (In other words: The connections will be stored within the main project). */ public void submitConnections() { - for (final ConnectionFilterToFilter connection : this.filter2filterConnections) { - if (connection.isValid()) { - connection.getOutputPort().getSubscribers().add(connection.getInputPort()); + synchronized (this) { + for (final ConnectionFilterToFilter connection : this.filter2filterConnections) { + if (connection.isValid()) { + connection.getOutputPort().getSubscribers().add(connection.getInputPort()); + } } - } - for (final ConnectionFilterToRepository connection : this.filter2repositoryConnections) { - if (connection.isValid()) { - connection.getOutputPort().setRepository(connection.getDestination()); + for (final ConnectionFilterToRepository connection : this.filter2repositoryConnections) { + if (connection.isValid()) { + connection.getOutputPort().setRepository(connection.getDestination()); + } } } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java index 1052932a..7305b217 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java @@ -21,10 +21,13 @@ package kieker.webgui.common; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import kieker.analysis.AnalysisController; import kieker.analysis.AnalysisController.STATE; +import kieker.analysis.display.AbstractDisplay; import kieker.analysis.exception.AnalysisConfigurationException; import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.webgui.common.exception.AnalysisNotInstantiatedException; @@ -225,4 +228,56 @@ public final class ACManager { return controllerState; } + + /** + * This method delivers the current displays of the given project. They can be used to show the stored information but should <b>not</b> be modified. + * + * @param projectName + * The name of the project whose displays should be delivered. + * @return A list of pairs containing the displays and the name of them. + */ + public List<Pair<String, AbstractDisplay>> getCurrentDisplays(final String projectName) { + final List<Pair<String, AbstractDisplay>> result = new ArrayList<Pair<String, AbstractDisplay>>(); + + return result; + } + + /** + * This helper thread is used to update the available displays of the ACManager at regular intervals. <b>Important:</b> If the interrupt-method of the thread is + * being called, it will be terminated. + * + * @author Nils Christian Ehmke + * @version 1.0 + */ + @SuppressWarnings("unused") + private class DisplayUpdateThread extends Thread { + + /** + * This is the time the thread waits between the updates. + */ + private static final long SLEEP_TIME_MS = 2 * 1000; + + /** + * Default constructor. + */ + public DisplayUpdateThread() { + // No code necessary + } + + @Override + public void run() { + // Run until we have been interrupted + while (!Thread.interrupted()) { + // TODO Implement + + // Wait a little bit. + try { + Thread.sleep(DisplayUpdateThread.SLEEP_TIME_MS); + } catch (final InterruptedException ex) { + // We have been interrupted. Exit the thread + return; + } + } + } + } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java index 8855545f..541671ae 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FSManager.java @@ -299,7 +299,7 @@ public final class FSManager { * @param projectName * The name of the project to be removed. */ - private void deleteProject(final String projectName) { + public void deleteProject(final String projectName) { // TODO Delete } @@ -315,7 +315,7 @@ public final class FSManager { * @throws IOException * If something goes wrong during the copy procedure. */ - private void copyProject(final String projectName, final String newName) throws ProjectAlreadyExistingException, IOException { + public void copyProject(final String projectName, final String newName) throws ProjectAlreadyExistingException, IOException { if (projectName.equals(newName)) { throw new ProjectAlreadyExistingException("A project with the name '" + newName + "' exists already."); } 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 95e6e74b..3db7b35a 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPluginStringConverter.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPluginStringConverter.java @@ -60,6 +60,10 @@ public class MIPluginStringConverter implements Converter { @Override public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) { - return o.toString(); + if (o == null) { + return ""; + } else { + return o.toString(); + } } } 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 cc8e2c89..e39c7253 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPortStringConverter.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIPortStringConverter.java @@ -60,6 +60,10 @@ public class MIPortStringConverter implements Converter { @Override public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) { - return o.toString(); + if (o == null) { + return ""; + } else { + return o.toString(); + } } } 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 36c71f5a..da1a567a 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIRepositoryStringConverter.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIRepositoryStringConverter.java @@ -60,6 +60,10 @@ public class MIRepositoryStringConverter implements Converter { @Override public String getAsString(final FacesContext fc, final UIComponent uic, final Object o) { - return o.toString(); + if (o == null) { + return ""; + } else { + return o.toString(); + } } } diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisCockpit.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisCockpit.xhtml index ab394769..b3e7fabd 100644 --- a/Kieker.WebGUI/src/main/webapp/AnalysisCockpit.xhtml +++ b/Kieker.WebGUI/src/main/webapp/AnalysisCockpit.xhtml @@ -24,13 +24,13 @@ <p:submenu label="File"> <p:menuitem value="Close Cockpit" action="#{currentAnalysisCockpitProjectBean.clearProject()}" ajax="false"/> <p:separator/> - <p:menuitem value="Settings" onclick="settingsDialog.show()" ajax="true"/> + <p:menuitem value="Settings" onclick="settingsDlg.show()" ajax="true"/> </p:submenu> <p:submenu label="Help"> <p:menuitem value="User Guide" ajax="true"/> <p:separator/> - <p:menuitem value="About..." onclick="aboutDialog.show()" ajax="true"/> + <p:menuitem value="About..." onclick="aboutDlg.show()" ajax="true"/> </p:submenu> <p:menuitem styleClass="logOutButton" disabled="true" value="#{userBean.userName} [Log Out]" ajax="true"/> diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml index 834ae220..3442563a 100644 --- a/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml +++ b/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml @@ -24,13 +24,13 @@ <p:submenu label="File"> <p:menuitem value="Close Controller" action="#{currentAnalysisControllerProjectBean.clearProject()}" ajax="false"/> <p:separator/> - <p:menuitem value="Settings" onclick="settingsDialog.show()" ajax="true"/> + <p:menuitem value="Settings" onclick="settingsDlg.show()" ajax="true"/> </p:submenu> <p:submenu label="Help"> <p:menuitem value="User Guide" ajax="true"/> <p:separator/> - <p:menuitem value="About..." onclick="aboutDialog.show()" ajax="true"/> + <p:menuitem value="About..." onclick="aboutDlg.show()" ajax="true"/> </p:submenu> <p:menuitem styleClass="logOutButton" disabled="true" value="#{userBean.userName} [Log Out]" ajax="true"/> diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisViewWorkSpace.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisViewWorkSpace.xhtml index 771cadac..1e06f51c 100644 --- a/Kieker.WebGUI/src/main/webapp/AnalysisViewWorkSpace.xhtml +++ b/Kieker.WebGUI/src/main/webapp/AnalysisViewWorkSpace.xhtml @@ -9,10 +9,90 @@ <h:head> <title>Kieker.WebGUI</title> + <link rel="stylesheet" type="text/css" href="../css/Common.css" /> <link rel="stylesheet" type="text/css" href="../css/AnalysisViewWorkSpace.css" /> </h:head> <h:body> + <p:layout id="layout" fullPage="true"> + <p:layoutUnit position="north" collapsible="false" header="Kieker.WebGUI"> + <h:form> + <p:menubar> + <p:submenu label="File"> + <p:menuitem value="Save Project" update=":messages" ajax="true" action="#{currentWorkSpaceProjectBean.saveProject(false)}" disabled="#{empty currentWorkSpaceProjectBean.project}"/> + <p:menuitem value="Save Project As" update=":messages" ajax="true" disabled="#{empty currentWorkSpaceProjectBean.project}"/> + <p:menuitem styleClass="Force-Save-Project-Button" value="Force Save Project" update=":messages" ajax="true" action="#{currentWorkSpaceProjectBean.saveProject(true)}" disabled="#{empty currentWorkSpaceProjectBean.project}"/> + <p:separator/> + <p:menuitem value="Reset Project" ajax="true" disabled="#{empty currentWorkSpaceProjectBean.project}"/> + <p:separator/> + <p:menuitem value="New View" ajax="true"/> + <p:separator/> + <p:menuitem value="Close Project" action="#{currentWorkSpaceProjectBean.clearProject()}" ajax="false"/> + <p:separator/> + <p:menuitem value="Settings" onclick="settingsDlg.show()" ajax="true"/> + </p:submenu> + + <p:submenu label="Help"> + <p:menuitem value="User Guide" ajax="true"/> + <p:separator/> + <p:menuitem value="About..." onclick="aboutDlg.show()" ajax="true"/> + </p:submenu> + + <p:menuitem styleClass="logOutButton" disabled="true" value="#{userBean.userName} [Log Out]" ajax="true"/> + </p:menubar> + + </h:form> + </p:layoutUnit> + + <p:layoutUnit position="west"> + + <p:accordionPanel> + <p:tab title="Plugin 001"> + <p:panel id="display001" header="Display 001"> + + </p:panel> + <p:draggable helper="clone" revert="true" for="display001"/> + <br/> + <p:panel header="Display 002"> + + </p:panel> + </p:tab> + + <p:tab title="Plugin 002"> + <p:panel header="Display 001"> + + </p:panel> + <br/> + <p:panel header="Display 002"> + + </p:panel> + </p:tab> + </p:accordionPanel> + + </p:layoutUnit> + + <p:layoutUnit position="center"> + <p:accordionPanel> + <p:tab title="View 1"> + <p:dashboard> + + </p:dashboard> + </p:tab> + + <p:tab title="View 2"> + <p:dashboard> + + </p:dashboard> + </p:tab> + </p:accordionPanel> + </p:layoutUnit> + </p:layout> + + <!-- Include the dialog for the configuration. --> + <ui:include src="dialogs/settingsDialog.xhtml" /> + + <!-- Include the about-dialog. --> + <ui:include src="dialogs/aboutDialog.xhtml" /> </h:body> </html> \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/webapp/ProjectOverview.xhtml b/Kieker.WebGUI/src/main/webapp/ProjectOverview.xhtml index 81dd147e..418b2f23 100644 --- a/Kieker.WebGUI/src/main/webapp/ProjectOverview.xhtml +++ b/Kieker.WebGUI/src/main/webapp/ProjectOverview.xhtml @@ -14,7 +14,6 @@ </h:head> <h:body> - <p:layout fullPage="true"> <p:layoutUnit position="north" header="Kieker.WebGUI"> <h:form id="menubarForm"> @@ -25,13 +24,13 @@ <p:separator/> <p:menuitem value="Refresh Projects List" update=":projectsListForm" ajax="true"/> <p:separator/> - <p:menuitem value="Settings" onclick="settingsDialog.show()" ajax="true"/> + <p:menuitem value="Settings" onclick="settingsDlg.show()" ajax="true"/> </p:submenu> <p:submenu label="Help"> <p:menuitem value="User Guide" ajax="true"/> <p:separator/> - <p:menuitem value="About..." onclick="aboutDialog.show()" ajax="true"/> + <p:menuitem value="About..." onclick="aboutDlg.show()" ajax="true"/> </p:submenu> <p:menuitem styleClass="logOutButton" disabled="true" value="#{userBean.userName} [Log Out]" ajax="true"/> @@ -53,19 +52,19 @@ <p:column headerText="Last Modification" sortBy="#{projectsBean.getCurrTimeStamp(project)}" style="text-align: center"> <h:outputText value="#{projectsBean.getCurrTimeStamp(project)}" /> </p:column> - + <p:column headerText="Analysis" style="text-align: center" sortBy="#{projectsBean.getAnalysisControllerState(project)}"> <h:outputText value="#{projectsBean.getAnalysisControllerState(project)}"/> </p:column> - <p:column headerText="Options" style="text-align: center; width: 280px"> + <p:column headerText="Options" style="text-align: center; width: 310px"> <p:commandButton id="openButton" ajax="false" action="#{currentWorkSpaceProjectBean.setProject(projectsBean.openProject(project), project)}" icon="ui-icon-folder-open"/> <p:commandButton id="copyButton" icon="ui-icon-copy" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="copyProjectDialog.show()"/> <p:commandButton id="renameButton" icon="ui-icon-pencil" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="renameProjectDialog.show()"/> <p:commandButton id="deleteButton" icon="ui-icon-trash" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="deleteProjectDialog.show()"/> <p:spacer height="0" width="10"/> <p:commandButton id="controlAnalysis" ajax="false" action="#{currentAnalysisControllerProjectBean.setProject(project)}" icon="ui-icon-wrench"/> - <p:commandButton id="editAnalysisViews" icon="ui-icon-pencil"/> + <p:commandButton id="editAnalysisViews" ajax="false" action="#{currentAnalysisViewWorkSpaceProjectBean.setProject(project)}" icon="ui-icon-pencil" /> <p:commandButton id="showAnalysis" ajax="false" action="#{currentAnalysisCockpitProjectBean.setProject(project)}" icon="ui-icon-search"/> <p:tooltip for="deleteButton" value="Delete Project"/> @@ -84,13 +83,12 @@ <p:growl id="messages" life="1500" showDetail="true" autoUpdate="false" sticky="false"/> - <!-- Include the dialogs for the project managment. --> + <!-- Include the about-dialog. --> + <ui:include src="dialogs/aboutDialog.xhtml" /> + <!-- Include the dialogs for the project managment. --> <ui:include src="dialogs/projectDialogs.xhtml" /> - <!-- Include the dialog for the configuration. --> <ui:include src="dialogs/settingsDialog.xhtml" /> - - <!-- Include the about-dialog. --> - <ui:include src="dialogs/aboutDialog.xhtml" /> + </h:body> </html> \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/webapp/ProjectWorkSpace.xhtml b/Kieker.WebGUI/src/main/webapp/ProjectWorkSpace.xhtml index 1bf0f20b..e50096cd 100644 --- a/Kieker.WebGUI/src/main/webapp/ProjectWorkSpace.xhtml +++ b/Kieker.WebGUI/src/main/webapp/ProjectWorkSpace.xhtml @@ -41,13 +41,13 @@ <p:separator/> <p:menuitem value="Close Project" action="#{currentWorkSpaceProjectBean.clearProject()}" ajax="false"/> <p:separator/> - <p:menuitem value="Settings" onclick="settingsDialog.show()" ajax="true"/> + <p:menuitem value="Settings" onclick="settingsDlg.show()" ajax="true"/> </p:submenu> <p:submenu label="Help"> <p:menuitem value="User Guide" ajax="true"/> <p:separator/> - <p:menuitem value="About..." onclick="aboutDialog.show()" ajax="true"/> + <p:menuitem value="About..." onclick="aboutDlg.show()" ajax="true"/> </p:submenu> <p:menuitem styleClass="logOutButton" disabled="true" value="#{userBean.userName} [Log Out]" ajax="true"/> @@ -77,8 +77,6 @@ <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="Connections" update=":connectionDialogForm" onclick="connectionDialog.show();"/> - <br/> <p:commandLink ajax="true" value="Remove" action="#{currentWorkSpaceProjectBean.removeRepository(repository)}" update=":propertiesForm :centerForm"/> </div> </ui:repeat> diff --git a/Kieker.WebGUI/src/main/webapp/dialogs/aboutDialog.xhtml b/Kieker.WebGUI/src/main/webapp/dialogs/aboutDialog.xhtml index a79f1545..80c7ca07 100644 --- a/Kieker.WebGUI/src/main/webapp/dialogs/aboutDialog.xhtml +++ b/Kieker.WebGUI/src/main/webapp/dialogs/aboutDialog.xhtml @@ -6,7 +6,7 @@ xmlns:p="http://primefaces.org/ui"> <p:dialog header="About..." resizable="false" modal="true" - widgetVar="aboutDialog" id="aboutDialog"> + widgetVar="aboutDlg" id="aboutDialog"> <h:form> <img src="../img/kieker-logo-transparent.png" style="opacity: 0.25" /> <hr/> @@ -21,7 +21,7 @@ <a href="http://www.kieker-monitoring.net/">http://www.kieker-monitoring.net/</a> <hr/> <div style="text-align: right"> - <p:commandButton value="Ok" onclick="aboutDialog.hide()" /> + <p:commandButton value="Ok" oncomplete="aboutDlg.hide()" /> </div> </h:form> </p:dialog> diff --git a/Kieker.WebGUI/src/main/webapp/dialogs/manageLibrariesDialog.xhtml b/Kieker.WebGUI/src/main/webapp/dialogs/manageLibrariesDialog.xhtml index a0cd9fcc..a8c9102f 100644 --- a/Kieker.WebGUI/src/main/webapp/dialogs/manageLibrariesDialog.xhtml +++ b/Kieker.WebGUI/src/main/webapp/dialogs/manageLibrariesDialog.xhtml @@ -5,7 +5,7 @@ xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> - <p:dialog id="manageLibrariesDialog" header="Libraries" resizable="false" + <p:dialog id="manageLibrariesDlg" header="Libraries" resizable="false" modal="true" widgetVar="manageLibrariesDialog"> <h:form id="dependenciesForm"> diff --git a/Kieker.WebGUI/src/main/webapp/dialogs/projectDialogs.xhtml b/Kieker.WebGUI/src/main/webapp/dialogs/projectDialogs.xhtml index 424d120e..076b390b 100644 --- a/Kieker.WebGUI/src/main/webapp/dialogs/projectDialogs.xhtml +++ b/Kieker.WebGUI/src/main/webapp/dialogs/projectDialogs.xhtml @@ -8,7 +8,7 @@ <!-- ******************************************************************************** --> <!-- This is the dialog to create a new project. --> - <p:dialog id="newProjectDialog" header="New Project" resizable="false" modal="true" widgetVar="newProjectDialog"> + <p:dialog id="newProjectDlg" header="New Project" resizable="false" modal="true" widgetVar="newProjectDialog"> <!-- Make sure that closing of the dialog also clears the input field. --> <p:ajax event="close" update="newProjectDialogForm:newProjectInputText" /> @@ -28,7 +28,7 @@ </p:dialog> <!-- ******************************************************************************** --> - <p:dialog id="renameProjectDialog" header="Rename Project" resizable="false" modal="true" widgetVar="renameProjectDialog"> + <p:dialog id="renameProjectDlg" header="Rename Project" resizable="false" modal="true" widgetVar="renameProjectDialog"> <!-- Make sure that closing of the dialog also clears the input field. --> <p:ajax event="close" update="renameProjectDialogForm:renameProjectInputText" /> @@ -47,7 +47,7 @@ </h:form> </p:dialog> - <p:dialog id="deleteProjectDialog" header="Delete Project" resizable="false" modal="true" widgetVar="deleteProjectDialog"> + <p:dialog id="deleteProjectDlg" header="Delete Project" resizable="false" modal="true" widgetVar="deleteProjectDialog"> <h:form id="deleteProjectDialogForm"> <div style="text-align: center"> @@ -63,7 +63,7 @@ </h:form> </p:dialog> - <p:dialog id="copyProjectDialog" header="Copy Project" resizable="false" modal="true" widgetVar="copyProjectDialog"> + <p:dialog id="copyProjectDlg" header="Copy Project" resizable="false" modal="true" widgetVar="copyProjectDialog"> <!-- Make sure that closing of the dialog also clears the input field. --> <p:ajax event="close" update="copyProjectDialogForm:copyProjectDialogInputText" /> diff --git a/Kieker.WebGUI/src/main/webapp/dialogs/settingsDialog.xhtml b/Kieker.WebGUI/src/main/webapp/dialogs/settingsDialog.xhtml index a47b05ba..719db0c1 100644 --- a/Kieker.WebGUI/src/main/webapp/dialogs/settingsDialog.xhtml +++ b/Kieker.WebGUI/src/main/webapp/dialogs/settingsDialog.xhtml @@ -6,7 +6,7 @@ xmlns:p="http://primefaces.org/ui"> <p:dialog id="settingsDialog" header="Settings" resizable="false" - modal="true" widgetVar="settingsDialog"> + modal="true" widgetVar="settingsDlg"> <h:form> <h:panelGrid columns="2" cellpadding="10"> <h:outputText value="Look and Feel:" /> @@ -18,7 +18,7 @@ </h:panelGrid> <hr/> <div style="text-align: right"> - <p:commandButton value="Ok" oncomplete="settingsDialog.hide();" /> + <p:commandButton value="Ok" oncomplete="settingsDlg.hide();" /> </div> </h:form> </p:dialog> -- GitLab