diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableDependenciesBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableDependenciesBean.java index 2158483d2c854f6bcfb461b97c3f86efe157d328..d87bf9dec48e303b8078bbc820d9a08f83914546 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableDependenciesBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableDependenciesBean.java @@ -27,6 +27,7 @@ import javax.faces.bean.ManagedBean; import kieker.analysis.model.analysisMetaModel.MIDependency; import kieker.webgui.common.FileManager; +import kieker.webgui.common.PluginClassLoader; import org.primefaces.model.UploadedFile; @@ -66,19 +67,22 @@ public class AvailableDependenciesBean { * @param file * The file to be uploaded. */ - public synchronized void uploadDependency(final UploadedFile file) { - 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. - */ - for (final MIDependency dep : this.dependencies) { - if (dep.getFilePath().equals(dependency.getFilePath())) { - this.dependencies.remove(dep); - break; + public void uploadDependency(final UploadedFile file) { + 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. + */ + for (final MIDependency dep : this.dependencies) { + if (dep.getFilePath().equals(dependency.getFilePath())) { + this.dependencies.remove(dep); + break; + } } + PluginClassLoader.getInstance().addURL(dependency.getFilePath()); + this.dependencies.add(dependency); } - this.dependencies.add(dependency); } } @@ -88,10 +92,13 @@ public class AvailableDependenciesBean { * @param dependency * The dependency to be removed. */ - public synchronized void deleteDependency(final MIDependency dependency) { - final boolean result = FileManager.getInstance().deleteDependency(dependency); - if (result) { - this.dependencies.remove(dependency); + public void deleteDependency(final MIDependency dependency) { + synchronized (this) { + final boolean result = FileManager.getInstance().deleteDependency(dependency); + if (result) { + PluginClassLoader.getInstance().removeURL(dependency.getFilePath()); + this.dependencies.remove(dependency); + } } } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableProjectsBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableProjectsBean.java index 3173feb2b28dab73690301ac8e10398b0e4ed5bb..8d793dee74d93ccfb8d49a0db3e8f4ad50e44bb2 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableProjectsBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/AvailableProjectsBean.java @@ -68,29 +68,31 @@ public class AvailableProjectsBean { * @param projectName * The name of the new project. */ - public final synchronized void addProject(final String projectName) { - /* - * Create a new project. - */ - final MIProject project = this.factory.createProject(); - project.setName(projectName); - - /* - * Try to save the project. - */ - if (FileManager.getInstance().saveNewProject(project)) { + public final void addProject(final String projectName) { + synchronized (this) { /* - * Set the new project as the main project, if the current - * user doesn't have one. + * Create a new project. */ - final FacesContext context = FacesContext.getCurrentInstance(); - final SelectedProjectBean bean = context.getApplication().evaluateExpressionGet(context, "#{selectedProjectBean}", - SelectedProjectBean.class); - if (bean != null && bean.getMainProject() == null) { - bean.setMainProject(project); - } + final MIProject project = this.factory.createProject(); + project.setName(projectName); - this.projects.add(project); + /* + * Try to save the project. + */ + if (FileManager.getInstance().saveNewProject(project)) { + /* + * Set the new project as the main project, if the current + * user doesn't have one. + */ + final FacesContext context = FacesContext.getCurrentInstance(); + final SelectedProjectBean bean = context.getApplication().evaluateExpressionGet(context, "#{selectedProjectBean}", + SelectedProjectBean.class); + if (bean != null && bean.getMainProject() == null) { + bean.setMainProject(project); + } + + this.projects.add(project); + } } } @@ -99,19 +101,21 @@ public class AvailableProjectsBean { * * @return The root of the currently available projects. */ - public final synchronized TreeNode getProjectsRoot() { - final TreeNode root = new DefaultTreeNode("Root", null); - - for (final MIProject project : this.projects) { - final TreeNode projectNode = new DefaultTreeNode("project", project, root); - final TreeNode dependenciesNode = new DefaultTreeNode("dependencies", "Dependencies", projectNode); - final TreeNode usedPluginsNode = new DefaultTreeNode("usedPlugins", "Used Plugins", projectNode); - for (final MIPlugin plugin : project.getPlugins()) { - final TreeNode usedPluginNode = new DefaultTreeNode("usedPlugin", plugin.getClassname(), usedPluginsNode); + public final TreeNode getProjectsRoot() { + synchronized (this) { + final TreeNode root = new DefaultTreeNode("Root", null); + + for (final MIProject project : this.projects) { + final TreeNode projectNode = new DefaultTreeNode("project", project, root); + new DefaultTreeNode("dependencies", "Dependencies", projectNode); + final TreeNode usedPluginsNode = new DefaultTreeNode("usedPlugins", "Used Plugins", projectNode); + for (final MIPlugin plugin : project.getPlugins()) { + new DefaultTreeNode("usedPlugin", plugin.getClassname(), usedPluginsNode); + } } - } - return root; + return root; + } } /** @@ -121,8 +125,10 @@ public class AvailableProjectsBean { * @param project * The project to be saved. */ - public synchronized void saveProject(final MIProject project) { - FileManager.getInstance().saveProject(project); + public void saveProject(final MIProject project) { + synchronized (this) { + FileManager.getInstance().saveProject(project); + } } /** @@ -131,10 +137,12 @@ public class AvailableProjectsBean { * @param project * The project to be removed. */ - public synchronized void deleteProject(final MIProject project) { - final boolean result = FileManager.getInstance().deleteProject(project); - if (result) { - this.projects.remove(project); + public void deleteProject(final MIProject project) { + synchronized (this) { + final boolean result = FileManager.getInstance().deleteProject(project); + if (result) { + this.projects.remove(project); + } } } @@ -145,7 +153,13 @@ public class AvailableProjectsBean { * @param project * The project to be reloaded. */ - public synchronized void resetProject(final MIProject project) { - // TODO Fill method + public void resetProject(final MIProject project) { + synchronized (this) { + final MIProject result = FileManager.getInstance().reloadProject(project); + if (result != null) { + this.projects.remove(project); + this.projects.add(result); + } + } } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/SelectedDependenciesBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/SelectedDependenciesBean.java index e11bee3c35289ae436d195abb6a76def3c0497ee..12a453996bf168b37273c0ab13975f9f2a0b3375 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/SelectedDependenciesBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/SelectedDependenciesBean.java @@ -52,10 +52,6 @@ public class SelectedDependenciesBean { * The currently selected project. */ private final MIProject project; - /** - * The faces context of this bean. - */ - private final FacesContext context; /** * Creates a new instance of this class. @@ -66,9 +62,9 @@ public class SelectedDependenciesBean { this.dependencies = new DualListModel<MIDependency>(source, target); - this.context = FacesContext.getCurrentInstance(); + final FacesContext context = FacesContext.getCurrentInstance(); - final SelectedProjectBean selProjBean = this.context.getApplication().evaluateExpressionGet(this.context, "#{selectedProjectBean}", + final SelectedProjectBean selProjBean = context.getApplication().evaluateExpressionGet(context, "#{selectedProjectBean}", SelectedProjectBean.class); if (selProjBean != null) { this.project = selProjBean.getSelectedProject(); @@ -78,7 +74,7 @@ public class SelectedDependenciesBean { /* Get all available libs. */ - final AvailableDependenciesBean availDepBean = this.context.getApplication().evaluateExpressionGet(this.context, "#{availableDependenciesBean}", + final AvailableDependenciesBean availDepBean = context.getApplication().evaluateExpressionGet(context, "#{availableDependenciesBean}", AvailableDependenciesBean.class); this.dependencies.getSource().clear(); if (availDepBean != null) { @@ -112,7 +108,6 @@ public class SelectedDependenciesBean { * The new dependencies dual model. */ public final void setDependencies(final DualListModel<MIDependency> dependencies) { - System.out.println(dependencies); this.dependencies = dependencies; /* Remember the selected libs. */ 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 4ed3136e53a74d229b53344a629ef366d885474f..59e649e1a7e45ce28e5b4f1d980842c9ef1f2ef3 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 @@ -159,8 +159,8 @@ public class SelectedProjectBean { public final TreeNode getAvailablePluginsRoot() { final TreeNode root = new DefaultTreeNode("Root", null); - final TreeNode readerNode = new DefaultTreeNode("default", "Reader", root); - final TreeNode analysisPluginsNode = new DefaultTreeNode("default", "AnalysisPlugins", root); + new DefaultTreeNode("default", "Reader", root); + new DefaultTreeNode("default", "AnalysisPlugins", root); return root; } 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 a49fe2c9a43f632dd9177b1f9eed44375aa93955..04618341a994baac2c3deb9ce87b0dc7052fbe29 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/FileManager.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/FileManager.java @@ -350,4 +350,26 @@ public final class FileManager { } return false; } + + /** + * This method reloads the given project from the file system. + * + * @param project + * The project to be reloaded. + * @return The reloaded project. + */ + public MIProject reloadProject(final MIProject project) { + final String projectName = project.getName(); + + final File projectFile = new File(FileManager.PROJECT_DIR + File.separator + projectName + File.separator + projectName + EXTENSION); + if (projectFile.isFile()) { + try { + return AnalysisController.loadFromFile(projectFile); + } catch (Exception ex) { + FileManager.LOG.warn("Error reloaded project '" + projectName + "'"); + } + } + return null; + + } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..5e1f9034fc088b018359ac377bd8baa8322a75b3 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginClassLoader.java @@ -0,0 +1,88 @@ +/*************************************************************************** + * 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.common; + +import java.net.URL; + +/** + * This singleton class is responsible for the dynamic loading of classes. + * Unlike a normal <code>URLClassLoader</code> it is possible to dynamically add + * and remove urls from the class loader. This instance should always be used if + * plugin objects have to be created. + * + * @author Nils Christian Ehmke + */ +public final class PluginClassLoader { + + /** + * The singleton instance of this class. + */ + private static final PluginClassLoader INSTANCE = new PluginClassLoader(); + + /** + * The default constructor of this class. + */ + private PluginClassLoader() { + // Nothing to do + } + + /** + * This method can be used to add an url to the class loader. + * + * @param fileName + * The file name of the dependency to be added. + */ + public void addURL(final String fileName) { + // TODO Implement + } + + /** + * This method can be used to remove an url from the class loader. + * + * @param fileName + * The file name of the dependency to be removed. + */ + public void removeURL(final String fileName) { + // TODO Implement + } + + /** + * Delivers the only instance of this class. + * + * @return The singleton instance of this class. + */ + public static final synchronized PluginClassLoader getInstance() { + return PluginClassLoader.INSTANCE; + } + + /** + * This method tries to load the class with the given name using the + * currently loaded dependencies. + * + * @param name + * The name of the class to be loaded. + * @return The class. + */ + public Class<?> loadClass(final String name) { + // TODO Implement + return null; + } +} 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 5e1057064c5d9432206ebc0e5a958b4c4e8ea01b..31ddcd9c50dc2a21b0f1540b027f54b1dad5c129 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/PluginFinder.java @@ -19,7 +19,6 @@ ***************************************************************************/ package kieker.webgui.common; -import edu.umd.cs.findbugs.ba.AnalysisContext; import java.io.File; import java.io.IOException; import java.net.URL; @@ -32,8 +31,6 @@ import java.util.jar.JarFile; import kieker.analysis.AnalysisController; import kieker.analysis.plugin.port.Plugin; -import kieker.common.logging.Log; -import kieker.common.logging.LogFactory; /** * @author Nils Christian Ehmke @@ -41,11 +38,6 @@ import kieker.common.logging.LogFactory; */ public final class PluginFinder { - /** - * The logger of this class. - */ - private static final Log LOG = LogFactory.getLog(PluginFinder.class); - /** * Creates a new instance of this class. */ @@ -61,12 +53,13 @@ public final class PluginFinder { * exception occured. */ public static List<Class<?>> getAllPluginsWithinJar(final URL url) { + URLClassLoader classLoader = null; try { /* * Get a classloader and make sure that it has the system class * loader as parent and that it knows the url. */ - final ClassLoader classLoader = new URLClassLoader(new URL[] { url }, AnalysisController.class.getClassLoader()); + classLoader = new URLClassLoader(new URL[] { url }, AnalysisController.class.getClassLoader()); /* * Open the jar file and run through all entries within this file. */ @@ -98,7 +91,15 @@ public final class PluginFinder { return result; } catch (final IOException ex) { ex.printStackTrace(); - return null; + } finally { + try { + if (classLoader != null) { + classLoader.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } } + return null; } } 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 929d2a673ee208d7f39979b32d275de12bf5632e..07ecd110331980b0e10925b98f59ff35e8cb3ee7 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToCountPluginsConverter.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/converter/MIDependencyToCountPluginsConverter.java @@ -21,7 +21,6 @@ package kieker.webgui.converter; import java.io.File; import java.net.MalformedURLException; -import java.text.DecimalFormat; import java.util.HashMap; import java.util.Map;