blob: 78850fefbc70b26817c7570290f5653c76fcc4f2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.compile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.model.DataDrivenStateSystemPath;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenOutputEntry;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.output.DataDrivenXYDataProvider.DisplayType;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils;
import org.w3c.dom.Element;
/**
* Compilation unit for XML time graph entries
*
* @author Geneviève Bastien
*/
public class TmfXmlOutputEntryCu implements IDataDrivenCompilationUnit {
private final List<TmfXmlOutputEntryCu> fChildrenEntries;
private final String fPath;
private final @Nullable String fAnalysisId;
private final boolean fDisplayText;
private final @Nullable TmfXmlStateSystemPathCu fDisplayCu;
private final @Nullable TmfXmlStateSystemPathCu fIdCu;
private final @Nullable TmfXmlStateSystemPathCu fParentCu;
private final @Nullable TmfXmlStateSystemPathCu fNameCu;
private final DisplayType fDisplayType;
private TmfXmlOutputEntryCu(List<TmfXmlOutputEntryCu> childrenCu, String path,
@Nullable String analysisId, boolean displayText,
@Nullable TmfXmlStateSystemPathCu displayCu,
@Nullable TmfXmlStateSystemPathCu idCu,
@Nullable TmfXmlStateSystemPathCu parentCu,
@Nullable TmfXmlStateSystemPathCu nameCu,
DisplayType displayType) {
fChildrenEntries = childrenCu;
fPath = path;
fAnalysisId = analysisId;
fDisplayText = displayText;
fDisplayCu = displayCu;
fIdCu = idCu;
fParentCu = parentCu;
fNameCu = nameCu;
fDisplayType = displayType;
}
@Override
public DataDrivenOutputEntry generate() {
List<DataDrivenOutputEntry> entries = fChildrenEntries.stream()
.map(TmfXmlOutputEntryCu::generate)
.collect(Collectors.toList());
DataDrivenStateSystemPath display = fDisplayCu != null ? fDisplayCu.generate() : null;
DataDrivenStateSystemPath id = fIdCu != null ? fIdCu.generate() : null;
DataDrivenStateSystemPath parent = fParentCu != null ? fParentCu.generate() : null;
DataDrivenStateSystemPath name = fNameCu != null ? fNameCu.generate() : null;
return new DataDrivenOutputEntry(entries, fPath, fAnalysisId, fDisplayText,
display, id, parent, name, fDisplayType);
}
/**
* Compile a time graph view entry
*
* @param compilationData
* The analysis compilation data
* @param entryEl
* The XML element
* @return The time graph entry compilation unit or <code>null</code> if the
* entry did not compile properly.
*/
public static @Nullable TmfXmlOutputEntryCu compile(AnalysisCompilationData compilationData, Element entryEl) {
// Get the path in the state system
String path = entryEl.getAttribute(TmfXmlStrings.PATH);
if (path.isEmpty()) {
path = TmfXmlStrings.WILDCARD;
}
/*
* Make sure the XML element has either a display attribute or entries,
* otherwise issue a warning
*/
List<Element> displayElements = TmfXmlUtils.getChildElements(entryEl, TmfXmlStrings.DISPLAY_ELEMENT);
List<Element> entryElements = TmfXmlUtils.getChildElements(entryEl, TmfXmlStrings.ENTRY_ELEMENT);
if (displayElements.isEmpty() && entryElements.isEmpty()) {
// TODO: Validation message here
Activator.logWarning(String.format("XML view: entry for %s should have either a display element or entry elements", path)); //$NON-NLS-1$
return null;
}
// Compile children entries
List<TmfXmlOutputEntryCu> childrenCu = new ArrayList<>();
for (Element childEl : entryElements) {
TmfXmlOutputEntryCu childCu = compile(compilationData, childEl);
if (childCu != null) {
childrenCu.add(childCu);
}
}
// Compile the entry's specific data
// The display element
TmfXmlStateSystemPathCu displayCu = null;
if (!displayElements.isEmpty()) {
if (displayElements.size() > 1) {
Activator.logWarning(String.format("XML view: entry for %s should have at most one 'display' element", path)); //$NON-NLS-1$
}
displayCu = TmfXmlStateSystemPathCu.compile(compilationData, Collections.singletonList(displayElements.get(0)));
}
// The id element
TmfXmlStateSystemPathCu idCu = null;
List<Element> elements = TmfXmlUtils.getChildElements(entryEl, TmfXmlStrings.ID_ELEMENT);
if (!elements.isEmpty()) {
if (elements.size() > 1) {
Activator.logWarning(String.format("XML view: entry for %s should have at most one 'id' element", path)); //$NON-NLS-1$
}
idCu = TmfXmlStateSystemPathCu.compile(compilationData, Collections.singletonList(elements.get(0)));
}
// The parent element
TmfXmlStateSystemPathCu parentCu = null;
elements = TmfXmlUtils.getChildElements(entryEl, TmfXmlStrings.PARENT_ELEMENT);
if (!elements.isEmpty()) {
if (elements.size() > 1) {
Activator.logWarning(String.format("XML view: entry for %s should have at most one 'parent' element", path)); //$NON-NLS-1$
}
parentCu = TmfXmlStateSystemPathCu.compile(compilationData, Collections.singletonList(elements.get(0)));
}
// The name element
TmfXmlStateSystemPathCu nameCu = null;
elements = TmfXmlUtils.getChildElements(entryEl, TmfXmlStrings.NAME_ELEMENT);
if (!elements.isEmpty()) {
if (elements.size() > 1) {
Activator.logWarning(String.format("XML view: entry for %s should have at most one 'name' element", path)); //$NON-NLS-1$
}
nameCu = TmfXmlStateSystemPathCu.compile(compilationData, Collections.singletonList(elements.get(0)));
}
// Get the state system to use to populate those entries, by default, it
// is the same as the parent
String analysisId = entryEl.getAttribute(TmfXmlStrings.ANALYSIS_ID);
if (analysisId.isEmpty()) {
analysisId = null;
}
// Get whether to display the text, applies to time graphs
boolean displayText = Boolean.parseBoolean(entryEl.getAttribute(TmfXmlStrings.DISPLAY_TEXT));
// Get the type of display, applies to XY entries
String displayTypeStr = entryEl.getAttribute(TmfXmlStrings.DISPLAY_TYPE);
DisplayType displayType = DisplayType.ABSOLUTE;
if (displayTypeStr.equalsIgnoreCase(TmfXmlStrings.DISPLAY_TYPE_DELTA)) {
displayType = DisplayType.DELTA;
}
return new TmfXmlOutputEntryCu(childrenCu, path, analysisId, displayText, displayCu, idCu, parentCu, nameCu, displayType);
}
}