Java tutorial
/* * Copyright 2017 Axway Software * * 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 com.axway.ats.testexplorer.pages.testcase.statistics.charts; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.mutable.MutableInt; import org.apache.log4j.Logger; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.Session; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.link.DownloadLink; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.request.mapper.parameter.INamedParameters.NamedPair; import org.apache.wicket.request.mapper.parameter.PageParameters; import com.axway.ats.log.autodb.SQLServerDbReadAccess; import com.axway.ats.log.autodb.entities.Statistic; import com.axway.ats.log.autodb.entities.StatisticDescription; import com.axway.ats.log.autodb.exceptions.DatabaseAccessException; import com.axway.ats.log.autodb.model.StatisticAggregatedType; import com.axway.ats.testexplorer.model.TestExplorerSession; import com.axway.ats.testexplorer.pages.testcase.statistics.BaseStatisticsPanel; import com.axway.ats.testexplorer.pages.testcase.statistics.ChartData; import com.axway.ats.testexplorer.pages.testcase.statistics.CsvWriter; import com.axway.ats.testexplorer.pages.testcase.statistics.DataPanel; import com.axway.ats.testexplorer.pages.testcase.statistics.DbStatisticDescription; import com.axway.ats.testexplorer.pages.testcase.statistics.MachineDescription; import com.axway.ats.testexplorer.pages.testcase.statistics.StatisticsTableCell; @SuppressWarnings({ "unchecked", "rawtypes" }) public class ChartsPanel extends BaseStatisticsPanel { private static final long serialVersionUID = 1L; private static final Logger LOG = Logger.getLogger(ChartsPanel.class); private static final String NBSP = " "; private static final int MAX_LABEL_LENGTH = 130; private static final String NO_DATA_HTML = "<div id=\"chartid\"><span class=\"nodata\">No data to display</span></div>"; private Form<Object> chartsPanelContent; private float timeOffSet; private Set<Integer> testcaseIds = new HashSet<Integer>(); private Set<String> actionNames = new HashSet<String>(); private int chartId = 0; // the deltas for each testcase's start time and the earliest start time protected Map<Integer, Long> testcaseStarttimeDeltas; private Map<String, List<DbStatisticDescription>> userAndSystemStatistics = new LinkedHashMap<String, List<DbStatisticDescription>>(); private Map<String, List<DbStatisticDescription>> actionStatistics = new LinkedHashMap<String, List<DbStatisticDescription>>(); private Map<String, List<DbStatisticDescription>> diagramContent = new LinkedHashMap<String, List<DbStatisticDescription>>(); public ChartsPanel(String id, PageParameters parameters) { super(id); // get all parameters from the URL parsePageParameters(parameters); systemStatisticsPanel = new DataPanel(this, "System statistics", "system"); userStatisticsPanel = new DataPanel(this, "User activities", "user"); actionStatisticsPanel = new DataPanel(this, "Action responses", "checkpoint"); loadStatisticDescriptions(this.timeOffSet, false); calculateTestcaseStarttimeDeltas(); chartsPanelContent = new Form("chartsPanelContent"); chartsPanelContent.setOutputMarkupId(true); // load the statistics data from the database getSystemStatistics(); getUserStatistics(); getActionStatistics(); ListView chartListView = getChartListViewComponent(); chartListView.setOutputMarkupId(true); Component detailedStatisticDescriptions = getStatisticsDetailsComponent(); detailedStatisticDescriptions.setOutputMarkupId(true); chartsPanelContent.add(chartListView); chartsPanelContent.add(detailedStatisticDescriptions); add(chartsPanelContent.setOutputMarkupId(true)); } private void parsePageParameters(PageParameters parameters) { for (NamedPair attr : parameters.getAllNamed()) { if ("timeOffSet".equals(attr.getKey())) { if (attr.getValue() != null && !attr.getValue().isEmpty()) { this.timeOffSet = Float.parseFloat(attr.getValue().toString()); } } else if (!"dbname".equals(attr.getKey()) && !"currentTestcase".equals(attr.getKey()) && !"tab".equals(attr.getKey())) { List<DbStatisticDescription> sysUserStats = new ArrayList<DbStatisticDescription>(); List<DbStatisticDescription> actionStats = new ArrayList<DbStatisticDescription>(); for (String stat : attr.getValue().toString().split(",")) { DbStatisticDescription statData = DbStatisticDescription.fromURL(stat); testcaseIds.add(statData.testcaseId); if (statData.statisticId != -1) { sysUserStats.add(statData); } else { actionNames.add(statData.name); actionStats.add(statData); } } if (!sysUserStats.isEmpty()) { userAndSystemStatistics.put(attr.getKey(), sysUserStats); } if (!actionStats.isEmpty()) { actionStatistics.put(attr.getKey(), actionStats); } } } } @Override protected List<StatisticDescription> loadSystemAndUserStatisticDescriptions(float timeOffSet) { if (!userAndSystemStatistics.isEmpty()) { StringBuilder uniqueStatisticIds = new StringBuilder(); for (Entry<String, List<DbStatisticDescription>> statsData : userAndSystemStatistics.entrySet()) { for (DbStatisticDescription stat : statsData.getValue()) { if (stat.statisticId != -1) { uniqueStatisticIds.append(stat.statisticId).append(","); } } } if (uniqueStatisticIds.length() <= 0) { return new ArrayList<StatisticDescription>(); } uniqueStatisticIds.setLength(uniqueStatisticIds.length() - 1); String uniqueTestcaseIds = StringUtils.join(testcaseIds, ","); try { String whereClause = "where ss.testcaseId in ( " + uniqueTestcaseIds + " ) and ss.statsTypeId in ( " + uniqueStatisticIds + " )"; /* * Due to internal working of the charting/drawing JavaScript library ( Chronoscope ), * timeOffset is passed as 0, and not as TestExplorerSession.getTimeOffset() * */ List<StatisticDescription> statisticDescriptions = getTESession().getDbReadConnection() .getSystemStatisticDescriptions(timeOffSet, whereClause, new HashMap<String, String>(), 0/* ( ( TestExplorerSession ) Session.get() ).getTimeOffset() */, ((TestExplorerSession) Session.get()).isDayLightSavingOn()); return statisticDescriptions; } catch (DatabaseAccessException e) { LOG.error("Error loading system statistic descriptions", e); return new ArrayList<StatisticDescription>(); } } else { return new ArrayList<StatisticDescription>(); } } @Override protected List<StatisticDescription> loadChechpointStatisticDescriptions(float timeOffSet) { if (!actionStatistics.isEmpty()) { String uniqueTestcaseIds = StringUtils.join(testcaseIds, ","); StringBuilder actions = new StringBuilder(); StringBuilder actionParents = new StringBuilder(); Set<String> expectedActions = new HashSet<String>(); for (List<DbStatisticDescription> actionList : actionStatistics.values()) { for (DbStatisticDescription action : actionList) { if (!actions.toString().contains("'" + action.name + "'")) { actions.append("'").append(action.name).append("'").append(","); } if (!actionParents.toString().contains("'" + action.parentName + "'")) { actionParents.append("'").append(action.parentName).append("',"); } expectedActions.add(action.testcaseId + "->" + action.machineId + "->" + action.parentName + "->" + action.name); } } if (actions.toString().endsWith(",")) { actions.setLength(actions.length() - 1); } if (actionParents.toString().endsWith(",")) { actionParents.setLength(actionParents.length() - 1); } try { String whereClause = " where tt.testcaseId in (" + uniqueTestcaseIds + ") AND chs.name in ( " + actions + " ) AND c.name in ( " + actionParents + " ) "; /* * Due to internal working of the charting/drawing JavaScript library ( Chronoscope ), * timeOffset is passed as 0, and not as TestExplorerSession.getTimeOffset() * */ List<StatisticDescription> statisticDescriptions = getTESession().getDbReadConnection() .getCheckpointStatisticDescriptions(this.timeOffSet, whereClause, expectedActions, 0/*( ( TestExplorerSession ) Session.get() ).getTimeOffset() */, ((TestExplorerSession) Session.get()).isDayLightSavingOn()); return statisticDescriptions; } catch (DatabaseAccessException e) { LOG.error("Error loading action response statistic descriptions", e); return new ArrayList<StatisticDescription>(); } } else { return new ArrayList<StatisticDescription>(); } } private ListView getChartListViewComponent() { // update the content of the ListView container refreshDiagramContent(); final List<String> charts = new ArrayList<String>(diagramContent.keySet()); return new ListView("chartsListView", charts) { private static final long serialVersionUID = 1L; @Override protected void populateItem(final ListItem item) { String diagramName = charts.get(item.getIndex()); List<ChartData> chartData = new ArrayList<ChartData>(); for (DbStatisticDescription stat : diagramContent.get(diagramName)) { chartData.add(stat.getChartData()); } Label chartTitle = new Label("chartTitle", diagramName); item.add(chartTitle); final String chartScript = getChartScript(chartData, chartId++); final Label chart = new Label("chartScriptContainer", chartScript); chart.setEscapeModelStrings(false); CsvWriter csvWriter = new CsvWriter(chartData); DownloadLink downloadChartDataLink = csvWriter.getDownloadChartDataLink(); AjaxLink refreshButton = getRefreshChartLink(charts.get(item.getIndex())); item.add(chart); item.add(downloadChartDataLink); item.add(refreshButton); } }; } private AjaxLink<?> getRefreshChartLink(final String diagramName) { AjaxLink refreshChartLink = new AjaxLink("refreshChart") { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { List<DbStatisticDescription> dataToBeUpdated = diagramContent.get(diagramName); Set<Integer> sysStatisticTypeIds = new HashSet<Integer>(); Set<Integer> sysMachineIds = new HashSet<Integer>(); Set<Integer> usrStatisticTypeIds = new HashSet<Integer>(); Set<Integer> usrMachineIds = new HashSet<Integer>(); Set<Integer> testcaseIds = new HashSet<Integer>(); StringBuilder actions = new StringBuilder(); StringBuilder actionParents = new StringBuilder(); Set<String> expectedActions = new HashSet<String>(); // collect all the data from this diagram, so all statistics could be updated successfully for (DbStatisticDescription dbStatDescription : dataToBeUpdated) { testcaseIds.add(dbStatDescription.testcaseId); if (SQLServerDbReadAccess.MACHINE_NAME_FOR_ATS_AGENTS.equals(dbStatDescription.machineName)) { usrStatisticTypeIds.add(dbStatDescription.statisticId); usrMachineIds.add(dbStatDescription.machineId); } else if (dbStatDescription.machineId != 0) { sysStatisticTypeIds.add(dbStatDescription.statisticId); sysMachineIds.add(dbStatDescription.machineId); } else { actions.append("'").append(dbStatDescription.name).append("'").append(","); if (actionParents.indexOf(dbStatDescription.parentName) == -1) { actionParents.append("'").append(dbStatDescription.parentName).append("',"); } expectedActions.add(dbStatDescription.testcaseId + "->" + dbStatDescription.machineId + "->" + dbStatDescription.parentName + "->" + dbStatDescription.name); } } loadActionStatisticsFromDatabase(testcaseIds, actions, actionParents, expectedActions); loadSystemStatisticsFromDatabase(sysStatisticTypeIds, sysMachineIds); loadUserStatisticsFromDatabase(usrStatisticTypeIds, usrMachineIds); refreshDiagramContent(); target.add(chartsPanelContent); } }; return refreshChartLink; } private void refreshDiagramContent() { // remove the old content diagramContent.clear(); for (Entry<String, List<DbStatisticDescription>> stat : userAndSystemStatistics.entrySet()) { if (diagramContent.containsKey(stat.getKey())) { diagramContent.get(stat.getKey()).addAll(stat.getValue()); } else { List<DbStatisticDescription> statistics = new ArrayList<DbStatisticDescription>(stat.getValue()); diagramContent.put(stat.getKey(), statistics); } } for (Entry<String, List<DbStatisticDescription>> stat : actionStatistics.entrySet()) { if (diagramContent.containsKey(stat.getKey())) { diagramContent.get(stat.getKey()).addAll(stat.getValue()); } else { List<DbStatisticDescription> statistics = new ArrayList<DbStatisticDescription>(stat.getValue()); diagramContent.put(stat.getKey(), statistics); } } } private void getSystemStatistics() { Set<Integer> sysStatisticIds = new HashSet<Integer>(); Set<Integer> sysMachineIds = new HashSet<Integer>(); for (MachineDescription machDesc : systemStatisticsPanel.getMachineDescriptions()) { for (DbStatisticDescription statDesc : machDesc.getStatDescriptionsList()) { if (!SQLServerDbReadAccess.MACHINE_NAME_FOR_ATS_AGENTS.equals(statDesc.machineName)) { for (Entry<String, List<DbStatisticDescription>> statsData : userAndSystemStatistics .entrySet()) { for (DbStatisticDescription dbStatDescription : statsData.getValue()) { if (dbStatDescription.statisticId != -1 && statDesc.testcaseId == dbStatDescription.testcaseId && statDesc.statisticId == dbStatDescription.statisticId && statDesc.machineId == dbStatDescription.machineId) { sysStatisticIds.add(dbStatDescription.statisticId); sysMachineIds.add(dbStatDescription.machineId); } } } } } } loadSystemStatisticsFromDatabase(sysStatisticIds, sysMachineIds); } private void getUserStatistics() { Set<Integer> userStatisticIds = new HashSet<Integer>(); Set<Integer> userMachineIds = new HashSet<Integer>(); for (MachineDescription machDesc : userStatisticsPanel.getMachineDescriptions()) { for (DbStatisticDescription statDesc : machDesc.getStatDescriptionsList()) { if (SQLServerDbReadAccess.MACHINE_NAME_FOR_ATS_AGENTS.equals(statDesc.machineName)) { for (Entry<String, List<DbStatisticDescription>> statsData : userAndSystemStatistics .entrySet()) { for (DbStatisticDescription dbStatDescription : statsData.getValue()) { if (dbStatDescription.statisticId != -1 && statDesc.testcaseId == dbStatDescription.testcaseId && statDesc.statisticId == dbStatDescription.statisticId && statDesc.machineId == dbStatDescription.machineId) { userStatisticIds.add(dbStatDescription.statisticId); userMachineIds.add(dbStatDescription.machineId); } } } } } } loadUserStatisticsFromDatabase(userStatisticIds, userMachineIds); } private void getActionStatistics() { StringBuilder actions = new StringBuilder(); StringBuilder actionParents = new StringBuilder(); Set<String> expectedActions = new HashSet<String>(); for (List<DbStatisticDescription> actionList : actionStatistics.values()) { for (DbStatisticDescription action : actionList) { if (!actions.toString().contains("'" + action.name + "'")) { actions.append("'").append(action.name).append("'").append(","); } if (!actionParents.toString().contains("'" + action.parentName + "'")) { actionParents.append("'").append(action.parentName).append("',"); } expectedActions.add(action.testcaseId + "->" + action.machineId + "->" + action.parentName + "->" + action.name); } } loadActionStatisticsFromDatabase(testcaseIds, actions, actionParents, expectedActions); } private void loadSystemStatisticsFromDatabase(Set<Integer> statisticTypeIds, Set<Integer> machineIds) { try { if (!machineIds.isEmpty() && !statisticTypeIds.isEmpty()) { String uniqueStatisticIds = StringUtils.join(statisticTypeIds, ","); String uniqueMachineIds = StringUtils.join(machineIds, ","); String uniqueTestcaseIds = StringUtils.join(testcaseIds, ","); /* * Due to internal working of the charting/drawing JavaScript library ( Chronoscope ), * timeOffset is passed as 0, and not as TestExplorerSession.getTimeOffset() * */ List<Statistic> statistics = getTESession().getDbReadConnection().getSystemStatistics(timeOffSet, uniqueTestcaseIds, uniqueMachineIds, uniqueStatisticIds, 0/*( ( TestExplorerSession ) Session.get() ).getTimeOffset()*/, ((TestExplorerSession) Session.get()).isDayLightSavingOn()); if (statistics.size() > 0) { // convert statistics data into chart data setChartData(systemStatisticsDataToChart(statistics, false, systemStatisticsPanel), false); } } } catch (DatabaseAccessException e) { LOG.error("Can't load system statistics from database", e); } } private void loadUserStatisticsFromDatabase(Set<Integer> statisticTypeIds, Set<Integer> machineIds) { try { if (!machineIds.isEmpty() && !statisticTypeIds.isEmpty()) { String uniqueStatisticIds = StringUtils.join(statisticTypeIds, ","); String uniqueMachineIds = StringUtils.join(machineIds, ","); String uniqueTestcaseIds = StringUtils.join(testcaseIds, ","); /* * Due to internal working of the charting/drawing JavaScript library ( Chronoscope ), * timeOffset is passed as 0, and not as TestExplorerSession.getTimeOffset() * */ List<Statistic> statistics = getTESession().getDbReadConnection().getSystemStatistics(timeOffSet, uniqueTestcaseIds, uniqueMachineIds, uniqueStatisticIds, 0/*( ( TestExplorerSession ) Session.get() ).getTimeOffset() */, ((TestExplorerSession) Session.get()).isDayLightSavingOn()); if (statistics.size() > 0) { // convert statistics data into chart data setChartData(systemStatisticsDataToChart(statistics, true, userStatisticsPanel), true); } } } catch (DatabaseAccessException e) { LOG.error("Can't load system statistics from database", e); } } private void setChartData(Collection<ChartData> statisticsChartData, boolean userStatistics) { for (List<DbStatisticDescription> stats : userAndSystemStatistics.values()) { for (DbStatisticDescription stat : stats) { Iterator<ChartData> chartDataIterator = statisticsChartData.iterator(); while (chartDataIterator.hasNext()) { ChartData chartData = chartDataIterator.next(); if (chartData.getTestcaseId() == stat.testcaseId && chartData.getStatisticTypeId() == stat.statisticId && chartData.getMachineId() == stat.machineId) { ChartData chartDataCopy = chartData.newInstance(); if (!stat.alias.equals("null") && !stat.alias.isEmpty()) { chartDataCopy.setLabel(stat.alias); } if (userStatistics) { stat.machineName = SQLServerDbReadAccess.MACHINE_NAME_FOR_ATS_AGENTS; } stat.setChartData(chartDataCopy); break; } } } } } private void loadActionStatisticsFromDatabase(Set<Integer> testcaseId, StringBuilder actions, StringBuilder actionParents, Set<String> expectedActions) { try { String uniqueTestcaseIds = StringUtils.join(testcaseIds, ","); if (actions.length() > 0 && actionParents.length() > 0) { actions.setLength(actions.length() - 1); actionParents.setLength(actionParents.length() - 1); /* * Due to internal working of the charting/drawing JavaScript library ( Chronoscope ), * timeOffset is passed as 0, and not as TestExplorerSession.getTimeOffset() * */ List<Statistic> statistics = getTESession().getDbReadConnection().getCheckpointStatistics( timeOffSet, uniqueTestcaseIds, actions.toString(), actionParents.toString(), expectedActions, new HashSet<String>(), 0/*((TestExplorerSession)Session.get()).getTimeOffset() */, ((TestExplorerSession) Session.get()).isDayLightSavingOn()); if (statistics.size() > 0) { List<ChartData> statisticsChartData = new ArrayList<ChartData>(); // convert statistics data into chart data statisticsChartData.addAll(addActionStatisticsDataToChart(statistics, actionStatisticsPanel)); for (ChartData chartData : statisticsChartData) { for (List<DbStatisticDescription> stats : actionStatistics.values()) { for (DbStatisticDescription stat : stats) { String statLabelName = getActionLabelName(stat.name, stat.parentName, "[action response] ", ", [queue] "); statLabelName = statLabelName + " at " + getMachineAliasForThisStatistic( stat.testcaseId, stat.machineId, actionStatisticsPanel); if (chartData.getLabel().equals(statLabelName) && chartData.getTestcaseId() == stat.testcaseId) { ChartData chartDataCopy = chartData.newInstance(); if (!stat.alias.equals("null") && !stat.alias.isEmpty()) { chartDataCopy.setLabel(stat.alias); } stat.setChartData(chartDataCopy); } } } } } } } catch (DatabaseAccessException e) { LOG.error("Can't load system statistics from database", e); } } private Collection<ChartData> systemStatisticsDataToChart(List<Statistic> loadedSystemStatistics, boolean userActivityStatistics, DataPanel panel) { // add the statistics to the chart if (userActivityStatistics) { return addChartData(null, loadedSystemStatistics, ", [queue] ", panel); } else { return addChartData(null, loadedSystemStatistics, null, panel); } } private Collection<ChartData> addActionStatisticsDataToChart(List<Statistic> loadedActionStatistics, DataPanel panel) { if (loadedActionStatistics.size() > 0) { // add the statistics to the chart return addChartData("[action response] ", loadedActionStatistics, ", [queue] ", panel); } else { return new ArrayList<ChartData>(); } } private Collection<ChartData> addChartData(String statPrefix, List<Statistic> statistics, String parentPrefix, DataPanel panel) { // statistics are unique per testcase and statistic type Map<String, ChartData> chartData = new HashMap<String, ChartData>(); for (Statistic stat : statistics) { // add statistic prefix String statDisplayName = getActionLabelName(stat.name, stat.parentName, statPrefix, parentPrefix); ChartData data = chartData.get(stat.getUid()); if (data == null) { data = new ChartData(statDisplayName, getMachineAliasForThisStatistic(stat.testcaseId, stat.machineId, panel), stat.unit); data.setTestcaseId(stat.testcaseId); data.setStatisticTypeId(stat.statisticTypeId); data.setMachineId(stat.machineId); chartData.put(stat.getUid(), data); } int displayValuesMode = 0; data.addAxisValues(stat.value, stat.avgValue, stat.sumValue, stat.totalValue, stat.countValue, displayValuesMode); long statisticTimestamp = stat.getStartTimestamp(); if (testcaseStarttimeDeltas.containsKey(stat.testcaseId)) { // we are doing time synchronization statisticTimestamp = statisticTimestamp - testcaseStarttimeDeltas.get(stat.testcaseId); } data.addTimestamp(statisticTimestamp); } return chartData.values(); } private String getActionLabelName(String statName, String statParentName, String statPrefix, String parentPrefix) { String statDisplayName = ""; if (statPrefix != null) { statDisplayName = statPrefix; } // add statistic name statDisplayName = statDisplayName + clearStatName(statName); // add statistic parent name if (parentPrefix != null) { statDisplayName = statDisplayName + parentPrefix + getActionQueueAliasModel(statParentName).getObject(); } return statDisplayName; } private String getMachineAliasForThisStatistic(int testcaseId, int machineId, DataPanel panel) { for (MachineDescription machine : panel.getMachineDescriptions()) { if (machine.getTestcaseId() == testcaseId && machine.getMachineId() == machineId) { return getMachineAliasModel(machine.getMachineAlias()).getObject(); } } // this should never happen return "FAKE MACHINE - THIS IS A PROBLEM"; } private String clearStatName(String statisticName) { if (statisticName.contains(NBSP)) { return statisticName.replace(NBSP, ""); } return statisticName; } private String getChartScript(Collection<ChartData> statisticsChartData, int chartNumber) { StringBuilder data = new StringBuilder(); data.append("var data = [\n"); StringBuilder markersScript = new StringBuilder(); MutableInt markersCount = new MutableInt(0); MutableInt statIndex = new MutableInt(0); // iterate selected statistics boolean statisticValuesArePresent = true; for (ChartData chartData : statisticsChartData) { if (chartData != null) { for (int displayValueMode : StatisticAggregatedType.getAllTypes(chartData.getDisplayValuesMode())) { statisticValuesArePresent = appendStatisticJSData(data, chartData, displayValueMode, statIndex, markersCount, markersScript, statisticsChartData.size()); if (!statisticValuesArePresent) { return "<div id=\"chartMsgsPanel\">'" + chartData.getLabel() + "' doesn't have enough values to display the chart" + "</div>\n" + NO_DATA_HTML; } } } } data = data.deleteCharAt(data.length() - 1); // delete the last comma data.append("\n];\n"); StringBuilder scriptString = new StringBuilder(); scriptString.append("\n<script type=\"text/javascript\">\n"); scriptString.append("$(document).ready(function(){\n"); scriptString.append("var loaded=false;\n"); scriptString.append("function onChronoscopeLoaded(chrono) {\n"); scriptString.append("\tloaded=true;\n"); scriptString.append(data.toString()); scriptString.append("\tchronoscope.Chronoscope.setVerticalCrosshair(false);\n"); scriptString.append("\tchronoscope.Chronoscope.setFontBookRendering(true);\n"); scriptString.append("\tchronoscope.Chronoscope.setErrorReporting(true);\n"); scriptString.append("\tchronoscope.Chronoscope.createTimeseriesChartById(\"chartid" + chartNumber + "\",data,980,600,function(view)\n"); scriptString.append("\t\t{\n"); scriptString.append("\t\t\tvar plot=view.getChart().getPlot();\n"); scriptString.append("\t\t\tview.getChart().redraw();\n"); scriptString.append("\t\t\tlargeview=view;\n"); scriptString.append("\t\t});\n}\n"); scriptString.append( "if (!loaded && typeof(chronoscope)!=\"undefined\" && chronoscope != null) onChronoscopeLoaded(chronoscope);\n"); scriptString.append( "if (typeof(refreshButtonClicked)==\"undefined\" || !refreshButtonClicked) location.hash = '#chart';\n"); scriptString.append("});\n"); scriptString.append("</script>\n"); scriptString.append("<div class=\"chartid\" id=\"chartid" + chartNumber + "\"></div>\n"); return scriptString.toString(); } private boolean appendStatisticJSData(StringBuilder data, ChartData chartData, int displayValueMode, MutableInt statIndex, MutableInt markersCount, StringBuilder markersScript, int actionCount) { String label = null; String unit = chartData.getUnit(); if (StatisticAggregatedType.isAverage(displayValueMode)) { label = chartData.getLabel("Avg"); } else if (StatisticAggregatedType.isSum(displayValueMode)) { label = chartData.getLabel("Sum"); } else if (StatisticAggregatedType.isTotals(displayValueMode)) { label = chartData.getLabel("Total"); } else if (StatisticAggregatedType.isCount(displayValueMode)) { label = chartData.getLabelNoUnit("Count"); unit = "Count"; } else { label = chartData.getLabel(); } String timestamps = null; String values = null; if (chartData.getLabel().startsWith("[action response]") && displayValueMode == StatisticAggregatedType.REGULAR) { String[] tmpsAndAxisVals = chartData.getTimestampsAndAxisValuesAsString(statIndex.intValue(), actionCount); timestamps = tmpsAndAxisVals[0]; values = tmpsAndAxisVals[1]; markersScript.append(chartData.getJsMarkersScript()); markersCount.add(chartData.getJsMarkersCount()); } else { timestamps = chartData.getTimestampsAsString(); values = chartData.getAxisValuesAsString(displayValueMode); } if (timestamps.indexOf(',') < 0) { // not enough values for chart return false; } data.append("\t{\n"); data.append("\t\t\"domainscale\": 1000,\n"); data.append("\t\t\"preferredRenderer\": \"line\",\n"); if (label.length() > MAX_LABEL_LENGTH) { label = label.substring(0, MAX_LABEL_LENGTH) + "..."; } data.append("\t\t\"label\": \"" + label + " (" + unit + ") " + "\",\n"); data.append("\t\t\"axis\": \"" + unit.replace("Δ", "") + "\", \n"); data.append("\t\t\"domain\": [" + timestamps + "],\n"); data.append("\t\t\"range\": [" + values + "],\n"); data.append("\t},"); statIndex.increment(); return true; } /** * @return statistic details component with all Min, Avg and Max values */ private Component getStatisticsDetailsComponent() { List<List<StatisticsTableCell>> rows = new ArrayList<List<StatisticsTableCell>>(); List<StatisticsTableCell> columns = new ArrayList<StatisticsTableCell>(); // add title columns.add(new StatisticsTableCell( "<img class=\"arrowUD\" src=\"images/up.png\"> System statistic details", false)); // add machine value columns List<MachineDescription> mergedMachineDescriptions = getMergedMachineDescriptions(); columns.add(new StatisticsTableCell(true, getMachineAliasModel("Values"))); rows.add(columns); rows.addAll(systemStatisticsPanel.generateStatisticDetailRows(mergedMachineDescriptions, diagramContent)); rows.addAll(userStatisticsPanel.generateStatisticDetailRows(mergedMachineDescriptions, diagramContent)); rows.addAll(actionStatisticsPanel.generateStatisticDetailRows(mergedMachineDescriptions, diagramContent)); ListView<List<StatisticsTableCell>> statisticDetailsTable = new ListView<List<StatisticsTableCell>>( "statDetailsRows", rows) { private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem<List<StatisticsTableCell>> item) { // table TR if (item.getIndex() == 0) { item.add(AttributeModifier.replace("class", "statDetailsHeaderRow")); item.add(AttributeModifier.replace("onclick", "showOrHideTableRows('statDetailsTable',1,false);")); } else if (item.getIndex() > 1 && item.getModelObject().get(0).labelText.contains("statUnit")) { item.add(AttributeModifier.replace("class", "statDetailsStatNameRow")); } item.add(new ListView<StatisticsTableCell>("statDetailsColumns", item.getModelObject()) { private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem<StatisticsTableCell> item) { // table TD if (item.getIndex() > 0) { // skip the first column item.add(AttributeModifier.replace("class", "statDetailsCenCol")); } StatisticsTableCell cell = item.getModelObject(); Label label = null; if (cell.isInputText) { label = new Label("label", cell.getMachineLabelModel()); if (cell.getMachineLabelModel() != null) { rememberMachineAliasLabel(label); } } else { label = new Label("label", cell.labelText); } label.setEscapeModelStrings(false); item.add(label); } }); } }; return statisticDetailsTable; } /** * Some machine descriptions are available in more than one statistic panel, * but in some cases we need only unique machine descriptions * @return */ private List<MachineDescription> getMergedMachineDescriptions() { List<MachineDescription> mergedMachineDescriptions = new ArrayList<MachineDescription>(); mergedMachineDescriptions = mergeMachineDescriptions(mergedMachineDescriptions, systemStatisticsPanel.getMachineDescriptions()); mergedMachineDescriptions = mergeMachineDescriptions(mergedMachineDescriptions, userStatisticsPanel.getMachineDescriptions()); mergedMachineDescriptions = mergeMachineDescriptions(mergedMachineDescriptions, actionStatisticsPanel.getMachineDescriptions()); return mergedMachineDescriptions; } private List<MachineDescription> mergeMachineDescriptions(List<MachineDescription> mergedMachineDescriptions, Set<MachineDescription> machineDescriptions) { for (MachineDescription machineDescription : machineDescriptions) { boolean machineFound = false; for (MachineDescription mergedMachineDescription : mergedMachineDescriptions) { if (mergedMachineDescription.getMachineAlias().equals(machineDescription.getMachineAlias()) && machineDescription.getTestcaseId() == mergedMachineDescription.getTestcaseId()) { machineFound = true; for (DbStatisticDescription statisticDescription : machineDescription .getStatDescriptionsList()) { mergedMachineDescription.addStatisticDescription(statisticDescription); } } } if (!machineFound) { mergedMachineDescriptions.add(machineDescription.newSimpleInstance()); } } return mergedMachineDescriptions; } /** * When comparing data from 2 or more testcases, we have to move the * timestamps so user can compare the statistical data */ protected void calculateTestcaseStarttimeDeltas() { long earliestStarttime = Long.MAX_VALUE; this.testcaseStarttimeDeltas = new HashMap<Integer, Long>(); List<MachineDescription> allMachines = new ArrayList<MachineDescription>(); allMachines.addAll(systemStatisticsPanel.getMachineDescriptions()); allMachines.addAll(userStatisticsPanel.getMachineDescriptions()); allMachines.addAll(actionStatisticsPanel.getMachineDescriptions()); // first check if needed to deal with starttime deltas int firstTestcaseId = -1; for (MachineDescription machine : allMachines) { if (firstTestcaseId == -1) { firstTestcaseId = machine.getTestcaseId(); } } // collect the starttimes of each testcase for (MachineDescription machine : allMachines) { Long testcaseStarttime = testcaseStarttimeDeltas.get(machine.getTestcaseId()); if (testcaseStarttime == null) { testcaseStarttime = machine.getTestcaseStarttime(); testcaseStarttimeDeltas.put(machine.getTestcaseId(), testcaseStarttime); if (testcaseStarttime < earliestStarttime) { earliestStarttime = testcaseStarttime; } } } // calculate the delta for each testcase's start time and the // earliest start time for (int testcaseId : testcaseStarttimeDeltas.keySet()) { testcaseStarttimeDeltas.put(testcaseId, (testcaseStarttimeDeltas.get(testcaseId) - earliestStarttime)); } } }