tmf : Introduce the modules for the XML pattern analysis
authorJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Tue, 1 Mar 2016 19:38:03 +0000 (14:38 -0500)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Thu, 17 Mar 2016 15:17:24 +0000 (11:17 -0400)
This patch introduces the XmlPatternAnalysis and its sub-modules

Change-Id: If27ed6816316752c405f14a31b9b91dcfad877c7
Signed-off-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/65750
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Hudson CI
12 files changed:
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/AbstractSegmentStoreAnalysisModule.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/Messages.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternAnalysis.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateSystemModule.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/messages.properties [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/model/TmfXmlPatternSegmentBuilder.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/TmfAnalysisModuleHelperXml.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/XmlAnalysisModuleSource.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/tmf/analysis/xml/core/module/XmlUtils.java

index ece3c75d89ae3cc314617a344ef4fd5a752e80d5..5426b07077ffafd05d124f4af10263202079ce97 100644 (file)
@@ -151,9 +151,7 @@ public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnal
                         }
                     }
                     fSegmentStore = store;
-                    for (IAnalysisProgressListener listener : getListeners()) {
-                        listener.onComplete(this, store);
-                    }
+                    sendUpdate(store);
                     return true;
                 } catch (IOException | ClassNotFoundException | ClassCastException e) {
                     /*
@@ -190,10 +188,20 @@ public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnal
             }
         }
 
-        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
index a24da4c8da0ca045b2f26a0ebfe73abe367a452d..9cdefedc662a0e52ed23c4d3f46cb92f8983ee4a 100644 (file)
@@ -11,7 +11,8 @@ Bundle-ActivationPolicy: lazy
 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,
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/Messages.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/Messages.java
new file mode 100644 (file)
index 0000000..c86331f
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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() {
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternAnalysis.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternAnalysis.java
new file mode 100644 (file)
index 0000000..85c580a
--- /dev/null
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * 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;
+        }
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java
new file mode 100644 (file)
index 0000000..97037ac
--- /dev/null
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * 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;
+        }
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java
new file mode 100644 (file)
index 0000000..d87a09a
--- /dev/null
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * 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();
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateSystemModule.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateSystemModule.java
new file mode 100644 (file)
index 0000000..4facff2
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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;
+    }
+
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/messages.properties b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/messages.properties
new file mode 100644 (file)
index 0000000..3de3225
--- /dev/null
@@ -0,0 +1,12 @@
+###############################################################################
+# 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
index ba651fb1eaa1dd0f943a088b163ad699d1d9ce8c..6c445cadf66511fbfcc2d5df3ddeaab0d1efb6dd 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Map;
 
 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;
@@ -102,7 +103,11 @@ public class TmfXmlPatternSegmentBuilder {
         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;
     }
 
     /**
index 8f88f33837cb52b4ecfe8d48647afd392dda9ab6..bd0b97d7bbc5c1a604388babf156a2cc174edf65 100644 (file)
@@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Path;
 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;
@@ -46,7 +47,14 @@ public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper, ITmfPr
      */
     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;
@@ -182,6 +190,19 @@ public class TmfAnalysisModuleHelperXml implements IAnalysisModuleHelper, ITmfPr
              */
             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;
index c9eb4346a1bceb17e6b53cf10a0934bdae6c5676..e058e1b0be5c261ab8c689ecec91609c6b6bff97 100644 (file)
@@ -108,6 +108,15 @@ public class XmlAnalysisModuleSource implements IAnalysisModuleSource {
                 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$
         }
index 175e9235f6addf3de66af91e192107696feffcdd..601266e7ca3659a5c53bbb96a0b6e324ec8183aa 100644 (file)
@@ -262,6 +262,12 @@ public class XmlUtils {
                 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$
             }
This page took 0.036057 seconds and 5 git commands to generate.