/*******************************************************************************
* Copyright (c) 2016 École Polytechnique de Montréal and others
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Geneviève Bastien - Initial API and implementation
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.module;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.XmlPatternAnalysis;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternDensityView;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternLatencyTableView;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternScatterGraphView;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternStatisticsView;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.timegraph.XmlTimeGraphView;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.xychart.XmlXYView;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisOutput;
import org.eclipse.tracecompass.tmf.core.analysis.ITmfNewAnalysisModuleListener;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* This class searches all XML files to find outputs applicable to the newly
* created analysis
*
* @author Geneviève Bastien
*/
public class TmfXmlAnalysisOutputSource implements ITmfNewAnalysisModuleListener {
/** String separating data elements for the output properties */
public static final @NonNull String DATA_SEPARATOR = ";;;"; //$NON-NLS-1$
/**
* Enum to match the name of a view's XML element to its view ID.
*/
public static enum ViewType {
/**
* Time graph view element
*/
TIME_GRAPH_VIEW(TmfXmlUiStrings.TIME_GRAPH_VIEW, XmlTimeGraphView.ID),
/**
* XY chart view element
*/
XY_VIEW(TmfXmlUiStrings.XY_VIEW, XmlXYView.ID);
private final @NonNull String fXmlElem;
private final String fViewId;
private ViewType(@NonNull String xmlElem, String viewId) {
fXmlElem = xmlElem;
fViewId = viewId;
}
/**
* Get the XML element corresponding to this view type
*
* @return The XML element corresponding to this type
*/
public @NonNull String getXmlElem() {
return fXmlElem;
}
private String getViewId() {
return fViewId;
}
}
/**
* Enum for latency view type.
*
* @author Jean-Christian Kouame
*/
public static enum LatencyViewType {
/**
* Latency Table View type
*/
LATENCY_TABLE(PatternLatencyTableView.ID, Messages.TmfXmlAnalysisOutputSource_LatencyTable),
/**
* Latency Scatter View type
*/
SCATTER_GRAPH(PatternScatterGraphView.ID, Messages.TmfXmlAnalysisOutputSource_ScatterGraphTitle),
/**
* Latency Density View type
*/
DENSITY_VIEW(PatternDensityView.ID, Messages.TmfXmlAnalysisOutputSource_DensityChartTitle),
/**
* Latency Statistic View type
*/
STATISTIC_VIEW(PatternStatisticsView.ID, Messages.TmfXmlAnalysisOutputSource_LatencyStatisticsTitle);
private @NonNull String fLatencyViewId;
private String fLatencyViewLabel;
private LatencyViewType(@NonNull String viewId, String label) {
fLatencyViewId = viewId;
fLatencyViewLabel = label;
}
/**
* Get the ID of the latency view
*
* @return The ID
*/
public String getViewId() {
return fLatencyViewId;
}
/**
* Get the label of the view
*
* @return The label
*/
public String getLabel() {
return fLatencyViewLabel;
}
}
@Override
public void moduleCreated(IAnalysisModule module) {
// Get all the XML files, builtin and not builtin
Set<File> files = XmlUtils.listBuiltinFiles().values().stream()
.map(p -> p.toFile())
.collect(Collectors.toSet());
XmlUtils.listFiles().values().stream()
.forEach(f -> files.add(f));
for (File xmlFile : files) {
if (!XmlUtils.xmlValidate(xmlFile).isOK()) {
continue;
}
try {
Document doc = XmlUtils.getDocumentFromFile(xmlFile);
/* get state provider views if the analysis has state systems */
if (module instanceof ITmfAnalysisModuleWithStateSystems) {
for (ViewType viewType : ViewType.values()) {
NodeList ssViewNodes = doc.getElementsByTagName(viewType.getXmlElem());
for (int i = 0; i < ssViewNodes.getLength(); i++) {
Element node = (Element) ssViewNodes.item(i);
/* Check if analysis is the right one */
List<Element> headNodes = XmlUtils.getChildElements(node, TmfXmlStrings.HEAD);
if (headNodes.size() != 1) {
continue;
}
List<Element> analysisNodes = XmlUtils.getChildElements(headNodes.get(0), TmfXmlStrings.ANALYSIS);
for (Element analysis : analysisNodes) {
String analysisId = analysis.getAttribute(TmfXmlStrings.ID);
if (analysisId.equals(module.getId())) {
String viewId = viewType.getViewId();
IAnalysisOutput output = new TmfXmlViewOutput(viewId, viewType);
output.setOutputProperty(TmfXmlUiStrings.XML_OUTPUT_DATA, node.getAttribute(TmfXmlStrings.ID) + DATA_SEPARATOR + xmlFile.getAbsolutePath(), false);
module.registerOutput(output);
}
}
}
}
}
// Add the latency views for pattern analysis
if (module instanceof XmlPatternAnalysis) {
for (LatencyViewType viewType : LatencyViewType.values()) {
IAnalysisOutput output = new TmfXmlLatencyViewOutput(viewType.getViewId(), viewType.getLabel());
output.setOutputProperty(TmfXmlUiStrings.XML_LATENCY_OUTPUT_DATA, module.getId() + DATA_SEPARATOR + viewType.getLabel(), false);
module.registerOutput(output);
}
}
} catch (ParserConfigurationException | SAXException | IOException e) {
Activator.logError("Error opening XML file", e); //$NON-NLS-1$
}
}
}
}