Skip to content
Snippets Groups Projects
Commit e6258e8b authored by Nils Christian Ehmke's avatar Nils Christian Ehmke
Browse files

Continued with the usage of the correct project-classloaders.

parent fba16aa1
No related branches found
No related tags found
No related merge requests found
Showing
with 870 additions and 391 deletions
...@@ -39,4 +39,9 @@ ...@@ -39,4 +39,9 @@
</plugins> </plugins>
<dependencies filePath="BookstoreApplication.jar"/> <dependencies filePath="BookstoreApplication.jar"/>
<dependencies filePath="commons-cli-1.2.jar"/> <dependencies filePath="commons-cli-1.2.jar"/>
<views name="My View" description="Some amazing view.">
<displayConnectors name="Valid Counter Display" display="//@plugins.5/@displays.0"/>
<displayConnectors name="Global Counter Display" display="//@plugins.4/@displays.0"/>
<displayConnectors name="Invalid Counter Display" display="//@plugins.3/@displays.0"/>
</views>
</Project> </Project>
...@@ -20,20 +20,23 @@ ...@@ -20,20 +20,23 @@
package kieker.webgui.beans.view; package kieker.webgui.beans.view;
import java.lang.reflect.InvocationTargetException;
import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty; import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped; import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import kieker.analysis.display.AbstractDisplay;
import kieker.analysis.display.HtmlText; import kieker.analysis.display.HtmlText;
import kieker.analysis.display.Image; import kieker.analysis.display.Image;
import kieker.analysis.display.PlainText;
import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.analysis.model.analysisMetaModel.MIProject;
import kieker.analysis.model.analysisMetaModel.MIView; import kieker.analysis.model.analysisMetaModel.MIView;
import kieker.webgui.beans.application.ProjectsBean; import kieker.webgui.beans.application.ProjectsBean;
import kieker.webgui.common.ACManager; import kieker.webgui.common.ACManager;
import kieker.webgui.common.ClassAndMethodContainer;
import kieker.webgui.common.FSManager;
import kieker.webgui.common.Global; import kieker.webgui.common.Global;
import kieker.webgui.common.exception.ProjectLoadException;
/** /**
* The {@link CurrentCockpitBean} contains the necessary data behind an instance of the cockpit. It provides methods to read the state of the currently * The {@link CurrentCockpitBean} contains the necessary data behind an instance of the cockpit. It provides methods to read the state of the currently
...@@ -64,6 +67,8 @@ public class CurrentCockpitBean { ...@@ -64,6 +67,8 @@ public class CurrentCockpitBean {
@ManagedProperty(value = "#{projectsBean}") @ManagedProperty(value = "#{projectsBean}")
private ProjectsBean projectsBean; private ProjectsBean projectsBean;
private ClassAndMethodContainer classAndMethodContainer;
/** /**
* Creates a new instance of this class. * Creates a new instance of this class.
*/ */
...@@ -121,13 +126,19 @@ public class CurrentCockpitBean { ...@@ -121,13 +126,19 @@ public class CurrentCockpitBean {
/** /**
* This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by
* JSF.</b> * JSF.</b>
*
* @throws ProjectLoadException
*/ */
public void initalize() { public void initalize() throws ProjectLoadException {
synchronized (this) { synchronized (this) {
// Make sure that the initialization will only be done for the init request. // Make sure that the initialization will only be done for the init request.
if (!FacesContext.getCurrentInstance().isPostback() && (this.projectsBean != null)) { if (!FacesContext.getCurrentInstance().isPostback() && (this.projectsBean != null)) {
// Remember the given parameters // Remember the given parameters
this.project = this.projectsBean.openProject(this.projectName); this.project = this.projectsBean.openProject(this.projectName);
if (this.project != null) {
this.classAndMethodContainer = new ClassAndMethodContainer(FSManager.getInstance().getClassLoader(this.projectName));
}
} }
} }
} }
...@@ -152,18 +163,26 @@ public class CurrentCockpitBean { ...@@ -152,18 +163,26 @@ public class CurrentCockpitBean {
* does exist, but the return content is not plain text, null will be returned. * does exist, but the return content is not plain text, null will be returned.
*/ */
public String updatePlainTextDisplay(final String displayName) { public String updatePlainTextDisplay(final String displayName) {
final String result; String result;
synchronized (this) { synchronized (this) {
if ((this.activeView != null) && (this.projectName != null)) { if ((this.activeView != null) && (this.projectName != null)) {
final AbstractDisplay displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName); final Object displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
if (displayObj == null) { if (displayObj == null) {
// The display does not exist // The display does not exist
result = "N/A"; result = "N/A";
} else { } else {
if (displayObj instanceof PlainText) { if (this.classAndMethodContainer.getPlainTextClass().isAssignableFrom(displayObj.getClass())) {
// The display exists and is valid // The display exists and is valid
result = ((PlainText) displayObj).getText(); try {
result = (String) (this.classAndMethodContainer.getPlainTextgetTextMethod().invoke(displayObj, new Object[0]));
} catch (final IllegalAccessException e) {
result = "Error";
} catch (final IllegalArgumentException e) {
result = "Error";
} catch (final InvocationTargetException e) {
result = "Error";
}
} else { } else {
// The display exists, but is not valid // The display exists, but is not valid
result = null; result = null;
...@@ -191,7 +210,7 @@ public class CurrentCockpitBean { ...@@ -191,7 +210,7 @@ public class CurrentCockpitBean {
synchronized (this) { synchronized (this) {
if ((this.activeView != null) && (this.projectName != null)) { if ((this.activeView != null) && (this.projectName != null)) {
final AbstractDisplay displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName); final Object displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
if (displayObj == null) { if (displayObj == null) {
// The display does not exist // The display does not exist
result = "N/A"; result = "N/A";
...@@ -226,7 +245,7 @@ public class CurrentCockpitBean { ...@@ -226,7 +245,7 @@ public class CurrentCockpitBean {
synchronized (this) { synchronized (this) {
if ((this.activeView != null) && (this.projectName != null)) { if ((this.activeView != null) && (this.projectName != null)) {
final AbstractDisplay displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName); final Object displayObj = ACManager.getInstance().getDisplay(this.projectName, this.activeView.getName(), displayName);
if (displayObj == null) { if (displayObj == null) {
// The display does not exist // The display does not exist
result = "N/A"; result = "N/A";
......
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
package kieker.webgui.beans.view; package kieker.webgui.beans.view;
import java.io.IOException;
import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity; import javax.faces.application.FacesMessage.Severity;
import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedBean;
...@@ -30,17 +28,17 @@ import javax.faces.bean.ViewScoped; ...@@ -30,17 +28,17 @@ import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import kieker.analysis.AnalysisController; import kieker.analysis.AnalysisController;
import kieker.analysis.exception.AnalysisConfigurationException;
import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.analysis.model.analysisMetaModel.MIProject;
import kieker.common.logging.Log; import kieker.common.logging.Log;
import kieker.common.logging.LogFactory; import kieker.common.logging.LogFactory;
import kieker.webgui.beans.application.ProjectsBean; import kieker.webgui.beans.application.ProjectsBean;
import kieker.webgui.common.ACManager; import kieker.webgui.common.ACManager;
import kieker.webgui.common.Global; import kieker.webgui.common.Global;
import kieker.webgui.common.exception.AnalysisAlreadyInstantiatedException;
import kieker.webgui.common.exception.AnalysisAlreadyStartedException;
import kieker.webgui.common.exception.AnalysisInstantiationException;
import kieker.webgui.common.exception.AnalysisNotInstantiatedException; import kieker.webgui.common.exception.AnalysisNotInstantiatedException;
import kieker.webgui.common.exception.AnalysisNotRunningException; import kieker.webgui.common.exception.AnalysisNotStartedException;
import kieker.webgui.common.exception.ProjectAlreadyStartedException;
import kieker.webgui.common.exception.ProjectStillRunningException;
/** /**
* /** * /**
...@@ -166,9 +164,9 @@ public class CurrentControllerBean { ...@@ -166,9 +164,9 @@ public class CurrentControllerBean {
synchronized (this) { synchronized (this) {
ACManager.getInstance().startAnalysisController(this.projectName); ACManager.getInstance().startAnalysisController(this.projectName);
} }
} catch (final ProjectAlreadyStartedException ex) { } catch (final AnalysisAlreadyStartedException ex) {
CurrentControllerBean.LOG.info("The analysis is already running.", ex); CurrentControllerBean.LOG.info("The analysis has already been started.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis is already running."); CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has already been started.");
} catch (final AnalysisNotInstantiatedException ex) { } catch (final AnalysisNotInstantiatedException ex) {
CurrentControllerBean.LOG.info("The analysis has not been instantiated yet.", ex); CurrentControllerBean.LOG.info("The analysis has not been instantiated yet.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been instantiated yet."); CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been instantiated yet.");
...@@ -183,11 +181,9 @@ public class CurrentControllerBean { ...@@ -183,11 +181,9 @@ public class CurrentControllerBean {
synchronized (this) { synchronized (this) {
ACManager.getInstance().stopAnalysisController(this.projectName); ACManager.getInstance().stopAnalysisController(this.projectName);
} }
} catch (final AnalysisNotRunningException ex) { } catch (final AnalysisNotStartedException ex) {
CurrentControllerBean.LOG.info("The analysis has not been started yet.", ex); CurrentControllerBean.LOG.info("The analysis has not been started yet.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been started yet."); CurrentControllerBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been started yet.");
} catch (final InterruptedException ex) {
CurrentControllerBean.LOG.error("Unknown interrupted exception.", ex);
} }
} }
...@@ -199,18 +195,12 @@ public class CurrentControllerBean { ...@@ -199,18 +195,12 @@ public class CurrentControllerBean {
synchronized (this) { synchronized (this) {
ACManager.getInstance().instantiateAnalysisController(this.projectName); ACManager.getInstance().instantiateAnalysisController(this.projectName);
} }
} catch (final NullPointerException ex) { // NOPMD (Exception is explicitly thrown) } catch (final AnalysisAlreadyInstantiatedException ex) {
CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex); CurrentControllerBean.LOG.error("The analysis has already been instantiated.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis."); CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "The analysis has already been instantiated.");
} catch (final AnalysisConfigurationException ex) { } catch (final AnalysisInstantiationException ex) {
CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis.");
} catch (final IOException ex) {
CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex); CurrentControllerBean.LOG.error("An error occurred while instantiating the analysis.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis."); CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis.");
} catch (final ProjectStillRunningException ex) {
CurrentControllerBean.LOG.info("The analysis is still running.", ex);
CurrentControllerBean.showMessage(FacesMessage.SEVERITY_ERROR, "The analysis is still running.");
} }
} }
......
package kieker.webgui.common;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import kieker.analysis.model.analysisMetaModel.MIDisplayConnector;
import kieker.analysis.model.analysisMetaModel.MIProject;
import kieker.analysis.model.analysisMetaModel.MIView;
import kieker.analysis.plugin.AbstractPlugin;
import kieker.common.logging.Log;
import kieker.common.logging.LogFactory;
import kieker.webgui.common.exception.AnalysisAlreadyStartedException;
import kieker.webgui.common.exception.AnalysisInstantiationException;
import kieker.webgui.common.exception.ProjectLoadException;
// TODO AnalysisController, Thread etc. have to be initialized via the class loader as well
public class Analysis {
/**
* This is the log for errors, exceptions etc.
*/
private static final Log LOG = LogFactory.getLog(Analysis.class);
private static final long MAX_THREAD_WAIT_TIME_MS = 1000;
private final ClassAndMethodContainer classAndMethodContainer;
private final MIProject modelProject;
private final Object analysisController;
private final Object analysisControllerThread;
private final UpdateDisplaysThread updateDisplaysThread;
public Analysis(final ClassLoader classLoader, final MIProject modelProject) throws AnalysisInstantiationException {
try {
this.modelProject = modelProject;
this.classAndMethodContainer = new ClassAndMethodContainer(classLoader);
final Method createMethod = this.classAndMethodContainer.getAnalysisControllerCreateAnalysisController();
final Object controllerAndMapping = ClassAndMethodContainer.invokeClassMethod(createMethod, null, this.modelProject, classLoader);
this.analysisController = ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getAnalysisControllerWithMappingGetController(),
controllerAndMapping, null);
this.analysisControllerThread = ClassAndMethodContainer.invokeConstructor(this.classAndMethodContainer.getAnalysisControllerThreadConstructor(),
this.analysisController);
this.updateDisplaysThread = new UpdateDisplaysThread(ClassAndMethodContainer.invokeMethod(
this.classAndMethodContainer.getAnalysisControllerWithMappingGetMapping(), controllerAndMapping, null));
if ((this.analysisController == null) || (this.analysisControllerThread == null)) {
throw new AnalysisInstantiationException("An error occured while instantiating the analysis.");
}
} catch (final ProjectLoadException ex) {
throw new AnalysisInstantiationException("An error occured while instantiating the analysis.", ex);
} catch (final NullPointerException ex) {
throw new AnalysisInstantiationException("An error occured while instantiating the analysis.", ex);
}
}
public void start() throws AnalysisAlreadyStartedException {
synchronized (this) {
try {
this.classAndMethodContainer.getAnalysisControllerThreadStart().invoke(this.analysisControllerThread, new Object[0]);
this.updateDisplaysThread.start();
} catch (final IllegalThreadStateException ex) {
throw new AnalysisAlreadyStartedException("The analysis has already been started once. It has to be reinitialized to be runnable again.", ex);
} catch (final IllegalAccessException ex) {
Analysis.LOG.error("An error occured during a reflection method call.", ex);
} catch (final IllegalArgumentException ex) {
Analysis.LOG.error("An error occured during a reflection method call.", ex);
} catch (final InvocationTargetException ex) {
throw new AnalysisAlreadyStartedException("The analysis has already been started once. It has to be reinitialized to be runnable again.", ex);
}
}
}
public void stop() {
synchronized (this) {
try {
this.classAndMethodContainer.getAnalysisControllerThreadTerminate().invoke(this.analysisControllerThread, new Object[0]);
this.updateDisplaysThread.terminate();
this.classAndMethodContainer.getAnalysisControllerThreadJoin().invoke(this.analysisControllerThread, Analysis.MAX_THREAD_WAIT_TIME_MS);
this.updateDisplaysThread.join(Analysis.MAX_THREAD_WAIT_TIME_MS);
} catch (final InterruptedException ex) {
// Log the exception, but don't handle it further
Analysis.LOG.info("An interrupted exception occured.", ex);
} catch (final IllegalAccessException ex) {
Analysis.LOG.error("An error occured during a reflection method call.", ex);
} catch (final IllegalArgumentException ex) {
Analysis.LOG.error("An error occured during a reflection method call.", ex);
} catch (final InvocationTargetException ex) {
Analysis.LOG.error("An error occured during a reflection method call.", ex);
}
}
}
public Enum<?> getCurrentState() {
synchronized (this) {
return (Enum<?>) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getAnalysisControllerGetState(), this.analysisController, null);
}
}
public Object getDisplay(final String viewName, final String displayName) {
return this.updateDisplaysThread.getDisplay(viewName, displayName);
}
/**
* This manager is responsible for the currently used and running instances of {@code AnalysisController}. It supplies methods to check the states of analysis,
* instantiate, start and to stop them.
*
* @author Nils Christian Ehmke
* @version 1.0
*/
private class UpdateDisplaysThread extends Thread {
/**
* This is the time the thread waits between the updates.
*/
private static final long SLEEP_TIME_MS = 2 * 1000;
private final Object pluginMap;
/**
* The map containing all available display objects.
*/
private final Map<String, Map<String, Object>> displayObjects = new ConcurrentHashMap<String, Map<String, Object>>(); // NOPMD
/**
* This map contains the mapping to get the methods to be called.
*/
private final Map<Object, Method> methodMap = new ConcurrentHashMap<Object, Method>(); // NOPMD (Use of concurrent hash map)
/**
* The field determining whether the thread has been terminated or not. // (USeConcurrentHashMap)
*/
private volatile boolean terminated = false;
public UpdateDisplaysThread(final Object object) {
this.pluginMap = object;
}
@PostConstruct
private void initialize() {
// Initialize the hashmaps and the necessary objects
for (final MIView view : Analysis.this.modelProject.getViews()) {
final Map<String, Object> viewMap = new ConcurrentHashMap<String, Object>(); // NOPMD (Use of concurrent hash map)
this.displayObjects.put(view.getName(), viewMap);
for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
// final Method displayMethod = this.getDisplayMethod(this.pluginMap.get(displayConnector.getDisplay().getParent()).getClass(),
// displayConnector.getDisplay().getName());
// Make sure that the method really exists and that is has the correct parameters
/*
* if ((displayMethod != null) && (displayMethod.getParameterTypes().length == 1)) {
* final Class<?> parameterType = displayMethod.getParameterTypes()[0];
* final Object displayObject;
* // Get the correct type
* if (Analysis.this.classAndMethodContainer.getImageClass().isAssignableFrom(parameterType)) {
* displayObject = new Image();
* } else {
* if (Analysis.this.classAndMethodContainer.getPlainTextClass().isAssignableFrom(parameterType)) {
* displayObject = new PlainText();
* } else {
* if (Analysis.this.classAndMethodContainer.getHtmlTextClass().isAssignableFrom(parameterType)) {
* displayObject = new HtmlText();
* } else {
* displayObject = null;
* }
* }
* }
* if (displayObject != null) {
* viewMap.put(displayConnector.getName(), displayObject);
* this.methodMap.put(displayObject, displayMethod);
* }
* }
*/
}
}
}
/**
* Delivers the correct method to be invoked for an update of the display.
*
* @param clazz
* The class of the plugin.
* @param displayName
* The name within the display-annotation.
* @return The method instance.
*/
private Method getDisplayMethod(final Class<? extends AbstractPlugin> clazz, final String displayName) {
final Method[] methods = clazz.getMethods();
for (final Method method : methods) {
try {
final Annotation displayAnnot = method.getAnnotation(Analysis.this.classAndMethodContainer.getDisplayAnnotationClass());
if ((displayAnnot != null)
&& (Analysis.this.classAndMethodContainer.getDisplayNameMethod().invoke(displayAnnot, new Object[0]).equals(displayName))) {
// We found the correct method
return method;
}
} catch (final IllegalAccessException ex) {
// Log this exception, but ignore it
Analysis.LOG.info("An error occured while calling a method.", ex);
} catch (final IllegalArgumentException ex) {
// Log this exception, but ignore it
Analysis.LOG.info("An error occured while calling a method.", ex);
} catch (final InvocationTargetException ex) {
// Log this exception, but ignore it
Analysis.LOG.info("An error occured while calling a method.", ex);
}
}
return null;
}
/**
* Delivers the display object for the given view and the given display.
*
* @param viewName
* The name of the view.
* @param displayName
* The name of the display in the view.
* @return The object for the given display if it exists, null otherwise.
*/
public Object getDisplay(final String viewName, final String displayName) {
return this.displayObjects.get(viewName).get(displayName);
}
@Override
public void run() {
// Run until we have been interrupted
while (!this.terminated) {
for (final MIView view : Analysis.this.modelProject.getViews()) {
this.displayObjects.get(view.getName());
for (final MIDisplayConnector displayConnector : view.getDisplayConnectors()) {
// final Object displayObject = viewMap.get(displayConnector.getName());
// final Object pluginObject = this.pluginMap.get(displayConnector.getDisplay().getParent());
// Update the display object
// try {
// this.methodMap.get(displayObject).invoke(pluginObject, displayObject);
// } catch (final IllegalAccessException ex) {
// Analysis.LOG.error("An error occured while updating the display.", ex);
// } catch (final IllegalArgumentException ex) {
// Analysis.LOG.error("An error occured while updating the display.", ex);
// } catch (final InvocationTargetException ex) {
// Analysis.LOG.error("An error occured while updating the display.", ex);
// } catch (final NullPointerException ex) { // NOPMD
// Analysis.LOG.error("An error occured while updating the display.", ex);
// }
}
}
// Wait a little bit.
try {
Thread.sleep(UpdateDisplaysThread.SLEEP_TIME_MS);
} catch (final InterruptedException ex) {
// We have been interrupted. Exit the thread
return;
}
}
}
public void terminate() {
this.terminated = true;
}
}
}
...@@ -20,9 +20,18 @@ ...@@ -20,9 +20,18 @@
package kieker.webgui.common; package kieker.webgui.common;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import kieker.analysis.AnalysisController;
import kieker.analysis.AnalysisController.AnalysisControllerWithMapping;
import kieker.analysis.AnalysisControllerThread;
import kieker.analysis.display.HtmlText;
import kieker.analysis.display.Image;
import kieker.analysis.display.PlainText;
import kieker.analysis.display.annotation.Display; import kieker.analysis.display.annotation.Display;
import kieker.analysis.model.analysisMetaModel.MIProject;
import kieker.analysis.plugin.AbstractPlugin; import kieker.analysis.plugin.AbstractPlugin;
import kieker.analysis.plugin.annotation.InputPort; import kieker.analysis.plugin.annotation.InputPort;
import kieker.analysis.plugin.annotation.OutputPort; import kieker.analysis.plugin.annotation.OutputPort;
...@@ -57,6 +66,18 @@ public final class ClassAndMethodContainer { ...@@ -57,6 +66,18 @@ public final class ClassAndMethodContainer {
*/ */
private static final String MSG_LOAD_EXCEPTION = "An error occured while loading the classes and methods."; private static final String MSG_LOAD_EXCEPTION = "An error occured while loading the classes and methods.";
/**
* This is the class equivalence of {@link AnalysisControllerWithMapping}.
*/
private Class<?> analysisControllerWithMappingClass;
/**
* This is the class equivalence of {@link AnalysisController}.
*/
private final Class<?> analysisControllerClass;
/**
* This is the class equivalence of {@link AnalysisControllerThread}.
*/
private final Class<?> analysisControllerThreadClass;
/** /**
* This is the class equivalence of {@link AbstractRepository}. * This is the class equivalence of {@link AbstractRepository}.
*/ */
...@@ -101,6 +122,18 @@ public final class ClassAndMethodContainer { ...@@ -101,6 +122,18 @@ public final class ClassAndMethodContainer {
* This is the class equivalence of {@link Display}. * This is the class equivalence of {@link Display}.
*/ */
private final Class<? extends Annotation> displayAnnotationClass; private final Class<? extends Annotation> displayAnnotationClass;
/**
* This is the class equivalence of {@link Image}.
*/
private final Class<?> imageClass;
/**
* This is the class equivalence of {@link PlainText}.
*/
private final Class<?> plainTextClass;
/**
* This is the class equivalence of {@link HtmlText}.
*/
private final Class<?> htmlTextClass;
/** /**
* This is the description()-method of the class equivalence of {@link Plugin}. * This is the description()-method of the class equivalence of {@link Plugin}.
*/ */
...@@ -149,6 +182,42 @@ public final class ClassAndMethodContainer { ...@@ -149,6 +182,42 @@ public final class ClassAndMethodContainer {
* This is the defaultValue()-method of the class equivalence of {@link Property}. * This is the defaultValue()-method of the class equivalence of {@link Property}.
*/ */
private final Method propertyDefaultValueMethod; private final Method propertyDefaultValueMethod;
/**
* This is the getText()-method of the class equivalence of {@link PlainText}.
*/
private final Method plainTextgetTextMethod;
/**
* This is the getController()-method of the class equivalence of {@link AnalysisControllerWithMapping}.
*/
private final Method analysisControllerWithMappingGetController;
/**
* This is the getPluginMap()-method of the class equivalence of {@link AnalysisControllerWithMapping}.
*/
private final Method analysisControllerWithMappingGetMapping;
/**
* This is the createAnalysisController(MIProject, ClassLoader)-method of the class equivalence of {@link AnalysisControllerWithMapping}.
*/
private final Method analysisControllerCreateAnalysisController;
/**
* This is the start()-method of the class equivalence of {@link AnalysisController}.
*/
private final Method analysisControllerThreadStart;
/**
* This is the terminate()-method of the class equivalence of {@link AnalysisController}.
*/
private final Method analysisControllerThreadTerminate;
/**
* This is the join(long)-method of the class equivalence of {@link AnalysisController}.
*/
private final Method analysisControllerThreadJoin;
/**
* This is the getState()-method of the class equivalence of {@link AnalysisController}.
*/
private Method analysisControllerGetState;
/**
* This is the constructor for {@link AnalysisControllerThread}, which gets an instance of {@link AnalysisController}.
*/
private final Constructor<?> analysisControllerThreadConstructor;
/** /**
* Creates a new instance of this class, using the given class loader. * Creates a new instance of this class, using the given class loader.
...@@ -161,18 +230,25 @@ public final class ClassAndMethodContainer { ...@@ -161,18 +230,25 @@ public final class ClassAndMethodContainer {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public ClassAndMethodContainer(final ClassLoader classLoader) throws ProjectLoadException { public ClassAndMethodContainer(final ClassLoader classLoader) throws ProjectLoadException {
try { try {
this.abstractFilterPluginClass = classLoader.loadClass(AbstractFilterPlugin.class.getCanonicalName()); this.analysisControllerWithMappingClass = classLoader.loadClass(AnalysisControllerWithMapping.class.getName());
this.abstractReaderPluginClass = classLoader.loadClass(AbstractReaderPlugin.class.getCanonicalName());
this.abstractRepositoryClass = classLoader.loadClass(AbstractRepository.class.getCanonicalName()); this.analysisControllerClass = classLoader.loadClass(AnalysisController.class.getName());
this.abstractPluginClass = classLoader.loadClass(AbstractPlugin.class.getCanonicalName()); this.analysisControllerThreadClass = classLoader.loadClass(AnalysisControllerThread.class.getName());
this.abstractFilterPluginClass = classLoader.loadClass(AbstractFilterPlugin.class.getName());
this.pluginAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Plugin.class.getCanonicalName()); this.abstractReaderPluginClass = classLoader.loadClass(AbstractReaderPlugin.class.getName());
this.repositoryAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Repository.class.getCanonicalName()); this.abstractRepositoryClass = classLoader.loadClass(AbstractRepository.class.getName());
this.propertyAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Property.class.getCanonicalName()); this.abstractPluginClass = classLoader.loadClass(AbstractPlugin.class.getName());
this.outputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(OutputPort.class.getCanonicalName()); this.htmlTextClass = classLoader.loadClass(HtmlText.class.getName());
this.inputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(InputPort.class.getCanonicalName()); this.plainTextClass = classLoader.loadClass(PlainText.class.getName());
this.repositoryPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(RepositoryPort.class.getCanonicalName()); this.imageClass = classLoader.loadClass(Image.class.getName());
this.displayAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Display.class.getCanonicalName());
this.pluginAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Plugin.class.getName());
this.repositoryAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Repository.class.getName());
this.propertyAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Property.class.getName());
this.outputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(OutputPort.class.getName());
this.inputPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(InputPort.class.getName());
this.repositoryPortAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(RepositoryPort.class.getName());
this.displayAnnotationClass = (Class<? extends Annotation>) classLoader.loadClass(Display.class.getName());
this.pluginDescriptionMethod = this.pluginAnnotationClass.getMethod("description", new Class<?>[0]); this.pluginDescriptionMethod = this.pluginAnnotationClass.getMethod("description", new Class<?>[0]);
this.repositoryDescriptionMethod = this.repositoryAnnotationClass.getMethod("description", new Class<?>[0]); this.repositoryDescriptionMethod = this.repositoryAnnotationClass.getMethod("description", new Class<?>[0]);
...@@ -186,6 +262,29 @@ public final class ClassAndMethodContainer { ...@@ -186,6 +262,29 @@ public final class ClassAndMethodContainer {
this.repositoryPortNameMethod = this.repositoryPortAnnotationClass.getMethod("name", new Class<?>[0]); this.repositoryPortNameMethod = this.repositoryPortAnnotationClass.getMethod("name", new Class<?>[0]);
this.propertyNameMethod = this.propertyAnnotationClass.getMethod("name", new Class<?>[0]); this.propertyNameMethod = this.propertyAnnotationClass.getMethod("name", new Class<?>[0]);
this.propertyDefaultValueMethod = this.propertyAnnotationClass.getMethod("defaultValue", new Class<?>[0]); this.propertyDefaultValueMethod = this.propertyAnnotationClass.getMethod("defaultValue", new Class<?>[0]);
this.plainTextgetTextMethod = this.plainTextClass.getMethod("getText", new Class<?>[0]);
this.analysisControllerWithMappingGetController = this.analysisControllerWithMappingClass.getMethod("getController", new Class<?>[0]);
this.analysisControllerWithMappingGetMapping = this.analysisControllerWithMappingClass.getMethod("getPluginMap", new Class<?>[0]);
this.analysisControllerThreadStart = this.analysisControllerThreadClass.getMethod("start", new Class<?>[0]);
this.analysisControllerThreadTerminate = this.analysisControllerThreadClass.getMethod("terminate", new Class<?>[0]);
this.analysisControllerGetState = this.analysisControllerClass.getMethod("getState", new Class<?>[0]);
// This is a special case as we need to load some additional classes to search for the correct method
final Class<?> miProjectClass = classLoader.loadClass(MIProject.class.getName());
final Class<?> classLoaderClass = classLoader.loadClass(ClassLoader.class.getName());
this.analysisControllerCreateAnalysisController = this.analysisControllerClass.getMethod("createAnalysisController", miProjectClass, classLoaderClass);
// Another special case as the parameter is a long
final Method[] methods = this.analysisControllerThreadClass.getMethods();
Method joinMethod = null;
for (final Method method : methods) {
if ("join".equals(method.getName())) {
joinMethod = method;
}
}
this.analysisControllerThreadJoin = joinMethod;
this.analysisControllerThreadConstructor = this.analysisControllerThreadClass.getConstructor(this.analysisControllerClass);
} catch (final ClassNotFoundException ex) { } catch (final ClassNotFoundException ex) {
ClassAndMethodContainer.LOG.error(ClassAndMethodContainer.MSG_LOAD_EXCEPTION, ex); ClassAndMethodContainer.LOG.error(ClassAndMethodContainer.MSG_LOAD_EXCEPTION, ex);
throw new ProjectLoadException(ClassAndMethodContainer.MSG_LOAD_EXCEPTION, ex); throw new ProjectLoadException(ClassAndMethodContainer.MSG_LOAD_EXCEPTION, ex);
...@@ -408,4 +507,232 @@ public final class ClassAndMethodContainer { ...@@ -408,4 +507,232 @@ public final class ClassAndMethodContainer {
return this.propertyDefaultValueMethod; return this.propertyDefaultValueMethod;
} }
/**
* The getter-method for the field {@link ClassAndMethodContainer#imageClass}.
*
* @return The current value for the field.
*/
public Class<?> getImageClass() {
return this.imageClass;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#plainTextClass}.
*
* @return The current value for the field.
*/
public Class<?> getPlainTextClass() {
return this.plainTextClass;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#htmlTextClass}.
*
* @return The current value for the field.
*/
public Class<?> getHtmlTextClass() {
return this.htmlTextClass;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#plainTextgetTextMethod}.
*
* @return The current value for the field.
*/
public Method getPlainTextgetTextMethod() {
return this.plainTextgetTextMethod;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerWithMappingGetMapping}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerWithMappingGetMapping() {
return this.analysisControllerWithMappingGetMapping;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerClass}.
*
* @return The current value for the field.
*/
public Class<?> getAnalysisControllerClass() {
return this.analysisControllerClass;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerWithMappingClass}.
*
* @return The current value for the field.
*/
public Class<?> getAnalysisControllerWithMappingClass() {
return this.analysisControllerWithMappingClass;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadClass}.
*
* @return The current value for the field.
*/
public Class<?> getAnalysisControllerThreadClass() {
return this.analysisControllerThreadClass;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerCreateAnalysisController}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerCreateAnalysisController() {
return this.analysisControllerCreateAnalysisController;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerWithMappingGetController}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerWithMappingGetController() {
return this.analysisControllerWithMappingGetController;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadStart}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerThreadStart() {
return this.analysisControllerThreadStart;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadTerminate}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerThreadTerminate() {
return this.analysisControllerThreadTerminate;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadJoin}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerThreadJoin() {
return this.analysisControllerThreadJoin;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadJoin}.
*
* @return The current value for the field.
*/
public Method getAnalysisControllerGetState() {
return this.analysisControllerGetState;
}
/**
* The getter-method for the field {@link ClassAndMethodContainer#analysisControllerThreadConstructor}.
*
* @return The current value for the field.
*/
public Constructor<?> getAnalysisControllerThreadConstructor() {
return this.analysisControllerThreadConstructor;
}
/**
* This method can be used to invoke a given method with given parameters, without having to mind about the exceptions. If an exception occurs, the given default
* value will be returned.
*
* @param method
* The method to be invoked.
* @param obj
* The object on which the method will be invoked.
* @param defaultReturn
* The default return value in case of an exception.
* @param values
* The parameters for the method.
* @return The result of the invoked method if everything went well, the default value otherwise.
*/
public static Object invokeMethod(final Method method, final Object obj, final Object defaultReturn, final Object... values) {
try {
return method.invoke(obj, values);
} catch (final IllegalAccessException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection method call.", ex);
return defaultReturn;
} catch (final IllegalArgumentException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection method call.", ex);
return defaultReturn;
} catch (final InvocationTargetException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection method call.", ex);
return defaultReturn;
}
}
/**
* This method can be used to invoke a given constructor with given parameters, without having to mind about the exceptions. If an exception occurs, null will be
* returned.
*
* @param constructor
* The constructor to be invoked.
* @param values
* The parameters for the method.
* @return The result of the invoked method if everything went well, null otherwise.
*/
public static Object invokeConstructor(final Constructor<?> constructor, final Object... values) {
try {
return constructor.newInstance(values);
} catch (final InstantiationException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
return null;
} catch (final IllegalAccessException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
return null;
} catch (final IllegalArgumentException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
return null;
} catch (final InvocationTargetException ex) {
ClassAndMethodContainer.LOG.error("An error occured during a reflection constructor call.", ex);
return null;
}
}
/**
* This method can be used to invoke a given method with no parameters, without having to mind about the exceptions. If an exception occurs, the given default
* value will be returned. A call to this method is the same as {@link ClassAndMethodContainer#invokeMethod(Method, Object, Object, Object...)} with
* {@code new Object[0]} as parameters.
*
* @param method
* The method to be invoked.
* @param obj
* The object on which the method will be invoked.
* @param defaultReturn
* The default return value in case of an exception.
* @return The result of the invoked method if everything went well, the default value otherwise.
*/
public static Object invokeMethod(final Method method, final Object obj, final Object defaultReturn) {
return ClassAndMethodContainer.invokeMethod(method, obj, defaultReturn, new Object[0]);
}
/**
* This method can be used to invoke a given <b>class</b>-method with no parameters, without having to mind about the exceptions. If an exception occurs, the
* given default value will be returned. A call to this method is the same as {@link ClassAndMethodContainer#invokeMethod(Method, Object, Object, Object...)}
* with null as object.
*
* @param method
* The method to be invoked.
* @param defaultReturn
* The default return value in case of an exception.
* @param values
* The parameters for the method.
* @return The result of the invoked method if everything went well, the default value otherwise.
*/
public static Object invokeClassMethod(final Method method, final Object defaultReturn, final Object... values) {
return ClassAndMethodContainer.invokeMethod(method, null, defaultReturn, values);
}
} }
/***************************************************************************
* 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.exception;
/**
* This exception shows that the analysis has not yet been instantiated.
*
* @author Nils Christian Ehmke
* @version 1.0
*/
public class AnalysisAlreadyInstantiatedException extends Exception {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of this class.
*/
public AnalysisAlreadyInstantiatedException() {
// No code necessary
}
/**
* Creates a new instance of this class using the given parameters.
*
* @param msg
* The message used for the exception.
*/
public AnalysisAlreadyInstantiatedException(final String msg) {
super(msg);
}
}
...@@ -18,113 +18,38 @@ ...@@ -18,113 +18,38 @@
* limitations under the License. * limitations under the License.
***************************************************************************/ ***************************************************************************/
package kieker.webgui.common; package kieker.webgui.common.exception;
/** /**
* This is a simple helper class which can store three values. * This exception shows that the given project has already been started.
* *
* @author Nils Christian Ehmke * @author Nils Christian Ehmke
* @version 1.0 * @version 1.0
*
* @param <F>
* The type of the first element.
* @param <S>
* The type of the second element.
* @param <T>
* The type of the third element.
*/ */
public class Triple<F, S, T> { public class AnalysisAlreadyStartedException extends Exception {
/**
* This is the first element.
*/
private F fst;
/**
* This is the second element.
*/
private S snd;
/** /**
* This is the third element. * The serial version UID.
*/ */
private T thd; private static final long serialVersionUID = 1L;
/** /**
* Creates a new instance of this class with null values stored for the elements. * Creates a new instance of this class.
*/ */
public Triple() { public AnalysisAlreadyStartedException() {
// No code necessary // No code necessary
} }
/** /**
* Creates a new instance of this class using the given values. * Creates a new instance of this class using the given parameters.
*
* @param fst
* The first element to be stored in this object.
* @param snd
* The second element to be stored in this object.
* @param thd
* The third element to be stored in this object.
*/
public Triple(final F fst, final S snd, final T thd) {
this.fst = fst;
this.snd = snd;
this.thd = thd;
}
/**
* Delivers the first element.
*
* @return The first element.
*/
public F getFst() {
return this.fst;
}
/**
* Sets the first element to a new value.
*
* @param fst
* The new first element.
*/
public void setFst(final F fst) {
this.fst = fst;
}
/**
* Delivers the second element.
* *
* @return The second element. * @param msg
* The message used for the exception.
*/ */
public S getSnd() { public AnalysisAlreadyStartedException(final String msg) {
return this.snd; super(msg);
} }
/** public AnalysisAlreadyStartedException(final String msg, final Throwable ex) {
* Sets the second element to a new value. super(msg, ex);
*
* @param snd
* The new second element.
*/
public void setSnd(final S snd) {
this.snd = snd;
} }
/**
* Delivers the third element.
*
* @return The third element.
*/
public T getThd() {
return this.thd;
}
/**
* Sets the third element to a new value.
*
* @param thd
* The new third element.
*/
public void setThd(final T thd) {
this.thd = thd;
}
} }
/***************************************************************************
* 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.exception;
public class AnalysisInstantiationException extends Exception {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of this class.
*/
public AnalysisInstantiationException() {
// No code necessary
}
/**
* Creates a new instance of this class using the given parameters.
*
* @param msg
* The message used for the exception.
*/
public AnalysisInstantiationException(final String msg) {
super(msg);
}
/**
* Creates a new instance of this class using the given parameters.
*
* @param msg
* The message used for the exception.
* @param The
* cause for the method.
*/
public AnalysisInstantiationException(final String msg, final Throwable cause) {
super(msg, cause);
}
}
...@@ -26,7 +26,7 @@ package kieker.webgui.common.exception; ...@@ -26,7 +26,7 @@ package kieker.webgui.common.exception;
* @author Nils Christian Ehmke * @author Nils Christian Ehmke
* @version 1.0 * @version 1.0
*/ */
public class AnalysisNotRunningException extends Exception { public class AnalysisNotStartedException extends Exception {
/** /**
* The serial version UID. * The serial version UID.
*/ */
...@@ -35,7 +35,7 @@ public class AnalysisNotRunningException extends Exception { ...@@ -35,7 +35,7 @@ public class AnalysisNotRunningException extends Exception {
/** /**
* Creates a new instance of this class. * Creates a new instance of this class.
*/ */
public AnalysisNotRunningException() { public AnalysisNotStartedException() {
// No code necessary // No code necessary
} }
...@@ -45,7 +45,7 @@ public class AnalysisNotRunningException extends Exception { ...@@ -45,7 +45,7 @@ public class AnalysisNotRunningException extends Exception {
* @param msg * @param msg
* The message used for the exception. * The message used for the exception.
*/ */
public AnalysisNotRunningException(final String msg) { public AnalysisNotStartedException(final String msg) {
super(msg); super(msg);
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment