blob: 0be93bb7bff3c43f95a1ed7f2da37978e8784899 [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.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.DataDrivenMappingGroup;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.fsm.module.pattern.DataDrivenPattern;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.ISegmentListener;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlStrings;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfXmlUtils;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.w3c.dom.Element;
/**
* Compilation unit for pattern analyses
*
* @author Geneviève Bastien
*/
public class TmfXmlPatternCu {
private final String fProviderId;
private final int fVersion;
private final List<TmfXmlMappingGroupCu> fMappingGroups;
private final TmfXmlPatternEventHandlerCu fHandlerCu;
/** Map for stored values */
private final Map<String, String> fStoredFields;
private TmfXmlPatternCu(String providerId, int version, List<TmfXmlMappingGroupCu> mapGroups, TmfXmlPatternEventHandlerCu handlerCu, Map<String, String> storedFields) {
fProviderId = providerId;
fVersion = version;
fMappingGroups = mapGroups;
fHandlerCu = handlerCu;
fStoredFields = storedFields;
}
/**
* Generate a pattern from this compilation unit
*
* @param trace
* The trace for which to generate the state provider
* @param listener
* The segment listener
* @return The data driven pattern
*/
public DataDrivenPattern generate(ITmfTrace trace, ISegmentListener listener) {
List<DataDrivenMappingGroup> mappingGroups = fMappingGroups.stream()
.map(TmfXmlMappingGroupCu::generate)
.collect(Collectors.toList());
return new DataDrivenPattern(trace, fProviderId, fVersion, fHandlerCu.generate(), mappingGroups, listener, fStoredFields);
}
/**
* Compile a state provider from an XML file
*
* @param file
* The path to the XML file
* @param providerId
* The ID of the provider to build
* @return The compilation unit corresponding to this state provider
*/
public static @Nullable TmfXmlPatternCu compile(Path file, String providerId) {
Element spEl = TmfXmlUtils.getElementInFile(file.toAbsolutePath().toString(), TmfXmlStrings.PATTERN, providerId);
if (spEl == null) {
// TODO: Validation message here
Activator.logError("XML pattern: Cannot find pattern element in file " + file); //$NON-NLS-1$
return null;
}
return compile(spEl, providerId);
}
/**
* Compile a state provider from an XML element
*
* @param patternEl
* The pattern element
* @return The compilation unit corresponding to this state provider
*/
public static @Nullable TmfXmlPatternCu compile(Element patternEl) {
String id = patternEl.getAttribute(TmfXmlStrings.ID);
if (id.isEmpty()) {
// TODO: Validation message here
Activator.logError("XML pattern: The pattern must have an 'id' attribute"); //$NON-NLS-1$
return null;
}
return compile(patternEl, id);
}
/**
* Compile a state provider from an XML element
*
* @param patternEl
* The pattern element
* @param providerId
* The ID of the provider to build
* @return The compilation unit corresponding to this state provider
*/
private static @Nullable TmfXmlPatternCu compile(Element patternEl, String providerId) {
AnalysisCompilationData analysisData = new AnalysisCompilationData();
int version;
try {
version = Integer.parseInt(patternEl.getAttribute(TmfXmlStrings.VERSION));
} catch (NumberFormatException e) {
// TODO: Validation message here
Activator.logError("XML pattern: The version is not a parseable integer"); //$NON-NLS-1$
return null;
}
/* parser for defined Values */
List<Element> childElements = TmfXmlUtils.getChildElements(patternEl, TmfXmlStrings.DEFINED_VALUE);
for (Element element : childElements) {
analysisData.addDefinedValue(element.getAttribute(TmfXmlStrings.NAME), element.getAttribute(TmfXmlStrings.VALUE));
}
/* parser for defined Fields */
childElements = TmfXmlUtils.getChildElements(patternEl, TmfXmlStrings.STORED_FIELDS);
Map<String, String> storedFields = new HashMap<>();
for (Element element : childElements) {
String key = element.getAttribute(TmfXmlStrings.ALIAS);
String id = element.getAttribute(TmfXmlStrings.ID);
storedFields.put(id, key.isEmpty() ? id : key);
}
/* parser for the locations */
childElements = TmfXmlUtils.getChildElements(patternEl, TmfXmlStrings.LOCATION);
for (Element element : childElements) {
TmfXmlLocationCu.compile(analysisData, element);
}
/* parser for the mapping groups */
List<TmfXmlMappingGroupCu> mapGroups = new ArrayList<>();
childElements = TmfXmlUtils.getChildElements(patternEl, TmfXmlStrings.MAPPING_GROUP);
for (Element map : childElements) {
TmfXmlMappingGroupCu compile = TmfXmlMappingGroupCu.compile(analysisData, map);
if (compile == null) {
return null;
}
mapGroups.add(compile);
}
/* parser for the event handlers */
childElements = TmfXmlUtils.getChildElements(patternEl, TmfXmlStrings.PATTERN_HANDLER);
if (childElements.size() != 1) {
// TODO: Validation message here
Activator.logError("XML pattern: Only one pattern handler should be present"); //$NON-NLS-1$
return null;
}
TmfXmlPatternEventHandlerCu handlerCu = TmfXmlPatternEventHandlerCu.compile(analysisData, childElements.get(0));
if (handlerCu == null) {
return null;
}
return new TmfXmlPatternCu(providerId, version, mapGroups, handlerCu, storedFields);
}
}