}
}
fSegmentStore = store;
- for (IAnalysisProgressListener listener : getListeners()) {
- listener.onComplete(this, store);
- }
+ sendUpdate(store);
return true;
} catch (IOException | ClassNotFoundException | ClassCastException e) {
/*
}
}
- for (IAnalysisProgressListener listener : getListeners()) {
- listener.onComplete(this, segmentStore);
- }
+ sendUpdate(segmentStore);
return true;
}
+
+ /**
+ * Send the segment store to all its listener
+ *
+ * @param store
+ * The segment store to broadcast
+ */
+ protected void sendUpdate(final ISegmentStore<ISegment> store) {
+ for (IAnalysisProgressListener listener : getListeners()) {
+ listener.onComplete(this, store);
+ }
+ }
}
\ No newline at end of file
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.tracecompass.common.core,
org.eclipse.tracecompass.tmf.core,
- org.eclipse.tracecompass.segmentstore.core
+ org.eclipse.tracecompass.segmentstore.core,
+ org.eclipse.tracecompass.analysis.timing.core
Export-Package: org.eclipse.tracecompass.internal.tmf.analysis.xml.core;x-friends:="org.eclipse.tracecompass.tmf.analysis.xml.core.tests",
org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;x-internal:=true,
org.eclipse.tracecompass.tmf.analysis.xml.core.model,
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Externalized messages for the XML analysis state provider package
+ *
+ * @author Jean-Christian Kouame
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.messages"; //$NON-NLS-1$
+ /**
+ * The string content
+ */
+ public static String PatternSegmentContentAspect_Content;
+ /**
+ * Help text of the segment content aspect
+ */
+ public static String PatternSegmentContentAspect_HelpText;
+ /**
+ * Help text of the segment name aspect
+ */
+ public static String PatternSegmentNameAspect_HelpText;
+ /**
+ * The string name
+ */
+ public static String PatternSegmentNameAspect_Name;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ ******************************************************************************/
+package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.File;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlPatternSegmentBuilder;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.segment.TmfXmlPatternSegment;
+import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
+import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Analysis module for pattern matching within traces. This module creates two
+ * sub-analyses : A state system analysis that will execute the pattern on the
+ * trace and a segment store analysis that will build a segment store with the
+ * segments generated by the state system analysis.
+ *
+ * @author Jean-Christian Kouame
+ */
+public class XmlPatternAnalysis extends TmfAbstractAnalysisModule implements ITmfAnalysisModuleWithStateSystems, ISegmentStoreProvider {
+
+ /**
+ * Segment store supplementary file extension
+ */
+ public static final @NonNull String SEGMENT_STORE_EXTENSION = ".dat"; //$NON-NLS-1$
+ /**
+ * state system supplementary file extension
+ */
+ private static final @NonNull String STATE_SYSTEM_EXTENSION = ".ht"; //$NON-NLS-1$
+ private static final String SEGMENT_STORE_SUFFIX = " segment store"; //$NON-NLS-1$
+ private static final String STATE_SYSTEM_SUFFIX = " state system"; //$NON-NLS-1$
+ private final CountDownLatch fInitialized = new CountDownLatch(1);
+ private XmlPatternStateSystemModule fStateSystemModule;
+ private XmlPatternSegmentStoreModule fSegmentStoreModule;
+ private boolean fInitializationSucceeded;
+
+ /**
+ * Constructor
+ */
+ public XmlPatternAnalysis() {
+ super();
+ fSegmentStoreModule = new XmlPatternSegmentStoreModule(this);
+ fStateSystemModule = new XmlPatternStateSystemModule(fSegmentStoreModule);
+ }
+
+ @Override
+ public @Nullable ISegmentStore<@NonNull ISegment> getSegmentStore() {
+ return fSegmentStoreModule.getSegmentStore();
+ }
+
+ @Override
+ public @Nullable ITmfStateSystem getStateSystem(@NonNull String id) {
+ return fStateSystemModule.getStateSystem(id);
+ }
+
+ @Override
+ public @NonNull Iterable<@NonNull ITmfStateSystem> getStateSystems() {
+ return fStateSystemModule.getStateSystems();
+ }
+
+ @Override
+ public boolean waitForInitialization() {
+ try {
+ fInitialized.await();
+ } catch (InterruptedException e) {
+ return false;
+ }
+ return fInitializationSucceeded;
+ }
+
+ @Override
+ protected boolean executeAnalysis(@NonNull IProgressMonitor monitor) throws TmfAnalysisException {
+ ITmfTrace trace = getTrace();
+ if (trace == null) {
+ /* This analysis was cancelled in the meantime */
+ analysisReady(false);
+ return false;
+ }
+
+ File segmentStoreFile = getSupplementaryFile(getSegmentStoreFileName());
+ File stateSystemFile = getSupplementaryFile(getStateSystemFileName());
+ if (segmentStoreFile == null || stateSystemFile == null) {
+ analysisReady(false);
+ return false;
+ }
+
+ if (!segmentStoreFile.exists()) {
+ fStateSystemModule.cancel();
+ stateSystemFile.delete();
+ }
+
+ IStatus segmentStoreStatus = fSegmentStoreModule.schedule();
+ IStatus stateSystemStatus = fStateSystemModule.schedule();
+ if (!(segmentStoreStatus.isOK() && stateSystemStatus.isOK())) {
+ cancelSubAnalyses();
+ analysisReady(false);
+ return false;
+ }
+
+ /* Wait until the state system module is initialized */
+ if (!fStateSystemModule.waitForInitialization()) {
+ analysisReady(false);
+ cancelSubAnalyses();
+ return false;
+ }
+
+ ITmfStateSystem stateSystem = fStateSystemModule.getStateSystem();
+ if (stateSystem == null) {
+ analysisReady(false);
+ throw new IllegalStateException("Initialization of the state system module succeeded but the statesystem is null"); //$NON-NLS-1$
+ }
+
+ analysisReady(true);
+
+ return fStateSystemModule.waitForCompletion(monitor) && fSegmentStoreModule.waitForCompletion(monitor);
+ }
+
+ @Override
+ protected void canceling() {
+ cancelSubAnalyses();
+ }
+
+ private void cancelSubAnalyses() {
+ fStateSystemModule.cancel();
+ fSegmentStoreModule.cancel();
+ }
+
+ @Override
+ public void dispose() {
+ /*
+ * The sub-analyses are not registered to the trace directly, so we need
+ * to tell them when the trace is disposed.
+ */
+ super.dispose();
+ fStateSystemModule.dispose();
+ fSegmentStoreModule.dispose();
+ }
+
+ @Override
+ public void setId(@NonNull String id) {
+ super.setId(id);
+ fStateSystemModule.setId(id);
+ fSegmentStoreModule.setId(id);
+ }
+
+ @Override
+ public void setName(@NonNull String name) {
+ super.setName(name);
+ fStateSystemModule.setName(name + STATE_SYSTEM_SUFFIX);
+ fSegmentStoreModule.setName(name + SEGMENT_STORE_SUFFIX);
+ }
+
+ @Override
+ public boolean setTrace(ITmfTrace trace) throws TmfAnalysisException {
+ if (!super.setTrace(trace)) {
+ return false;
+ }
+
+ /*
+ * Since these sub-analyzes are not built from an extension point, we
+ * have to assign the trace ourselves. Very important to do so before
+ * calling schedule()!
+ */
+ return fSegmentStoreModule.setTrace(trace) && fStateSystemModule.setTrace(trace);
+ }
+
+ /**
+ * Sets the file path of the XML file and the id of pattern analysis in the
+ * file
+ *
+ * @param file
+ * The full path to the XML file
+ */
+ public void setXmlFile(IPath file) {
+ fStateSystemModule.setXmlFile(file);
+ }
+
+ /**
+ * Make the module available and set whether the initialization succeeded or
+ * not. If not, no state system is available and
+ * {@link #waitForInitialization()} should return false.
+ *
+ * @param success
+ * True if the initialization went well, false otherwise
+ */
+ private void analysisReady(boolean succeeded) {
+ fInitializationSucceeded = succeeded;
+ fInitialized.countDown();
+ }
+
+ private @Nullable File getSupplementaryFile(String filename) {
+ ITmfTrace trace = getTrace();
+ if (trace == null) {
+ return null;
+ }
+ String directory = TmfTraceManager.getSupplementaryFileDir(trace);
+ File file = new File(directory + filename);
+ return file;
+ }
+
+ private String getStateSystemFileName() {
+ return fStateSystemModule.getId() + STATE_SYSTEM_EXTENSION;
+ }
+
+ private String getSegmentStoreFileName() {
+ return fSegmentStoreModule.getId() + SEGMENT_STORE_EXTENSION;
+ }
+
+ @Override
+ public void addListener(@NonNull IAnalysisProgressListener listener) {
+ fSegmentStoreModule.addListener(listener);
+ }
+
+ @Override
+ public void removeListener(@NonNull IAnalysisProgressListener listener) {
+ fSegmentStoreModule.removeListener(listener);
+ }
+
+ @Override
+ public Iterable<ISegmentAspect> getSegmentAspects() {
+ return ImmutableList.of(PatternSegmentNameAspect.INSTANCE, PatternSegmentContentAspect.INSTANCE);
+ }
+
+ private static class PatternSegmentNameAspect implements ISegmentAspect {
+ public static final @NonNull ISegmentAspect INSTANCE = new PatternSegmentNameAspect();
+
+ private PatternSegmentNameAspect() {}
+
+ @Override
+ public String getHelpText() {
+ return checkNotNull(Messages.PatternSegmentNameAspect_HelpText);
+ }
+ @Override
+ public String getName() {
+ return checkNotNull(Messages.PatternSegmentNameAspect_Name);
+ }
+ @Override
+ public @Nullable Comparator<?> getComparator() {
+ return null;
+ }
+ @Override
+ public @Nullable String resolve(ISegment segment) {
+ if (segment instanceof TmfXmlPatternSegment) {
+ return ((TmfXmlPatternSegment) segment).getName()
+ .substring(TmfXmlPatternSegmentBuilder.PATTERN_SEGMENT_NAME_PREFIX.length());
+ }
+ return EMPTY_STRING;
+ }
+ }
+
+ private static class PatternSegmentContentAspect implements ISegmentAspect {
+ public static final @NonNull ISegmentAspect INSTANCE = new PatternSegmentContentAspect();
+
+ private PatternSegmentContentAspect() {}
+
+ @Override
+ public String getHelpText() {
+ return checkNotNull(Messages.PatternSegmentContentAspect_HelpText);
+ }
+ @Override
+ public String getName() {
+ return checkNotNull(Messages.PatternSegmentContentAspect_Content);
+ }
+ @Override
+ public @Nullable Comparator<?> getComparator() {
+ return null;
+ }
+ @Override
+ public @Nullable String resolve(ISegment segment) {
+ if (segment instanceof TmfXmlPatternSegment) {
+ List<String> values = ((TmfXmlPatternSegment) segment).getContent().entrySet().stream().map(c -> c.getKey() + '=' + c.getValue()).collect(Collectors.toList());
+ return String.join(", ", values); //$NON-NLS-1$
+ }
+ return EMPTY_STRING;
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ ******************************************************************************/
+package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.concurrent.CountDownLatch;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+
+/**
+ * Segment store module for pattern analysis defined in XML. This module will
+ * receive all the segments provided by an external source and will build a
+ * segment store
+ *
+ * @author Jean-Christian Kouame
+ */
+public class XmlPatternSegmentStoreModule extends AbstractSegmentStoreAnalysisModule implements ISegmentListener {
+
+ /**
+ * Fake segment indicated that the last segment have been received
+ */
+ public static final @NonNull EndSegment END_SEGMENT = new EndSegment();
+ private final ISegmentStore<@NonNull ISegment> fSegments = new TreeMapStore<>();
+ private final CountDownLatch fFinished = new CountDownLatch(1);
+ private final @NonNull XmlPatternAnalysis fParent;
+ private boolean fSegmentStoreCompleted;
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * The parent analysis
+ */
+ public XmlPatternSegmentStoreModule(@NonNull XmlPatternAnalysis parent) {
+ super();
+ fParent = parent;
+ }
+
+ @Override
+ protected Object @NonNull [] readObject(@NonNull ObjectInputStream ois) throws ClassNotFoundException, IOException {
+ return checkNotNull((Object[]) ois.readObject());
+ }
+
+ @Override
+ protected boolean buildAnalysisSegments(@NonNull ISegmentStore<@NonNull ISegment> segments, @NonNull IProgressMonitor monitor) throws TmfAnalysisException {
+ final @Nullable ITmfTrace trace = getTrace();
+ if (trace == null) {
+ /* This analysis was cancelled in the meantime */
+ segmentStoreReady(false);
+ return false;
+ }
+ waitForSegmentStoreCompletion();
+ segments.addAll(getSegments());
+ return true;
+ }
+
+ @Override
+ protected void canceling() {
+ super.cancel();
+ segmentStoreReady(false);
+ }
+
+ @Override
+ protected @Nullable String getDataFileName() {
+ return getId() + XmlPatternAnalysis.SEGMENT_STORE_EXTENSION;
+ }
+
+ /**
+ * Broadcast the segment store to its listeners. Since this analysis is not
+ * directly register to the trace, the parent analysis is used as the source.
+ *
+ * @param store
+ * The store to broadcast
+ */
+ @Override
+ protected void sendUpdate(final ISegmentStore<@NonNull ISegment> store) {
+ for (IAnalysisProgressListener listener : getListeners()) {
+ listener.onComplete(fParent, store);
+ }
+ }
+
+ @Override
+ public void onNewSegment(@NonNull ISegment segment) {
+ // We can accept segments until the first END_SEGMENT arrives. Nothing
+ // should be accept after it. This prevents to receive new segments if
+ // the analysis that generates the segments is rescheduled
+ if (!fSegmentStoreCompleted) {
+ if (segment == END_SEGMENT) {
+ segmentStoreReady(true);
+ return;
+ }
+ getSegments().add(segment);
+ }
+ }
+
+ /**
+ * Get the internal segment store of this module
+ *
+ * @return The segment store
+ */
+ private synchronized ISegmentStore<@NonNull ISegment> getSegments() {
+ return fSegments;
+ }
+
+ /**
+ * Wait until internal segment store of the module is fully filled. If all
+ * the segments have been received, the completion succeeded, otherwise it
+ * is not.
+ *
+ * @return True if the completion succeeded, false otherwise
+ */
+ public boolean waitForSegmentStoreCompletion() {
+ try {
+ fFinished.await();
+ } catch (InterruptedException e) {
+ return false;
+ }
+ return fSegmentStoreCompleted;
+ }
+
+ /**
+ * Make the module available and set whether the segment store completion
+ * succeeded or not. If not, no segment store is available and
+ * {@link #waitForSegmentStoreCompletion()} should return false.
+ *
+ * @param success
+ * True if the segment store completion succeeded, false
+ * otherwise
+ */
+ private void segmentStoreReady(boolean succeeded) {
+ fSegmentStoreCompleted = succeeded;
+ fFinished.countDown();
+ }
+
+ /**
+ * Fake segment indicating the build is over, and the segment store is fully
+ * filled
+ */
+ public static class EndSegment implements ISegment {
+ /**
+ * The serial version UID
+ */
+ private static final long serialVersionUID = 7834984029618274707L;
+
+ @Override
+ public long getStart() {
+ return Long.MIN_VALUE;
+ }
+
+ @Override
+ public long getEnd() {
+ return Long.MIN_VALUE;
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ ******************************************************************************/
+package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlLocation;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
+import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
+import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.w3c.dom.Element;
+
+/**
+ * State provider for the pattern analysis
+ *
+ * @author Jean-Christian Kouame
+ */
+public class XmlPatternStateProvider extends AbstractTmfStateProvider implements IXmlStateSystemContainer {
+
+ private final IPath fFilePath;
+
+ private final @NonNull String fStateId;
+
+ /** List of all Locations */
+ private final @NonNull Set<@NonNull TmfXmlLocation> fLocations;
+
+ private final ISegmentListener fListener;
+
+ /**
+ * @param trace
+ * The active trace
+ * @param stateid
+ * The state id, which corresponds to the id of the analysis
+ * defined in the XML file
+ * @param file
+ * The XML file
+ * @param listener
+ * Listener for segment creation
+ */
+ public XmlPatternStateProvider(@NonNull ITmfTrace trace, @NonNull String stateid, @Nullable IPath file, ISegmentListener listener) {
+ super(trace, stateid);
+ fStateId = stateid;
+ fFilePath = file;
+ fListener = listener;
+ final String pathString = fFilePath.makeAbsolute().toOSString();
+ Element doc = XmlUtils.getElementInFile(pathString, TmfXmlStrings.PATTERN, fStateId);
+ fLocations = new HashSet<>();
+ if (doc == null) {
+ Activator.logError("Failed to find a pattern in " + pathString); //$NON-NLS-1$
+ return;
+ }
+ }
+
+ @Override
+ public String getAttributeValue(String name) {
+ return null;
+ }
+
+ @Override
+ public int getVersion() {
+ return 0;
+ }
+
+ @Override
+ public @NonNull ITmfStateProvider getNewInstance() {
+ return new XmlPatternStateProvider(getTrace(), getStateId(), fFilePath, fListener);
+ }
+
+ /**
+ * Get the state ID of the provider. It corresponds to the analysis ID.
+ *
+ * @return the state Id
+ */
+ public @NonNull String getStateId() {
+ return fStateId;
+ }
+
+ @Override
+ public ITmfStateSystem getStateSystem() {
+ return getStateSystemBuilder();
+ }
+
+ @Override
+ public @NonNull Iterable<@NonNull TmfXmlLocation> getLocations() {
+ return fLocations;
+ }
+
+ @Override
+ protected void eventHandle(@NonNull ITmfEvent event) {
+ }
+
+ /**
+ * Get the listerner for segments creation
+ *
+ * @return The segment listener
+ */
+ public ISegmentListener getListener() {
+ return fListener;
+ }
+
+ @Override
+ public void dispose() {
+ fListener.onNewSegment(XmlPatternSegmentStoreModule.END_SEGMENT);
+ super.dispose();
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ ******************************************************************************/
+package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
+import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
+
+/**
+ * State system analysis for pattern matching analysis described in XML. This
+ * module will parse the XML description of the analyses and execute it against
+ * the trace and will execute all required action
+ *
+ * @author Jean-Christian Kouame
+ */
+public class XmlPatternStateSystemModule extends TmfStateSystemAnalysisModule {
+
+ private @Nullable IPath fXmlFile;
+ private final ISegmentListener fListener;
+
+ /**
+ * Constructor
+ *
+ * @param listener
+ * Listener for segments that will be created
+ */
+ public XmlPatternStateSystemModule(ISegmentListener listener) {
+ super();
+ fListener = listener;
+ }
+
+ @Override
+ protected @NonNull ITmfStateProvider createStateProvider() {
+ String id = getId();
+ return new XmlPatternStateProvider(checkNotNull(getTrace()), id, fXmlFile, fListener);
+ }
+
+ /**
+ * Sets the file path of the XML file containing the state provider
+ *
+ * @param file
+ * The full path to the XML file
+ */
+ public void setXmlFile(IPath file) {
+ fXmlFile = file;
+ }
+
+}
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 Ericsson
+#
+# 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
+###############################################################################
+PatternSegmentContentAspect_Content=Content
+PatternSegmentContentAspect_HelpText=The content of the segment
+PatternSegmentNameAspect_HelpText=The name of the segment
+PatternSegmentNameAspect_Name=Name
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.pattern.stateprovider.XmlPatternStateProvider;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
String segmentName = getPatternSegmentName(event);
Map<String, ITmfStateValue> fields = new HashMap<>();
setPatternSegmentContent(event, start, end, fields);
- return new TmfXmlPatternSegment(startValue, endValue, scale, segmentName, fields);
+ TmfXmlPatternSegment segment = new TmfXmlPatternSegment(startValue, endValue, scale, segmentName, fields);
+ if (fContainer instanceof XmlPatternStateProvider) {
+ ((XmlPatternStateProvider) fContainer).getListener().onNewSegment(segment);
+ }
+ return segment;
}
/**
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.XmlPatternAnalysis;
import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.XmlStateSystemModule;
import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
*/
public enum XmlAnalysisModuleType {
/** Analysis will be of type XmlStateSystemModule */
- STATE_SYSTEM
+ STATE_SYSTEM,
+
+ /**
+ * Analysis will be of type XmlPatternAnalysisModule
+ *
+ * @since 2.0
+ */
+ PATTERN
}
private final File fSourceFile;
*/
ssModule.setAutomatic(true);
+ break;
+ case PATTERN:
+ module = new XmlPatternAnalysis();
+ module.setName(getName());
+ module.setId(analysisid);
+ XmlPatternAnalysis paModule = (XmlPatternAnalysis) module;
+ paModule.setXmlFile(new Path(fSourceFile.getAbsolutePath()));
+
+ /*
+ * FIXME: Maybe the pattern analysis should not be automatic.
+ */
+ paModule.setAutomatic(true);
+
break;
default:
break;
IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.STATE_SYSTEM);
fModules.add(helper);
}
+
+ /* get pattern modules */
+ NodeList patternNodes = doc.getElementsByTagName(TmfXmlStrings.PATTERN);
+ for (int i = 0; i < patternNodes.getLength(); i++) {
+ Element node = (Element) patternNodes.item(i);
+
+ IAnalysisModuleHelper helper = new TmfAnalysisModuleHelperXml(xmlFile, node, XmlAnalysisModuleType.PATTERN);
+ fModules.add(helper);
+ }
} catch (ParserConfigurationException | SAXException | IOException e) {
Activator.logError("Error opening XML file", e); //$NON-NLS-1$
}
for (int i = 0; i < stateproviderNodes.getLength(); i++) {
ids.add(nullToEmptyString(((Element) stateproviderNodes.item(i)).getAttribute(TmfXmlStrings.ID)));
}
+
+ /* get patterns modules */
+ NodeList patternNodes = doc.getElementsByTagName(TmfXmlStrings.PATTERN);
+ for (int i = 0; i < patternNodes.getLength(); i++) {
+ ids.add(nullToEmptyString(((Element) patternNodes.item(i)).getAttribute(TmfXmlStrings.ID)));
+ }
} catch (ParserConfigurationException | SAXException | IOException e) {
Activator.logError("Failed to get analyses IDs from " + fileName); //$NON-NLS-1$
}