From 0c9c78a834328ad5402849ea421452a7d9942878 Mon Sep 17 00:00:00 2001 From: Nils Christian Ehmke <nie@informatik.uni-kiel.de> Date: Sun, 20 May 2012 14:28:47 +0200 Subject: [PATCH] Moved some code for the analysis controller into an ACManager; Analysis can now be controlled. --- .gitignore | 3 +- .../beans/application/ProjectsBean.java | 27 +-- .../CurrentAnalysisControllerProjectBean.java | 93 ++++++++ .../java/kieker/webgui/common/ACManager.java | 221 ++++++++++++++++++ .../AnalysisNotInstantiatedException.java | 49 ++++ .../AnalysisNotRunningException.java | 49 ++++ .../ProjectAlreadyStartedException.java | 49 ++++ .../ProjectStillRunningException.java | 49 ++++ .../src/main/webapp/AnalysisController.xhtml | 31 ++- 9 files changed, 535 insertions(+), 36 deletions(-) create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotInstantiatedException.java create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectAlreadyStartedException.java create mode 100644 Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectStillRunningException.java diff --git a/.gitignore b/.gitignore index 6db4bed6..166c8edd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /build/ /dist/ /nbproject/private -/Kieker.WebGUI/target/ \ No newline at end of file +/Kieker.WebGUI/target/ +/Kieker.WebGUI/data \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java index 9c5bb7cf..cd1bc43c 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java @@ -25,7 +25,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; import javax.faces.application.FacesMessage; @@ -36,6 +35,7 @@ import javax.faces.context.FacesContext; import kieker.analysis.AnalysisController; import kieker.analysis.model.analysisMetaModel.MIProject; +import kieker.webgui.common.ACManager; import kieker.webgui.common.FSManager; import kieker.webgui.common.exception.ProjectAlreadyExistingException; @@ -54,10 +54,6 @@ public final class ProjectsBean { * This is the list containing all projects. */ private final List<String> projects = Collections.synchronizedList(new ArrayList<String>()); - /** - * This list contains the current analysis controllers. Not every project does have a controller, but every project can have maximal one. - */ - private final ConcurrentHashMap<String, AnalysisController> analysisController = new ConcurrentHashMap<String, AnalysisController>(); /** * Creates a new instance of this class. @@ -140,17 +136,6 @@ public final class ProjectsBean { return this.projects; } - /** - * This method delivers the corresponding analysis controller of the given project. - * - * @param project - * The project whose analysis controller should be delivered. - * @return The corresponding instance of {@link AnalysisController} if it exists, null otherwise. - */ - public AnalysisController getAnalysisController(final String project) { - return this.analysisController.get(project); - } - /** * This method can be used to deliver the state of the analysis controller of the given project as a human readable string. * @@ -159,15 +144,7 @@ public final class ProjectsBean { * @return The current state of the corresponding {@link AnalysisController} if it exists, 'N/A' otherwise. */ public String getAnalysisControllerState(final String project) { - final AnalysisController controller = this.analysisController.get(project); - - final String controllerState; - if (controller == null) { - controllerState = "N/A"; - } else { - controllerState = controller.getState().toString(); - } - return controllerState; + return ACManager.getInstance().getAnalysisControllerStateString(project); } /** diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentAnalysisControllerProjectBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentAnalysisControllerProjectBean.java index 31e42b77..68983019 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentAnalysisControllerProjectBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/CurrentAnalysisControllerProjectBean.java @@ -20,8 +20,21 @@ package kieker.webgui.beans.session; +import java.io.IOException; + +import javax.faces.application.FacesMessage; +import javax.faces.application.FacesMessage.Severity; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; +import javax.faces.context.FacesContext; + +import kieker.analysis.AnalysisController; +import kieker.analysis.exception.AnalysisConfigurationException; +import kieker.webgui.common.ACManager; +import kieker.webgui.common.exception.AnalysisNotInstantiatedException; +import kieker.webgui.common.exception.AnalysisNotRunningException; +import kieker.webgui.common.exception.ProjectAlreadyStartedException; +import kieker.webgui.common.exception.ProjectStillRunningException; /** * This bean contains the project of the current (session) user for the analysis controller page. @@ -85,4 +98,84 @@ public class CurrentAnalysisControllerProjectBean { return CurrentAnalysisControllerProjectBean.PAGE_PROJECT_OVERVIEW; } + + /** + * This method starts the current analysis and informs the user about a fail. + */ + public void startAnalysis() { + try { + ACManager.getInstance().startAnalysisController(this.projectName); + } catch (final ProjectAlreadyStartedException ex) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis is already running."); + } catch (final AnalysisNotInstantiatedException ex) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been instantiated yet."); + } + } + + /** + * This method stops the current analysis and informs the user about a fail. + */ + public void stopAnalysis() { + try { + ACManager.getInstance().stopAnalysisController(this.projectName); + } catch (final AnalysisNotRunningException e) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_WARN, "The analysis has not been started yet."); + } catch (final InterruptedException ex) { + ex.printStackTrace(); + } + } + + /** + * This method initializes the current analysis and informs the user about a fail. + */ + public void instantiateAnalysis() { + try { + ACManager.getInstance().instantiateAnalysisController(this.projectName); + } catch (final NullPointerException e) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis."); + } catch (final AnalysisConfigurationException e) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis."); + } catch (final IOException e) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occurred while instantiating the analysis."); + } catch (final ProjectStillRunningException e) { + CurrentAnalysisControllerProjectBean.showMessage(FacesMessage.SEVERITY_ERROR, "The analysis is still running."); + } + } + + /** + * Checks whether the analysis is currently running. + * + * @return true if and only if the analysis is running. + */ + public boolean isAnalysisRunning() { + return ACManager.getInstance().getAnalysisControllerState(this.projectName) == AnalysisController.STATE.RUNNING; + } + + public boolean isAnalysisReady() { + return ACManager.getInstance().getAnalysisControllerState(this.projectName) == AnalysisController.STATE.READY; + } + + public boolean isAnalysisNotAvailable() { + return ACManager.getInstance().getAnalysisControllerState(this.projectName) == null; + } + + public boolean isAnalysisTerminated() { + return ACManager.getInstance().getAnalysisControllerState(this.projectName) == AnalysisController.STATE.TERMINATED; + } + + public boolean isAnalysisFailed() { + return ACManager.getInstance().getAnalysisControllerState(this.projectName) == AnalysisController.STATE.FAILED; + } + + /** + * This method shows the current user a message by using the growl-component of PrimeFaces. + * + * @param severity + * The severity of the message. + * @param msg + * The message itself. + */ + private static void showMessage(final Severity severity, final String msg) { + FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(severity, "", msg)); + } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java new file mode 100644 index 00000000..1a2ab36b --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ACManager.java @@ -0,0 +1,221 @@ +/*************************************************************************** + * 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.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +import kieker.analysis.AnalysisController; +import kieker.analysis.AnalysisController.STATE; +import kieker.analysis.exception.AnalysisConfigurationException; +import kieker.analysis.model.analysisMetaModel.MIProject; +import kieker.webgui.common.exception.AnalysisNotInstantiatedException; +import kieker.webgui.common.exception.AnalysisNotRunningException; +import kieker.webgui.common.exception.ProjectAlreadyStartedException; +import kieker.webgui.common.exception.ProjectStillRunningException; + +/** + * 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. This is also a singleton instance. + * + * @author Nils Christian Ehmke + * @version 1.0 + */ +public class ACManager { + /** + * This is the maximal time the application will wait for an analysis thread to be terminated. + */ + private static final long MAX_THREAD_WAIT_TIME_MS = 1000; + /** + * This list contains the current analysis controllers and their corresponding threads. Not every project does have a controller, but every project can have + * maximal one. + */ + private final ConcurrentHashMap<String, Pair<AnalysisController, Thread>> analysisController = new ConcurrentHashMap<String, Pair<AnalysisController, Thread>>(); + /** + * This is the singleton instance of this class. + */ + private static final ACManager INSTANCE = new ACManager(); + + /** + * Creates a new instance of this class. + */ + private ACManager() { + // No code necessary. + } + + /** + * Delivers the singleton instance of this class. + * + * @return The only instance of {@link FSManager}. + */ + public static ACManager getInstance() { + return ACManager.INSTANCE; + } + + /** + * This method tries to stop a running analysis. + * + * @param project + * The project to be stopped. + * @throws AnalysisNotRunningException + * If the analysis is not running or has not yet been initialized. + * @throws InterruptedException + * If the current thread has somehow been interrupted while waiting for the existing analysis thread. + */ + public void stopAnalysisController(final String project) throws AnalysisNotRunningException, InterruptedException { + final Pair<AnalysisController, Thread> currController = this.analysisController.get(project); + synchronized (currController) { + // Is there a thread available? + if ((currController.getFst() == null) || (currController.getSnd() == null)) { + throw new AnalysisNotRunningException(); + } + + // Try to stop the analysis + currController.getFst().terminate(); + currController.getSnd().join(ACManager.MAX_THREAD_WAIT_TIME_MS); + } + } + + /** + * This method tries to start the analysis for the given project. It has already to be initialized. + * + * @param project + * The project to be started. + * @throws ProjectAlreadyStartedException + * If the project is already running. + * @throws AnalysisNotInstantiatedException + * If the analysis has not yet been initialized. + */ + public void startAnalysisController(final String project) throws ProjectAlreadyStartedException, AnalysisNotInstantiatedException { + final Pair<AnalysisController, Thread> currController = this.analysisController.get(project); + synchronized (currController) { + // Is there an analysis after all? + if (currController.getFst() == null) { + throw new AnalysisNotInstantiatedException(); + } + // Check whether this analysis has already been started. + if (currController.getSnd() != null) { + throw new ProjectAlreadyStartedException(); + } else { + // Otherwise start a thread and run the analysis in it. + currController.setSnd(new Thread() { + @Override + public void run() { + try { + currController.getFst().run(); + } catch (final IllegalStateException ex) { + ex.printStackTrace(); + } catch (final AnalysisConfigurationException ex) { + ex.printStackTrace(); + } + } + }); + + currController.getSnd().start(); + } + } + } + + /** + * This method tries to instantiate the analysis controller of the given project using the data available on the file system. + * + * @param project + * The project whose analysis controller should be instantiated. + * @throws NullPointerException + * If an error occurred while loading the project. + * @throws AnalysisConfigurationException + * If the given configuration is somehow invalid. + * @throws IOException + * If an error occurred while loading the project. + * @throws ProjectStillRunningException + * If there exists already an analysis controller and is still running. + */ + public void instantiateAnalysisController(final String project) throws NullPointerException, AnalysisConfigurationException, IOException, + ProjectStillRunningException { + // Add the potential new project atomically + final MIProject modelProject = FSManager.getInstance().openProject(project); + final ClassLoader classLoader = FSManager.getInstance().getClassLoader(project); + final Pair<AnalysisController, Thread> newController = new Pair<AnalysisController, Thread>(new AnalysisController(modelProject, classLoader), null); + final Pair<AnalysisController, Thread> currController = this.analysisController.putIfAbsent(project, newController); + + if (currController != null) { + // There is currently an analysis controller available. Decide what to do. + synchronized (currController) { + switch (currController.getFst().getState()) { + case FAILED: + case TERMINATED: + case READY: + // No problem in instantiating a new controller + this.analysisController.put(project, newController); + break; + case RUNNING: + throw new ProjectStillRunningException("The project with the name '" + project + "' is still running."); + } + } + } + } + + /** + * This method can be used to deliver the state of the analysis controller of the given project as a human readable string. + * + * @param project + * The project whose state should be delivered. + * @return The current state of the corresponding {@link AnalysisController} if it exists, 'N/A' otherwise. + */ + public String getAnalysisControllerStateString(final String project) { + final STATE controllerState = this.getAnalysisControllerState(project); + final String controllerStateString; + + if (controllerState == null) { + controllerStateString = "N/A"; + } else { + controllerStateString = controllerState.toString(); + } + + return controllerStateString; + } + + /** + * This method can be used to deliver the state of the analysis controller of the given project as a human readable string. + * + * @param project + * The project whose state should be delivered. + * @return The current state of the corresponding {@link AnalysisController} if it exists, 'N/A' otherwise. + */ + public STATE getAnalysisControllerState(final String project) { + final Pair<AnalysisController, Thread> controller = this.analysisController.get(project); + + final STATE controllerState; + if (controller == null) { + controllerState = null; + } else { + synchronized (controller) { + if (controller.getFst() == null) { + controllerState = null; + } else { + controllerState = controller.getFst().getState(); + } + } + } + + return controllerState; + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotInstantiatedException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotInstantiatedException.java new file mode 100644 index 00000000..6f789155 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotInstantiatedException.java @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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 AnalysisNotInstantiatedException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of this class. + */ + public AnalysisNotInstantiatedException() { + // No code necessary + } + + /** + * Creates a new instance of this class using the given parameters. + * + * @param msg + * The message used for the exception. + */ + public AnalysisNotInstantiatedException(final String msg) { + super(msg); + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java new file mode 100644 index 00000000..ff9a3823 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/AnalysisNotRunningException.java @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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 AnalysisNotRunningException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of this class. + */ + public AnalysisNotRunningException() { + // No code necessary + } + + /** + * Creates a new instance of this class using the given parameters. + * + * @param msg + * The message used for the exception. + */ + public AnalysisNotRunningException(final String msg) { + super(msg); + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectAlreadyStartedException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectAlreadyStartedException.java new file mode 100644 index 00000000..3a76cba6 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectAlreadyStartedException.java @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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 given project has already been started. + * + * @author Nils Christian Ehmke + * @version 1.0 + */ +public class ProjectAlreadyStartedException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of this class. + */ + public ProjectAlreadyStartedException() { + // No code necessary + } + + /** + * Creates a new instance of this class using the given parameters. + * + * @param msg + * The message used for the exception. + */ + public ProjectAlreadyStartedException(final String msg) { + super(msg); + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectStillRunningException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectStillRunningException.java new file mode 100644 index 00000000..cbd66f2e --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/ProjectStillRunningException.java @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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 project is still running. + * + * @author Nils Christian Ehmke + * @version 1.0 + */ +public class ProjectStillRunningException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of this class. + */ + public ProjectStillRunningException() { + // No code necessary + } + + /** + * Creates a new instance of this class using the given parameters. + * + * @param msg + * The message used for the exception. + */ + public ProjectStillRunningException(final String msg) { + super(msg); + } +} diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml index 204287fa..834ae220 100644 --- a/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml +++ b/Kieker.WebGUI/src/main/webapp/AnalysisController.xhtml @@ -44,25 +44,36 @@ </p:layoutUnit> <p:layoutUnit position="south" header="Control" resizable="true" collapsible="true"> - <h:form> - <p:commandButton value="Instantiate Analysis Controller" disabled="#{empty currentAnalysisControllerProjectBean.projectName}"/> - <p:commandButton value="Start Analysis" disabled="true"/> - <p:commandButton value="Stop Analysis" disabled="true"/> - <hr/> + <h:form id="controllerForm"> + <p:commandButton value="Instantiate Analysis Controller" action="#{currentAnalysisControllerProjectBean.instantiateAnalysis()}" update=":messages" disabled="#{empty currentAnalysisControllerProjectBean.projectName}"/> + <p:commandButton value="Start Analysis" action="#{currentAnalysisControllerProjectBean.startAnalysis()}" update=":messages" disabled="#{empty currentAnalysisControllerProjectBean.projectName}"/> + <p:commandButton value="Stop Analysis" action="#{currentAnalysisControllerProjectBean.stopAnalysis()}" update=":messages" disabled="#{empty currentAnalysisControllerProjectBean.projectName}"/> + </h:form> + <hr/> + <h:form id="ledsForm"> <div align="center"> - <h:graphicImage id="iconLEDRed1" url="../img/Icon_LED_Red.png" height="50px"/> + <h:graphicImage id="iconLEDRed1" url="../img/Icon_LED_Red.png" height="50px" rendered="#{currentAnalysisControllerProjectBean.isAnalysisNotAvailable()}"/> + <h:graphicImage id="iconLEDRed1_2" url="../img/Icon_LED_Gray.png" height="50px" rendered="#{not currentAnalysisControllerProjectBean.isAnalysisNotAvailable()}"/> <p:spacer height="0" width="15px"/> - <h:graphicImage id="iconLEDYellow" url="../img/Icon_LED_Gray.png" height="50px"/> + <h:graphicImage id="iconLEDYellow" url="../img/Icon_LED_Yellow.png" height="50px" rendered="#{currentAnalysisControllerProjectBean.isAnalysisReady()}"/> + <h:graphicImage id="iconLEDYellow_2" url="../img/Icon_LED_Gray.png" height="50px" rendered="#{not currentAnalysisControllerProjectBean.isAnalysisReady()}"/> <p:spacer height="0" width="15px"/> - <h:graphicImage id="iconLEDGreen" url="../img/Icon_LED_Gray.png" height="50px"/> + <h:graphicImage id="iconLEDGreen" url="../img/Icon_LED_Green.png" height="50px" rendered="#{currentAnalysisControllerProjectBean.isAnalysisRunning()}"/> + <h:graphicImage id="iconLEDGreen_2" url="../img/Icon_LED_Gray.png" height="50px" rendered="#{not currentAnalysisControllerProjectBean.isAnalysisRunning()}"/> <p:spacer height="0" width="15px"/> - <h:graphicImage id="iconLEDRed2" url="../img/Icon_LED_Gray.png" height="50px"/> + <h:graphicImage id="iconLEDRed2" url="../img/Icon_LED_Red.png" height="50px" rendered="#{currentAnalysisControllerProjectBean.isAnalysisTerminated() or currentAnalysisControllerProjectBean.isAnalysisFailed()}"/> + <h:graphicImage id="iconLEDRed2_2" url="../img/Icon_LED_Gray.png" height="50px" rendered="#{not (currentAnalysisControllerProjectBean.isAnalysisTerminated() or currentAnalysisControllerProjectBean.isAnalysisFailed())}"/> <p:tooltip for="iconLEDRed1" value="Indicates that the AnalysisController has not been instantiated yet."/> <p:tooltip for="iconLEDYellow" value="Indicates that the AnalysisController has been instantiated, but not yet started."/> <p:tooltip for="iconLEDGreen" value="Indicates that the AnalysisController has been started and is running."/> - <p:tooltip for="iconLEDRed2" value="Indicates that the AnalysisController has been terminated."/> + <p:tooltip for="iconLEDRed2" value="Indicates that the AnalysisController has been terminated or has failed."/> + <p:tooltip for="iconLEDRed1_2" value="Indicates that the AnalysisController has not been instantiated yet."/> + <p:tooltip for="iconLEDYellow_2" value="Indicates that the AnalysisController has been instantiated, but not yet started."/> + <p:tooltip for="iconLEDGreen_2" value="Indicates that the AnalysisController has been started and is running."/> + <p:tooltip for="iconLEDRed2_2" value="Indicates that the AnalysisController has been terminated or has failed."/> </div> + <p:poll interval="1" update="ledsForm"/> </h:form> </p:layoutUnit> </p:layout> -- GitLab