diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java index 929d33c23a4bf8abb8c847cd44fab64add75937e..40e78198a12854598d1b4ca699e84f9e7007d8b5 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java @@ -23,12 +23,14 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import javax.faces.application.Application; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.ViewScoped; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; +import javax.faces.component.html.HtmlOutputText; import javax.faces.context.FacesContext; import kieker.analysis.display.annotation.Display; @@ -50,8 +52,14 @@ import kieker.webgui.common.exception.NewerProjectException; import kieker.webgui.common.exception.ProjectLoadException; import kieker.webgui.common.exception.ProjectNotExistingException; +import org.primefaces.component.dashboard.Dashboard; +import org.primefaces.component.panel.Panel; import org.primefaces.context.RequestContext; import org.primefaces.event.TabChangeEvent; +import org.primefaces.model.DashboardColumn; +import org.primefaces.model.DashboardModel; +import org.primefaces.model.DefaultDashboardColumn; +import org.primefaces.model.DefaultDashboardModel; /** * The {@link CurrentCockpitEditorBean} contains the necessary data behind an instance of the cockpit editor. @@ -63,43 +71,87 @@ import org.primefaces.event.TabChangeEvent; @ManagedBean @ViewScoped public final class CurrentCockpitEditorBean { - /** - * This is the log for errors, exceptions etc. - */ + + private static final int NUMBER_COLUMNS = 2; private static final Log LOG = LogFactory.getLog(CurrentCockpitEditorBean.class); - /** - * This is the factory which will be used to create new components for the project. - */ + private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory(); - /** - * This is the name of the stored project. It can be used as an identifier within the FS-Manager - */ + private final IProjectManagerFacade projectManagerFacade = ProjectManagerFacade.getInstance(); + private ClassAndMethodContainer classAndMethodContainer; + + private long timeStamp; private String projectName; - /** - * This is the actual model instance. It is the in-memory-model of the current (session) user. - */ private MIProject project; - /** - * This is the time stamp of the moment, the project was loaded or last saved. It can be used to check whether the project has been modified in the meanwhile. - */ - private long timeStamp; - /** - * This is the currently selected view. - */ private MIView activeView; + private ClassLoader classLoader; + private Dashboard dashboard; @ManagedProperty(value = "#{projectsBean}") private ProjectsBean projectsBean; - private final IProjectManagerFacade projectManagerFacade = ProjectManagerFacade.getInstance(); - private ClassAndMethodContainer classAndMethodContainer; - private ClassLoader classLoader; - /** * Creates a new instance of this class. <b>Do not call this constructor manually. It will only be accessed by JSF.</b> */ public CurrentCockpitEditorBean() { - // No code necessary + this.createDashboard(); + } + + private void createDashboard() { + final FacesContext fc = FacesContext.getCurrentInstance(); + final Application application = fc.getApplication(); + + // Create the primefaces dashboard + this.dashboard = (Dashboard) application.createComponent(fc, "org.primefaces.component.Dashboard", "org.primefaces.component.DashboardRenderer"); + this.dashboard.setId("dashboard"); + + // Create the model and add the columns + final DashboardModel model = new DefaultDashboardModel(); + for (int i = 0; i < CurrentCockpitEditorBean.NUMBER_COLUMNS; i++) { + final DashboardColumn column = new DefaultDashboardColumn(); + model.addColumn(column); + } + this.dashboard.setModel(model); + } + + private void fillDashboard() { + // Dump the old entries + this.clearDashboard(); + + // Now add the entries from the current view + if (this.activeView != null) { + final FacesContext fc = FacesContext.getCurrentInstance(); + final Application application = fc.getApplication(); + + // Add a panel for every display connector we have + final List<MIDisplayConnector> connectors = this.activeView.getDisplayConnectors(); + int i = 0; + for (final MIDisplayConnector connector : connectors) { + final Panel panel = (Panel) application.createComponent(fc, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer"); + panel.setId("displayConnectorPanel_" + i); + panel.setHeader(connector.getName()); + panel.setClosable(true); + panel.setToggleable(false); + + this.getDashboard().getChildren().add(panel); + final DashboardColumn column = this.dashboard.getModel().getColumn(i % CurrentCockpitEditorBean.NUMBER_COLUMNS); + column.addWidget(panel.getId()); + final HtmlOutputText text = new HtmlOutputText(); + text.setValue("N/A"); + + panel.getChildren().add(text); + i++; + } + } + } + + private void clearDashboard() { + // Run through all columns of the dashboard and remove the items + final List<DashboardColumn> columns = this.dashboard.getModel().getColumns(); + for (final DashboardColumn column : columns) { + column.getWidgets().clear(); + } + // Now run through the dashboard itself and remove the items as well + this.dashboard.getChildren().clear(); } /** @@ -138,6 +190,7 @@ public final class CurrentCockpitEditorBean { // Update the class loader and the specific classes used within various methods in this bean this.reloadClassLoader(); this.reloadClassesAndMethods(); + this.fillDashboard(); } } } catch (final ProjectLoadException ex) { @@ -349,6 +402,8 @@ public final class CurrentCockpitEditorBean { public void setActiveView(final MIView view) { synchronized (this) { this.activeView = view; + + this.fillDashboard(); } } @@ -365,6 +420,24 @@ public final class CurrentCockpitEditorBean { connector.setDisplay(display); connector.setName(UUID.randomUUID().toString()); this.activeView.getDisplayConnectors().add(connector); + + // Now add it to the dashboard as well + final FacesContext fc = FacesContext.getCurrentInstance(); + final Application application = fc.getApplication(); + + final Panel panel = (Panel) application.createComponent(fc, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer"); + panel.setId("displayConnectorPanel_" + (this.dashboard.getChildCount() + 1)); + panel.setHeader(connector.getName()); + panel.setClosable(true); + panel.setToggleable(false); + + this.getDashboard().getChildren().add(panel); + final DashboardColumn column = this.dashboard.getModel().getColumn(CurrentCockpitEditorBean.NUMBER_COLUMNS - 1); + column.addWidget(panel.getId()); + final HtmlOutputText text = new HtmlOutputText(); + text.setValue("N/A"); + + panel.getChildren().add(text); } } } @@ -426,4 +499,12 @@ public final class CurrentCockpitEditorBean { } } + public Dashboard getDashboard() { + return this.dashboard; + } + + public void setDashboard(final Dashboard dashboard) { + this.dashboard = dashboard; + } + } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java index 864df7ce37b94f801cd7d496812cb300b6a5cef3..ce755eb5c66c48807fa7f6c9b061aa7c011e5cce 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java @@ -55,6 +55,7 @@ public final class CurrentControllerBean { private final IProjectManagerFacade projectManagerFacade = ProjectManagerFacade.getInstance(); private final List<String> logEntries = new ArrayList<String>(); private String projectName; + @ManagedProperty(value = "#{projectsBean}") private ProjectsBean projectsBean; diff --git a/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_de.properties b/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_de.properties index 04c380d093735b3dee02040d716777a794297622..5c3863674fdf176603c92ed148b10db4402c9e90 100644 --- a/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_de.properties +++ b/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_de.properties @@ -16,8 +16,6 @@ autoLayout = Auto-Layout disable = Deaktivieren enable = Aktivieren -noPropertiesAvailable = Keine Eigenschaften vorhanden - name = Name className = ClassName @@ -38,10 +36,6 @@ repositoryPorts = Repositoryports msgProjectModified = Das Projekt wurde in der Zwischenzeit au\u00dferhalb dieses Editors modifiziert. Wollen Sie die \u00c4nderungen \u00fcberschreiben? -properties = Eigenschaften -property = Eigenschaft -value = Wert - libraries = Bibliotheken fileName = Dateiname fileSize = Gr\u00f6\u00dfe diff --git a/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_en.properties b/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_en.properties index d0169ee362b281b32d79ab112a316c649840b832..4e5c3c68a2939b7fa75ee2000892cf32b56b3116 100644 --- a/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_en.properties +++ b/Kieker.WebGUI/src/main/resources/lang/AnalysisEditorPage_en.properties @@ -16,8 +16,6 @@ autoLayout = Auto-Layout disable = Disable enable = Enable -noPropertiesAvailable = No properties available - name = Name className = ClassName @@ -38,10 +36,6 @@ repositoryPorts = Repository Ports msgProjectModified = The project has been modified externally in the meanwhile. Do you want to overwrite the changes? -properties = Properties -property = Property -value = Value - libraries = Libraries fileName = Filename fileSize = Size diff --git a/Kieker.WebGUI/src/main/resources/lang/Common_de.properties b/Kieker.WebGUI/src/main/resources/lang/Common_de.properties index d44232df58f5b44fe0fdd57b21d503db3ff9224e..edcc9c75283fec1aef6321d29e138e5f9f84d515 100644 --- a/Kieker.WebGUI/src/main/resources/lang/Common_de.properties +++ b/Kieker.WebGUI/src/main/resources/lang/Common_de.properties @@ -31,6 +31,11 @@ closeProject = Projekt schlie\u00dfen noRecordsFound = Keine Einträge vorhanden. +properties = Eigenschaften +property = Eigenschaft +value = Wert +noPropertiesAvailable = Keine Eigenschaften vorhanden + #------------------------------------------------------------------------------ # # These are the messages for the settings dialog. diff --git a/Kieker.WebGUI/src/main/resources/lang/Common_en.properties b/Kieker.WebGUI/src/main/resources/lang/Common_en.properties index 5b4af740775aa962d85f5bb99975dd30708b4ded..8e8211b5f25902b85034ff113c125684fa1947f7 100644 --- a/Kieker.WebGUI/src/main/resources/lang/Common_en.properties +++ b/Kieker.WebGUI/src/main/resources/lang/Common_en.properties @@ -31,6 +31,11 @@ closeProject = Close Project noRecordsFound = No records found. +properties = Properties +property = Property +value = Value +noPropertiesAvailable = No properties available + #------------------------------------------------------------------------------ # # These are the messages for the settings dialog. diff --git a/Kieker.WebGUI/src/main/webapp/AnalysisEditorPage.xhtml b/Kieker.WebGUI/src/main/webapp/AnalysisEditorPage.xhtml index f9c018c6fe1c62df0a5a8f7c027697f47fe18f05..c6a1794483ad26dbcad2fc9ab35300beadd38702 100644 --- a/Kieker.WebGUI/src/main/webapp/AnalysisEditorPage.xhtml +++ b/Kieker.WebGUI/src/main/webapp/AnalysisEditorPage.xhtml @@ -136,10 +136,10 @@ </p:layoutUnit> <!-- This is the component presenting the available properties. --> - <p:layoutUnit style="font-size: 12px" position="south" size="150" header="#{localizedAnalysisEditorPageMessages.properties}" resizable="true" collapsible="true"> + <p:layoutUnit style="font-size: 12px" position="south" size="150" header="#{localizedMessages.properties}" resizable="true" collapsible="true"> <h:form id="propertiesForm" > - <p:dataTable editable="true" value="#{currentAnalysisEditorBean.advancedPluginProperties}" var="property" rowIndexVar="rowIndex" emptyMessage="No properties available" rendered="#{not empty currentAnalysisEditorBean.selectedPlugin}"> - <p:column headerText="#{localizedAnalysisEditorPageMessages.property}" style="width:125px"> + <p:dataTable editable="true" value="#{currentAnalysisEditorBean.advancedPluginProperties}" var="property" rowIndexVar="rowIndex" emptyMessage="#{localizedMessages.noPropertiesAvailable}" rendered="#{not empty currentAnalysisEditorBean.selectedPlugin}"> + <p:column headerText="#{localizedMessages.property}" style="width:125px"> <!-- The first property is always the classname, the second one always the normal name. After that, other properties can follow. --> <h:outputText id="classNameProperty" value="#{localizedAnalysisEditorPageMessages.className}" rendered="#{rowIndex == 0}"/> <h:outputText id="nameProperty" value="#{localizedAnalysisEditorPageMessages.name}" rendered="#{rowIndex == 1}"/> @@ -150,7 +150,7 @@ </p:column> <!-- The classname is not editable, the name is editable with a specific target, other properies are editable normally. --> - <p:column headerText="#{localizedAnalysisEditorPageMessages.value}" style="width:125px"> + <p:column headerText="#{localizedMessages.value}" style="width:125px"> <h:outputText id="className" value="#{currentAnalysisEditorBean.selectedPlugin.classname}" rendered="#{rowIndex == 0}"/> <p:inplace id="nameEditor" editor="true" rendered="#{rowIndex == 1}" > <p:inputText value="#{currentAnalysisEditorBean.selectedPlugin.name}" /> diff --git a/Kieker.WebGUI/src/main/webapp/CockpitEditorPage.xhtml b/Kieker.WebGUI/src/main/webapp/CockpitEditorPage.xhtml index 4d1852923a078b598ad6f96a67492abf6899e89d..6dfdcb191de493a4ed4e94ab953b4392a1d583ab 100644 --- a/Kieker.WebGUI/src/main/webapp/CockpitEditorPage.xhtml +++ b/Kieker.WebGUI/src/main/webapp/CockpitEditorPage.xhtml @@ -32,16 +32,16 @@ <p:toolbarGroup align="right"> <p:commandButton styleClass="perspective-button" icon="ui-icon-home" action="ProjectOverview.xhtml" /> <p:separator/> - <p:button styleClass="perspective-button" icon="ui-icon-wrench" value="Analysis Editor" style="white-space: none" outcome="AnalysisEditor.xhtml"> + <p:button styleClass="perspective-button" icon="ui-icon-wrench" value="Analysis Editor" style="white-space: none" outcome="AnalysisEditorPage.xhtml"> <f:param name="projectName" value="#{currentCockpitEditorBean.projectName}" /> </p:button> - <p:button styleClass="perspective-button" icon="ui-icon-circle-triangle-e" value="Analysis" style="white-space: none" outcome="Controller.xhtml"> + <p:button styleClass="perspective-button" icon="ui-icon-circle-triangle-e" value="Analysis" style="white-space: none" outcome="ControllerPage.xhtml"> <f:param name="projectName" value="#{currentCockpitEditorBean.projectName}" /> </p:button> <p:separator/> <p:button styleClass="perspective-button" icon="ui-icon-wrench" value="Cockpit Editor" style="white-space: none" disabled="true"> </p:button> - <p:button styleClass="perspective-button" icon="ui-icon-image" value="Cockpit" style="white-space: none" outcome="Cockpit.xhtml"> + <p:button styleClass="perspective-button" icon="ui-icon-image" value="Cockpit" style="white-space: none" outcome="CockpitPage.xhtml"> <f:param name="projectName" value="#{currentCockpitEditorBean.projectName}" /> </p:button> </p:toolbarGroup> @@ -101,30 +101,27 @@ <p:layoutUnit position="center"> <h:form id="centerForm"> - <h:outputText value="Number of Columns: "/><br/> - <h:outputText value="Description: " /> - <p:inplace id="basic" editor="true"> - <p:inputText value="#{currentCockpitEditorBean.activeView.description}" /> - </p:inplace> - <br/> - <hr/> - <p:dataTable value="#{currentCockpitEditorBean.activeView.displayConnectors}" var="dispConn"> - <p:column headerText="Plugin" style="text-align: center"> - #{dispConn.display.parent.name} - </p:column> - <p:column headerText="Display Name" style="text-align: center"> - #{dispConn.display.name} - </p:column> - <p:column headerText="Name" style="text-align: center"> - <p:inplace id="basic" editor="true"> - <p:inputText value="#{dispConn.name}" validator="#{currentCockpitEditorBean.validateDisplayConnectorName}" /> - </p:inplace> - </p:column> - <p:column headerText="Column" style="text-align: center"> - </p:column> - <p:column style="text-align: center; width: 50px" > - <p:commandButton icon="ui-icon-trash" disabled="true"/> + <ui:fragment rendered="#{not empty currentCockpitEditorBean.activeView}"> + <h:outputText value="Description: "/> + <p:inplace id="basic" editor="true"> + <p:inputText value="#{currentCockpitEditorBean.activeView.description}" /> + </p:inplace> + <br/> + <hr/> + <p:dashboard id="dynamicDashboard" binding="#{currentCockpitEditorBean.dashboard}"/> + </ui:fragment> + </h:form> + </p:layoutUnit> + + <!-- This is the component presenting the available properties. --> + <p:layoutUnit style="font-size: 12px" position="south" size="150" header="#{localizedMessages.properties}" resizable="true" collapsible="true"> + <h:form id="propertiesForm" > + <p:dataTable editable="true" var="property" rowIndexVar="rowIndex" emptyMessage="#{localizedMessages.noPropertiesAvailable}"> + <p:column headerText="#{localizedMessages.property}" style="width:125px"> </p:column> + + <p:column headerText="#{localizedMessages.value}" style="width:125px"> + </p:column> </p:dataTable> </h:form> </p:layoutUnit> diff --git a/Kieker.WebGUI/src/main/webapp/ProjectOverviewPage.xhtml b/Kieker.WebGUI/src/main/webapp/ProjectOverviewPage.xhtml index e7a2d9cb56d1857cecb97abd0ac77478def22265..47c1ed3861b5a228c29786ab8e4b2befa219f7d4 100644 --- a/Kieker.WebGUI/src/main/webapp/ProjectOverviewPage.xhtml +++ b/Kieker.WebGUI/src/main/webapp/ProjectOverviewPage.xhtml @@ -77,7 +77,7 @@ <p:menuitem icon="ui-icon-analysis" id="controlAnalysis" styleClass="element-with-whitespace" value=" #{localizedMessages.analysis}" ajax="false" url="controller?projectName=#{project}" /> <p:separator/> - <p:menuitem icon="ui-icon-cockpitEditor" id="editAnalysisViews" styleClass="element-with-whitespace" value=" #{localizedMessages.cockpitEditor}" ajax="false" disabled="true" /> + <p:menuitem icon="ui-icon-cockpitEditor" id="editAnalysisViews" styleClass="element-with-whitespace" value=" #{localizedMessages.cockpitEditor}" ajax="false" url="cockpitEditor?projectName=#{project}" /> <p:menuitem icon="ui-icon-cockpit" id="showAnalysis" styleClass="element-with-whitespace" value=" #{localizedMessages.cockpit}" ajax="false" disabled="true" /> <p:separator/> <p:menuitem id="copyButton" icon="ui-icon-copy" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.copyProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="copyProjectDialog.show()"/>