blob: d1081ddb4e21b84b78d1f100c7b56b97b3fafe31 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 É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.incubator.internal.callstack.core.xml.callstack;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.incubator.internal.callstack.core.Activator;
import org.eclipse.tracecompass.tmf.analysis.xml.core.module.TmfAnalysisModuleHelperXml;
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.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.w3c.dom.Element;
import com.google.common.collect.Multimap;
/**
* An XML module helper for the callstack modules. It overrides some methods to
* use the trace type that applies as well as labels from the module that
* creates the state system.
*
* @author Geneviève Bastien
*/
public class CallstackXmlModuleHelper extends TmfAnalysisModuleHelperXml {
static interface ISubModuleHelper {
public Collection<IAnalysisModuleHelper> getHelpers();
public @Nullable IAnalysisModule getAnalysis(ITmfTrace trace);
}
static class HiddenModuleHelper implements ISubModuleHelper {
private final IAnalysisModuleHelper fHelper;
public HiddenModuleHelper(IAnalysisModuleHelper helper) {
fHelper = helper;
}
@Override
public Collection<IAnalysisModuleHelper> getHelpers() {
return Collections.singleton(fHelper);
}
@Override
public @Nullable IAnalysisModule getAnalysis(@NonNull ITmfTrace trace) {
try {
return fHelper.newModule(trace);
} catch (TmfAnalysisException e) {
Activator.getInstance().logError(e.getMessage());
}
return null;
}
}
static class RefModuleHelper implements ISubModuleHelper {
private final String fAnalysisId;
public RefModuleHelper(String id) {
fAnalysisId = id;
}
@Override
public @NonNull Collection<IAnalysisModuleHelper> getHelpers() {
Multimap<String, IAnalysisModuleHelper> analysisModules = TmfAnalysisManager.getAnalysisModules();
Collection<IAnalysisModuleHelper> collection = analysisModules.get(fAnalysisId);
if (collection.isEmpty()) {
Activator.getInstance().logWarning("Callstack XML analysis: no analysis called " + fAnalysisId); //$NON-NLS-1$
}
return collection;
}
@Override
public @Nullable IAnalysisModule getAnalysis(@NonNull ITmfTrace trace) {
return trace.getAnalysisModule(fAnalysisId);
}
}
private final ISubModuleHelper fHelper;
/**
* Constructor
*
* @param xmlFile
* The XML file this element comes from
* @param node
* The XML element for this callstack
*/
public CallstackXmlModuleHelper(File xmlFile, Element node) {
super(xmlFile, node, XmlAnalysisModuleType.OTHER);
/* Create the helper for the underlying module or set its analysis ID */
List<@NonNull Element> childElements = TmfXmlUtils.getChildElements(node, TmfXmlStrings.PATTERN);
if (!childElements.isEmpty()) {
// Create a helper for this module
fHelper = new HiddenModuleHelper(new TmfAnalysisModuleHelperXml(xmlFile, childElements.get(0), XmlAnalysisModuleType.PATTERN));
return;
}
childElements = TmfXmlUtils.getChildElements(node, TmfXmlStrings.STATE_PROVIDER);
if (!childElements.isEmpty()) {
// Create a helper for this module
fHelper = new HiddenModuleHelper(new TmfAnalysisModuleHelperXml(xmlFile, childElements.get(0), XmlAnalysisModuleType.STATE_SYSTEM));
return;
}
childElements = TmfXmlUtils.getChildElements(node, TmfXmlStrings.ANALYSIS);
if (childElements.isEmpty()) {
throw new IllegalStateException("XML callstack element: there should be one of {pattern, stateProvider, analysis}. none found"); //$NON-NLS-1$
}
// Create a helper for this module
fHelper = new RefModuleHelper(String.valueOf(childElements.get(0).getAttribute(TmfXmlStrings.ID)));
return;
}
@Override
protected IAnalysisModule createOtherModule(@NonNull String analysisid, @NonNull String name) {
IAnalysisModule module = new CallstackXmlAnalysis(getSourceFile(), fHelper);
module.setId(analysisid);
module.setName(name);
return module;
}
@Override
public String getName() {
return fHelper.getHelpers().stream()
.map(h -> h.getName())
.findFirst()
.get();
}
@Override
@NonNullByDefault({})
public boolean appliesToTraceType(Class<? extends ITmfTrace> traceClass) {
List<IAnalysisModuleHelper> collect = fHelper.getHelpers().stream()
.filter(h -> h.appliesToTraceType(traceClass))
.collect(Collectors.toList());
return !collect.isEmpty();
}
}