TMF: Introduce a framework to hook trace analysis modules/plugins
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Mon, 15 Jul 2013 18:55:41 +0000 (14:55 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Mon, 4 Nov 2013 19:53:27 +0000 (14:53 -0500)
* Add a new extension point to define trace analysis modules.
* Add new interface IAnalysisModule and abstract class
  TmfAbstractAnalysisModule to implement the analysis itself.
* TmfAnalysisManager is the main class to obtain which analysis are available
  to a trace.
* IAnalysisOutput interface describe the different outputs the analysis can
  provide.  Objects of classes implementing this interface can register to an
  analysis module.
* The IAnalysisParameterProvider allows other parts of the system to set an
  analysis' parameters.
* Analysis are executed as Eclipse jobs.
* On the UI side, analysis and their provided outputs (if any) are now children
  of the trace and can be directly opened.
* Unit tests in tmf.core and tmf.ui provide stub analysis.

Change-Id: Ie0d0fa9b726555b6416829c1c49e44301297d11b
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/14935
Tested-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
IP-Clean: Patrick Tasse <patrick.tasse@gmail.com>

55 files changed:
org.eclipse.linuxtools.tmf.core.tests/build.properties
org.eclipse.linuxtools.tmf.core.tests/plugin.xml [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestCtfAnalysis.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF
org.eclipse.linuxtools.tmf.core/build.properties
org.eclipse.linuxtools.tmf.core/plugin.xml
org.eclipse.linuxtools.tmf.core/schema/org.eclipse.linuxtools.tmf.core.analysis.exsd [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisType.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperCE.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java
org.eclipse.linuxtools.tmf.ui.tests/plugin.xml
org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/AllTests.java
org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelTestData.java
org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelTraceTest.java
org.eclipse.linuxtools.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF
org.eclipse.linuxtools.tmf.ui/plugin.properties
org.eclipse.linuxtools.tmf.ui/plugin.xml
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAction.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/Messages.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfExperimentElement.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorContentProvider.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfNavigatorLabelProvider.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfTraceElement.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TraceTypeHelper.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/messages.properties

index 30e33a7a354eaaab6c93a8296ec64fd54d29a8f3..5abbb1ff8fb75fc6d7fff39d9a93d3f40265fc9d 100644 (file)
@@ -17,5 +17,6 @@ output.. = bin/
 bin.includes = META-INF/,\
                .,\
                plugin.properties,\
-               testfiles/
+               testfiles/,\
+               plugin.xml
 src.includes = about.html
diff --git a/org.eclipse.linuxtools.tmf.core.tests/plugin.xml b/org.eclipse.linuxtools.tmf.core.tests/plugin.xml
new file mode 100644 (file)
index 0000000..d280c63
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.linuxtools.tmf.core.analysis">
+      <module
+         id="org.eclipse.linuxtools.tmf.core.tests.analysis.test"
+         name="Test analysis"
+         analysis_module="org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis">
+         <parameter
+               name="test">
+         </parameter>
+         <tracetype
+               class="org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub">
+         </tracetype>
+      </module>
+      <module
+         id="org.eclipse.linuxtools.tmf.core.tests.analysis.test2"
+         name="Test analysis 2"
+         analysis_module="org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis"
+         automatic="true">
+         <parameter
+               default_value="3"
+               name="test">
+         </parameter>
+         <tracetype
+               class="org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub">
+         </tracetype>
+      </module>
+      <module
+         id="org.eclipse.linuxtools.tmf.core.tests.analysis.testctf"
+         name="Test analysis ctf"
+         analysis_module="org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestCtfAnalysis"
+         automatic="true">
+         <tracetype
+               applies="true"
+               class="org.eclipse.linuxtools.tmf.tests.stubs.ctf.CtfTmfTraceStub">
+         </tracetype>
+      </module>
+   </extension>
+
+</plugin>
index 35b29459505bf10b2e904525b380ab918948c5fe..2e6b9f5c5f4b3fa4c2f08a3b5890fe0225858716 100644 (file)
@@ -22,6 +22,7 @@ import org.junit.runners.Suite;
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
     TmfCorePluginTest.class,
+    org.eclipse.linuxtools.tmf.core.tests.analysis.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.component.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.ctfadaptor.AllTests.class,
     org.eclipse.linuxtools.tmf.core.tests.event.AllTests.class,
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AllTests.java
new file mode 100644 (file)
index 0000000..27d2ff8
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.analysis;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Unit tests for the analysis package.
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+    AnalysisModuleTest.class,
+    AnalysisManagerTest.class,
+    AnalysisParameterProviderTest.class
+})
+public class AllTests {
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisManagerTest.java
new file mode 100644 (file)
index 0000000..4731ed0
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.analysis;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Map;
+
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test suite for the TmfAnalysisModule class
+ */
+public class AnalysisManagerTest {
+
+    /** Id of analysis module with parameter */
+    public static final String MODULE_PARAM = "org.eclipse.linuxtools.tmf.core.tests.analysis.test";
+    /** ID of analysis module with parameter and default value */
+    public static final String MODULE_PARAM_DEFAULT = "org.eclipse.linuxtools.tmf.core.tests.analysis.test2";
+    /** ID of analysis module for CTF traces only */
+    public static final String MODULE_CTF = "org.eclipse.linuxtools.tmf.core.tests.analysis.testctf";
+
+    /**
+     * Some tests use traces, let's clean them here
+     */
+    @After
+    public void cleanupTraces() {
+        TmfTestTrace.A_TEST_10K.dispose();
+        CtfTmfTestTrace.KERNEL.dispose();
+    }
+
+    /**
+     * Test suite for the {@link TmfAnalysisManager#getAnalysisModules()} method
+     */
+    @Test
+    public void testGetAnalysisModules() {
+        Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules();
+        /* At least 3 modules should be found */
+        assertTrue(modules.size() >= 3);
+
+        IAnalysisModuleHelper module = modules.get(MODULE_PARAM_DEFAULT);
+        assertTrue(module.isAutomatic());
+
+        module = modules.get(MODULE_PARAM);
+        assertFalse(module.isAutomatic());
+    }
+
+    /**
+     * Test suite for {@link TmfAnalysisManager#getAnalysisModules(Class)} Use
+     * the test TMF trace and test Ctf trace as sample traces
+     */
+    @Test
+    public void testListForTraces() {
+        /* Generic TmfTrace */
+        ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace();
+        Map<String, IAnalysisModuleHelper> map = TmfAnalysisManager.getAnalysisModules(trace.getClass());
+
+        assertTrue(map.containsKey(MODULE_PARAM));
+        assertTrue(map.containsKey(MODULE_PARAM_DEFAULT));
+        assertFalse(map.containsKey(MODULE_CTF));
+
+        /* Ctf trace */
+        assumeTrue(CtfTmfTestTrace.KERNEL.exists());
+        CtfTmfTrace ctftrace = CtfTmfTestTrace.KERNEL.getTrace();
+
+        map = TmfAnalysisManager.getAnalysisModules(ctftrace.getClass());
+
+        assertFalse(map.containsKey(MODULE_PARAM));
+        assertFalse(map.containsKey(MODULE_PARAM_DEFAULT));
+        assertTrue(map.containsKey(MODULE_CTF));
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleHelperTest.java
new file mode 100644 (file)
index 0000000..625b83c
--- /dev/null
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.analysis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.Messages;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisModuleHelperCE;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis;
+import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestCtfAnalysis;
+import org.eclipse.linuxtools.tmf.tests.stubs.ctf.CtfTmfTraceStub;
+import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub;
+import org.eclipse.osgi.util.NLS;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+/**
+ * Test suite for the {@link TmfAnalysisModuleHelperCE} class
+ *
+ * @author Geneviève Bastien
+ */
+public class AnalysisModuleHelperTest {
+
+    private IAnalysisModuleHelper fModule;
+    private IAnalysisModuleHelper fCtfModule;
+
+    /**
+     * Gets the module helpers for 2 test modules
+     */
+    @Before
+    public void getModules() {
+        fModule = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM);
+        assertNotNull(fModule);
+        assertTrue(fModule instanceof TmfAnalysisModuleHelperCE);
+        fCtfModule = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_CTF);
+        assertNotNull(fCtfModule);
+        assertTrue(fCtfModule instanceof TmfAnalysisModuleHelperCE);
+    }
+
+    /**
+     * Some tests use traces, let's clean them here
+     */
+    @After
+    public void cleanupTraces() {
+        TmfTestTrace.A_TEST_10K.dispose();
+        CtfTmfTestTrace.KERNEL.dispose();
+    }
+
+    /**
+     * Test the helper's getters and setters
+     */
+    @Test
+    public void testHelperGetters() {
+        /* With first module */
+        assertEquals(AnalysisManagerTest.MODULE_PARAM, fModule.getId());
+        assertEquals("Test analysis", fModule.getName());
+        assertFalse(fModule.isAutomatic());
+
+        Bundle helperbundle = fModule.getBundle();
+        Bundle thisbundle = Platform.getBundle("org.eclipse.linuxtools.tmf.core.tests");
+        assertNotNull(helperbundle);
+        assertEquals(thisbundle, helperbundle);
+
+        /* With ctf module */
+        assertEquals(AnalysisManagerTest.MODULE_CTF, fCtfModule.getId());
+        assertEquals("Test analysis ctf", fCtfModule.getName());
+        assertTrue(fCtfModule.isAutomatic());
+    }
+
+    /**
+     * Test the {@link TmfAnalysisModuleHelperCE#appliesToTraceType(Class)}
+     * method for the 2 modules
+     */
+    @Test
+    public void testAppliesToTrace() {
+        /* non-ctf module */
+        assertFalse(fModule.appliesToTraceType(TmfTrace.class));
+        assertTrue(fModule.appliesToTraceType(TmfTraceStub.class));
+        assertFalse(fModule.appliesToTraceType(CtfTmfTraceStub.class));
+
+        /* ctf module */
+        assertFalse(fCtfModule.appliesToTraceType(TmfTrace.class));
+        assertFalse(fCtfModule.appliesToTraceType(TmfTraceStub.class));
+        assertTrue(fCtfModule.appliesToTraceType(CtfTmfTraceStub.class));
+    }
+
+    /**
+     * Test the {@link TmfAnalysisModuleHelperCE#newModule(ITmfTrace)} method
+     * for the 2 modules
+     */
+    @Test
+    public void testNewModule() {
+        /* Test analysis module with traceStub */
+        Exception exception = null;
+        IAnalysisModule module = null;
+        try {
+            module = fModule.newModule(TmfTestTrace.A_TEST_10K.getTrace());
+        } catch (TmfAnalysisException e) {
+            exception = e;
+        }
+        assertNull(exception);
+        assertNotNull(module);
+        assertTrue(module instanceof TestAnalysis);
+
+        /* Test Analysis module with ctf trace, should return an exception */
+        assumeTrue(CtfTmfTestTrace.KERNEL.exists());
+        CtfTmfTraceStub ctfTrace = (CtfTmfTraceStub) CtfTmfTestTrace.KERNEL.getTrace();
+        module = null;
+        try {
+            module = fModule.newModule(ctfTrace);
+        } catch (TmfAnalysisException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+        assertEquals(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, fModule.getName()), exception.getMessage());
+
+        /* Test analysis CTF module with ctf trace stub */
+        exception = null;
+        module = null;
+        try {
+            module = fCtfModule.newModule(ctfTrace);
+        } catch (TmfAnalysisException e) {
+            exception = e;
+        }
+        assertNull(exception);
+        assertNotNull(module);
+        assertTrue(module instanceof TestCtfAnalysis);
+    }
+
+    /**
+     * Test for the initialization of parameters from the extension points
+     */
+    @Test
+    public void testParameters() {
+        assumeTrue(CtfTmfTestTrace.KERNEL.exists());
+        CtfTmfTrace ctftrace = CtfTmfTestTrace.KERNEL.getTrace();
+        ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace();
+
+        /*
+         * This analysis has a parameter, but no default value. we should be
+         * able to set the parameter
+         */
+        IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM);
+        IAnalysisModule module;
+        try {
+            module = helper.newModule(trace);
+        } catch (TmfAnalysisException e1) {
+            fail(e1.getMessage());
+            return;
+        }
+
+        assertNull(module.getParameter(TestAnalysis.PARAM_TEST));
+        module.setParameter(TestAnalysis.PARAM_TEST, 1);
+        assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST));
+
+        /* This module has a parameter with default value */
+        helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM_DEFAULT);
+        try {
+            module = helper.newModule(trace);
+        } catch (TmfAnalysisException e1) {
+            fail(e1.getMessage());
+            return;
+        }
+        assertEquals(3, module.getParameter(TestAnalysis.PARAM_TEST));
+        module.setParameter(TestAnalysis.PARAM_TEST, 1);
+        assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST));
+
+        /*
+         * This module does not have a parameter so setting it should throw an
+         * error
+         */
+        helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_CTF);
+        try {
+            module = helper.newModule(ctftrace);
+        } catch (TmfAnalysisException e1) {
+            fail(e1.getMessage());
+            return;
+        }
+        assertNull(module.getParameter(TestAnalysis.PARAM_TEST));
+        Exception exception = null;
+        try {
+            module.setParameter(TestAnalysis.PARAM_TEST, 1);
+        } catch (RuntimeException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisModuleTest.java
new file mode 100644 (file)
index 0000000..3332d8f
--- /dev/null
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.analysis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.analysis.Messages;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis;
+import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestCtfAnalysis;
+import org.eclipse.osgi.util.NLS;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test suite for the {@link TmfAbstractAnalysisModule} class
+ */
+public class AnalysisModuleTest {
+
+    private static String MODULE_GENERIC_ID = "test.id";
+    private static String MODULE_GENERIC_NAME = "Test analysis";
+
+    /**
+     * Some tests use traces, let's clean them here
+     */
+    @After
+    public void cleanupTraces() {
+        TmfTestTrace.A_TEST_10K.dispose();
+        CtfTmfTestTrace.KERNEL.dispose();
+    }
+
+    /**
+     * Test suite for analysis module getters and setters
+     */
+    @Test
+    public void testGettersSetters() {
+        IAnalysisModule module = new TestAnalysis();
+
+        module.setName(MODULE_GENERIC_NAME);
+        module.setId(MODULE_GENERIC_ID);
+        assertEquals(MODULE_GENERIC_ID, module.getId());
+        assertEquals(MODULE_GENERIC_NAME, module.getName());
+
+        module.setAutomatic(false);
+        assertFalse(module.isAutomatic());
+        module.setAutomatic(true);
+        assertTrue(module.isAutomatic());
+        module.addParameter(TestAnalysis.PARAM_TEST);
+        assertNull(module.getParameter(TestAnalysis.PARAM_TEST));
+        module.setParameter(TestAnalysis.PARAM_TEST, 1);
+        assertEquals(1, module.getParameter(TestAnalysis.PARAM_TEST));
+
+        /* Try to set and get wrong parameter */
+        String wrongParam = "abc";
+        Exception exception = null;
+        try {
+            module.setParameter(wrongParam, 1);
+        } catch (RuntimeException e) {
+            exception = e;
+            assertEquals(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, wrongParam, module.getName()), e.getMessage());
+        }
+        assertNotNull(exception);
+        assertNull(module.getParameter(wrongParam));
+    }
+
+    private static TestAnalysis setUpAnalysis() {
+        TestAnalysis module = new TestAnalysis();
+
+        module.setName(MODULE_GENERIC_NAME);
+        module.setId(MODULE_GENERIC_ID);
+        module.addParameter(TestAnalysis.PARAM_TEST);
+
+        return module;
+
+    }
+
+    /**
+     * Test suite for analysis module
+     * {@link TmfAbstractAnalysisModule#waitForCompletion(IProgressMonitor)} with
+     * successful execution
+     */
+    @Test
+    public void testWaitForCompletionSuccess() {
+        TestAnalysis module = setUpAnalysis();
+
+        IStatus status = module.schedule();
+        assertEquals(IStatus.ERROR, status.getSeverity());
+
+        /* Set a stub trace for analysis */
+        try {
+            module.setTrace(TmfTestTrace.A_TEST_10K.getTrace());
+        } catch (TmfAnalysisException e) {
+            fail(e.getMessage());
+        }
+
+        /* Default execution, with output 1 */
+        module.setParameter(TestAnalysis.PARAM_TEST, 1);
+        status = module.schedule();
+        assertEquals(Status.OK_STATUS, status);
+        boolean completed = module.waitForCompletion(new NullProgressMonitor());
+
+        assertTrue(completed);
+        assertEquals(1, module.getAnalysisOutput());
+    }
+
+    /**
+     * Test suite for {@link TmfAbstractAnalysisModule#waitForCompletion(IProgressMonitor)} with cancellation
+     */
+    @Test
+    public void testWaitForCompletionCancelled() {
+        TestAnalysis module = setUpAnalysis();
+
+        /* Set a stub trace for analysis */
+        ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace();
+        try {
+            module.setTrace(trace);
+        } catch (TmfAnalysisException e) {
+            fail(e.getMessage());
+        }
+
+        module.setParameter(TestAnalysis.PARAM_TEST, 0);
+        IStatus status = module.schedule();
+        assertEquals(Status.OK_STATUS, status);
+        boolean completed = module.waitForCompletion(new NullProgressMonitor());
+
+        assertFalse(completed);
+        assertEquals(0, module.getAnalysisOutput());
+    }
+
+    /**
+     * Test the {@link TmfAbstractAnalysisModule#setTrace(ITmfTrace)} method with wrong trace
+     */
+    @Test
+    public void testSetWrongTrace() {
+        IAnalysisModule module = new TestCtfAnalysis();
+
+        module.setName(MODULE_GENERIC_NAME);
+        module.setId(MODULE_GENERIC_ID);
+        assertEquals(MODULE_GENERIC_ID, module.getId());
+        assertEquals(MODULE_GENERIC_NAME, module.getName());
+
+        Exception exception = null;
+        try {
+            module.setTrace(TmfTestTrace.A_TEST_10K.getTrace());
+        } catch (TmfAnalysisException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+        assertEquals(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, module.getName()), exception.getMessage());
+
+    }
+
+    /**
+     * Test suite for the {@link TmfAbstractAnalysisModule#cancel()} method
+     */
+    @Test
+    public void testCancel() {
+        TestAnalysis module = setUpAnalysis();
+
+        module.setParameter(TestAnalysis.PARAM_TEST, 999);
+        try {
+            module.setTrace(TmfTestTrace.A_TEST_10K.getTrace());
+        } catch (TmfAnalysisException e) {
+            fail(e.getMessage());
+        }
+
+        assertEquals(Status.OK_STATUS, module.schedule());
+
+        /* Give the job a chance to start */
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            fail(e.getMessage());
+        }
+
+        module.cancel();
+        assertFalse(module.waitForCompletion(new NullProgressMonitor()));
+        assertEquals(-1, module.getAnalysisOutput());
+    }
+
+    /**
+     * Test suite for the {@link IAnalysisModule#notifyParameterChanged(String)}
+     * method
+     */
+    @Test
+    public void testParameterChanged() {
+        TestAnalysis module = setUpAnalysis();
+
+        try {
+            module.setTrace(TmfTestTrace.A_TEST_10K.getTrace());
+        } catch (TmfAnalysisException e) {
+            fail(e.getMessage());
+        }
+
+        /* Check exception if no wrong parameter name */
+        Exception exception = null;
+        try {
+            module.notifyParameterChanged("aaa");
+        } catch (RuntimeException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+
+        /*
+         * Cannot test anymore of this method, need a parameter provider to do
+         * this
+         */
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java b/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/analysis/AnalysisParameterProviderTest.java
new file mode 100644 (file)
index 0000000..bd3e0c8
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.analysis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisParameterProvider;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.tests.shared.TmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysis;
+import org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestAnalysisParameterProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test the TmfAbstractParameterProvider class
+ *
+ * @author Geneviève Bastien
+ */
+public class AnalysisParameterProviderTest {
+
+    /**
+     * Registers the parameter provider
+     */
+    @Before
+    public void setup() {
+        TmfAnalysisManager.registerParameterProvider(AnalysisManagerTest.MODULE_PARAM, TestAnalysisParameterProvider.class);
+    }
+
+    /**
+     * Cleanup the trace after testing
+     */
+    @After
+    public void cleanupTrace() {
+        TmfTestTrace.A_TEST_10K.dispose();
+    }
+
+    /**
+     * Test that the provider's value is used
+     */
+    @Test
+    public void testProviderTmfTrace() {
+        ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace();
+        /* Make sure the value is set to null */
+        IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(AnalysisManagerTest.MODULE_PARAM);
+        IAnalysisModule module;
+        try {
+            module = helper.newModule(trace);
+        } catch (TmfAnalysisException e) {
+            fail(e.getMessage());
+            return;
+        }
+        assertEquals(10, module.getParameter(TestAnalysis.PARAM_TEST));
+
+        /* Change the value of the parameter in the provider */
+        List<IAnalysisParameterProvider> providers = TmfAnalysisManager.getParameterProviders(module, trace);
+        assertEquals(1, providers.size());
+        TestAnalysisParameterProvider provider = (TestAnalysisParameterProvider) providers.get(0);
+        provider.setValue(5);
+        assertEquals(5, module.getParameter(TestAnalysis.PARAM_TEST));
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysis.java
new file mode 100644 (file)
index 0000000..9879ac3
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.tests.stubs.analysis;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Simple analysis type for test
+ */
+public class TestAnalysis extends TmfAbstractAnalysisModule {
+
+    private int output = 0;
+
+    /**
+     * Test parameter. If set, simulate cancellation
+     */
+    public static final String PARAM_TEST = "test";
+
+    /**
+     * Constructor
+     */
+    public TestAnalysis() {
+        super();
+    }
+
+    @Override
+    public boolean canExecute(ITmfTrace trace) {
+        return true;
+    }
+
+    @Override
+    protected boolean executeAnalysis(final IProgressMonitor monitor) {
+        if (getParameter(PARAM_TEST) == null) {
+            throw new RuntimeException("The parameter should be set");
+        }
+        /* If PARAM_TEST is set to 0, simulate cancellation */
+        if ((Integer) getParameter(PARAM_TEST) == 0) {
+            output = 0;
+            return false;
+        } else if ((Integer) getParameter(PARAM_TEST) == 999) {
+            /* just stay in an infinite loop until cancellation */
+            while (!monitor.isCanceled()) {
+
+            }
+            return !monitor.isCanceled();
+        }
+        output = (Integer) getParameter(PARAM_TEST);
+        return true;
+    }
+
+    @Override
+    protected void canceling() {
+        output = -1;
+    }
+
+    @Override
+    public Object getParameter(String name) {
+        Object value = super.getParameter(name);
+        if ((value != null) && name.equals(PARAM_TEST) && (value instanceof String)) {
+            return Integer.parseInt((String) value);
+        }
+        return value;
+    }
+
+    @Override
+    protected void parameterChanged(String name) {
+        schedule();
+    }
+
+    /**
+     * Get the analysis output value
+     *
+     * @return The analysis output
+     */
+    public int getAnalysisOutput() {
+        return output;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestAnalysisParameterProvider.java
new file mode 100644 (file)
index 0000000..b5614e8
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.tests.stubs.analysis;
+
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisParamProvider;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub;
+
+/**
+ * Test parameter provider for the PARAM_TEST that would apply only to
+ * CtfTmfTrace (though it is associated with an analysis that supports all trace
+ * types)
+ *
+ * @author Geneviève Bastien
+ */
+public class TestAnalysisParameterProvider extends TmfAbstractAnalysisParamProvider {
+
+    private int fValue = 10;
+
+    @Override
+    public String getName() {
+        return "test parameter provider";
+    }
+
+    @Override
+    public Object getParameter(String name) {
+        if (name.equals(TestAnalysis.PARAM_TEST)) {
+            return fValue;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean appliesToTrace(ITmfTrace trace) {
+        return (trace instanceof TmfTraceStub);
+    }
+
+    /**
+     * Sets a new value for the parameter
+     *
+     * @param value
+     *            new parameter value
+     */
+    public void setValue(int value) {
+        fValue = value;
+        notifyParameterChanged(TestAnalysis.PARAM_TEST);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestCtfAnalysis.java b/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/analysis/TestCtfAnalysis.java
new file mode 100644 (file)
index 0000000..517dcf9
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.tests.stubs.analysis;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.tests.stubs.ctf.CtfTmfTraceStub;
+
+/**
+ * Simple analysis type for test
+ */
+public class TestCtfAnalysis extends TmfAbstractAnalysisModule{
+
+    @Override
+    public boolean canExecute(ITmfTrace trace) {
+        /* This just makes sure the trace is a ctf stub trace */
+        return (CtfTmfTraceStub.class.isAssignableFrom(trace.getClass()));
+    }
+
+    @Override
+    protected void canceling() {
+
+    }
+
+    @Override
+    protected boolean executeAnalysis(final IProgressMonitor monitor) {
+        return false;
+    }
+
+}
index 3d4f71073e342cb3a526ec03528db4f0598338da..151937282e3fd73a9e6ec289e54260f1833eed95 100644 (file)
@@ -12,6 +12,7 @@ Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.core.resources,
  org.eclipse.linuxtools.ctf.core;bundle-version="3.0.0"
 Export-Package: org.eclipse.linuxtools.internal.tmf.core;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
+ org.eclipse.linuxtools.internal.tmf.core.analysis;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
  org.eclipse.linuxtools.internal.tmf.core.component;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
  org.eclipse.linuxtools.internal.tmf.core.request;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
  org.eclipse.linuxtools.internal.tmf.core.statesystem;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
@@ -22,6 +23,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.core;x-friends:="org.eclipse
  org.eclipse.linuxtools.internal.tmf.core.trace;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
  org.eclipse.linuxtools.internal.tmf.core.trace.indexer;x-friends:="org.eclipse.linuxtools.tmf.core.tests",
  org.eclipse.linuxtools.tmf.core,
+ org.eclipse.linuxtools.tmf.core.analysis,
  org.eclipse.linuxtools.tmf.core.callstack,
  org.eclipse.linuxtools.tmf.core.component,
  org.eclipse.linuxtools.tmf.core.ctfadaptor,
index c0c91cb21581834f7864a0428efecee11ebb667e..0a6f1d768b50c5dd4f114bc2e5909f0d7cf60769 100644 (file)
@@ -16,7 +16,8 @@ bin.includes = META-INF/,\
                plugin.properties,\
                plugin.xml,\
                about.html,\
-               .
+               .,\
+               plugin.xml
 src.includes = about.html
 additional.bundles = org.eclipse.jdt.annotation
 jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
index deebba59a710506b18f941c313829b17501d2b91..d22388b8128170edf2f09a38146f430c40ea49a8 100644 (file)
@@ -7,5 +7,5 @@
             class="org.eclipse.linuxtools.internal.tmf.core.TmfCorePreferenceInitializer">
       </initializer>
    </extension>
-
+   <extension-point id="org.eclipse.linuxtools.tmf.core.analysis" name="Trace Analysis Module" schema="schema/org.eclipse.linuxtools.tmf.core.analysis.exsd"/>
 </plugin>
diff --git a/org.eclipse.linuxtools.tmf.core/schema/org.eclipse.linuxtools.tmf.core.analysis.exsd b/org.eclipse.linuxtools.tmf.core/schema/org.eclipse.linuxtools.tmf.core.analysis.exsd
new file mode 100644 (file)
index 0000000..3d54457
--- /dev/null
@@ -0,0 +1,217 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.linuxtools.tmf.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.linuxtools.tmf.core" id="org.eclipse.linuxtools.tmf.core.analysis" name="Trace Analysis Module"/>
+      </appinfo>
+      <documentation>
+         This extension point is used to contribute new analysis modules to the TMF framework.  Analysis modules provide new independent functionalities that can be run on traces.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence minOccurs="0" maxOccurs="unbounded">
+            <element ref="module"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="module">
+      <complexType>
+         <sequence minOccurs="0" maxOccurs="unbounded">
+            <element ref="parameter"/>
+            <element ref="tracetype"/>
+         </sequence>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The unique ID that identifies this analysis module.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The trace analysis module&apos;s name as it is displayed to the end user
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="analysis_module" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The fully qualified name of a class that implements the &lt;samp&gt;IAnalysisModule&lt;/samp&gt; interface.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="icon" type="string">
+            <annotation>
+               <documentation>
+                  The icon associated to this analysis module.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="resource"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="automatic" type="boolean">
+            <annotation>
+               <documentation>
+                  Whether to execute this analysis automatically when trace is opened, or wait for the user to ask for it
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="parameter">
+      <annotation>
+         <documentation>
+            Parameter for this module
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The parameter name
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="default_value" type="string">
+            <annotation>
+               <documentation>
+                  A default value for this parameter
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="tracetype">
+      <annotation>
+         <documentation>
+            Allow to define the tracetypes this analysis applies to.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The base trace class this analysis applies to or not (it also applies to traces extending this class).
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.linuxtools.tmf.core.trace.ITmfTrace"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="applies" type="boolean">
+            <annotation>
+               <documentation>
+                  Does this tracetype element mean the class applies or not (default true)
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         3.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         &lt;p&gt;
+For an example implementation of an analysis module see:
+&lt;pre&gt;
+plug-in: org.eclipse.linuxtools.tmf.core.tests
+package: org.eclipse.linuxtools.tmf.core.tests.stubs.analysis
+class: TestCtfAnalysis
+&lt;/pre&gt;
+&lt;/p&gt;
+
+&lt;p&gt;
+The following is an example of the extension point:
+&lt;pre&gt;
+&lt;extension
+         point=&quot;org.eclipse.linuxtools.tmf.core.analysis&quot;&gt;
+      &lt;module
+         id=&quot;org.eclipse.linuxtools.tmf.core.tests.analysis.testctf&quot;
+         name=&quot;Test analysis ctf&quot;
+         analysis_module=&quot;org.eclipse.linuxtools.tmf.tests.stubs.analysis.TestCtfAnalysis&quot;
+         automatic=&quot;true&quot;&gt;
+      &lt;/module&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         &lt;p&gt;
+For this extension point, a class implementing IAnalysisModule must be defined (org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule).  Most analysis can just extend the org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule class, since it already contains everything to manage the trace&apos;s, the analysis&apos; execution, cancellation, completion, the help texts, etc.
+&lt;/p&gt;
+&lt;p&gt;
+The key method to implement if extending TmfAbstractAnalysisModule is executeAnalysis(final IProgressMonitor monitor).  It contains the code of the analysis itself and is executed inside an Eclipse job.
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2013 É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 v1.0 which accompanies this distribution, and is available at &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisType.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/analysis/TmfAnalysisType.java
new file mode 100644 (file)
index 0000000..3a5a78a
--- /dev/null
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.tmf.core.analysis;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisModuleHelperCE;
+
+/**
+ * Utility class for accessing TMF analysis type extensions from the platform's
+ * extensions registry.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public final class TmfAnalysisType {
+
+    /** Extension point ID */
+    public static final String TMF_ANALYSIS_TYPE_ID = "org.eclipse.linuxtools.tmf.core.analysis"; //$NON-NLS-1$
+
+    /** Extension point element 'module' */
+    public static final String MODULE_ELEM = "module"; //$NON-NLS-1$
+
+    /** Extension point element 'parameter' */
+    public static final String PARAMETER_ELEM = "parameter"; //$NON-NLS-1$
+
+    /** Extension point attribute 'ID' */
+    public static final String ID_ATTR = "id"; //$NON-NLS-1$
+
+    /** Extension point attribute 'name' */
+    public static final String NAME_ATTR = "name"; //$NON-NLS-1$
+
+    /** Extension point attribute 'analysis_module' */
+    public static final String ANALYSIS_MODULE_ATTR = "analysis_module"; //$NON-NLS-1$
+
+    /** Extension point attribute 'automatic' */
+    public static final String AUTOMATIC_ATTR = "automatic"; //$NON-NLS-1$
+
+    /** Extension point attribute 'icon' */
+    public static final String ICON_ATTR = "icon"; //$NON-NLS-1$
+
+    /** Extension point attribute 'default_value' */
+    public static final String DEFAULT_VALUE_ATTR = "default_value"; //$NON-NLS-1$
+
+    /** Extension point element 'tracetype' */
+    public static final String TRACETYPE_ELEM = "tracetype"; //$NON-NLS-1$
+
+    /** Extension point attribute 'class' */
+    public static final String CLASS_ATTR = "class"; //$NON-NLS-1$
+
+    /** Extension point attribute 'applies' */
+    public static final String APPLIES_ATTR = "applies"; //$NON-NLS-1$
+
+    /**
+     * The mapping of available trace type IDs to their corresponding
+     * configuration element
+     */
+    private final Map<String, IAnalysisModuleHelper> fAnalysisTypeAttributes = new HashMap<String, IAnalysisModuleHelper>();
+
+    private static TmfAnalysisType fInstance = null;
+
+    /**
+     * Retrieves all configuration elements from the platform extension registry
+     * for the trace type extension.
+     *
+     * @return an array of trace type configuration elements
+     */
+    public static IConfigurationElement[] getTypeElements() {
+        IConfigurationElement[] elements =
+                Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID);
+        List<IConfigurationElement> typeElements = new LinkedList<IConfigurationElement>();
+        for (IConfigurationElement element : elements) {
+            if (element.getName().equals(MODULE_ELEM)) {
+                typeElements.add(element);
+            }
+        }
+        return typeElements.toArray(new IConfigurationElement[typeElements.size()]);
+    }
+
+    private TmfAnalysisType() {
+        populateAnalysisTypes();
+    }
+
+    /**
+     * The analysis type instance
+     *
+     * @return the analysis type instance
+     */
+    public static synchronized TmfAnalysisType getInstance() {
+        if (fInstance == null) {
+            fInstance = new TmfAnalysisType();
+        }
+        return fInstance;
+    }
+
+    /**
+     * Get the list of analysis modules
+     *
+     * @return list of analysis modules
+     */
+    public Map<String, IAnalysisModuleHelper> getAnalysisModules() {
+        return fAnalysisTypeAttributes;
+    }
+
+    private void populateAnalysisTypes() {
+        if (fAnalysisTypeAttributes.isEmpty()) {
+            // Populate the Categories and Trace Types
+            IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID);
+            for (IConfigurationElement ce : config) {
+                String elementName = ce.getName();
+                if (elementName.equals(TmfAnalysisType.MODULE_ELEM)) {
+                    String analysisTypeId = ce.getAttribute(TmfAnalysisType.ID_ATTR);
+                    fAnalysisTypeAttributes.put(analysisTypeId, new TmfAnalysisModuleHelperCE(ce));
+                }
+            }
+        }
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModule.java
new file mode 100644 (file)
index 0000000..95bb5ec
--- /dev/null
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Interface that hooks analysis modules to the rest of TMF. Analysis modules
+ * are a set of operations to be run on a trace (or experiment). They will
+ * typically either provide outputs to the end user, or feed other analysis.
+ *
+ * An analysis module must tell what trace type it applies to and if it can be
+ * executed on a given trace of the right type.
+ *
+ * Implementations of this interface must define how an analysis will be
+ * executed once scheduled and provide help texts to describe how to use the
+ * analysis.
+ *
+ * Analysis can also take parameters, manually set, through default values or
+ * using an {@link IAnalysisParameterProvider}. {@link IAnalysisOutput} can also
+ * be registered to an analysis modules to display the results of the analysis.
+ *
+ * This interface just allows to hook the analysis to the TMF framework, but the
+ * developer is free to implement the internals of its operations the way he
+ * wishes.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public interface IAnalysisModule {
+
+    // --------------------------------------------------------
+    // Getters and setters
+    // --------------------------------------------------------
+
+    /**
+     * Sets the name of the analysis module
+     *
+     * @param name
+     *            name of the module
+     */
+    void setName(String name);
+
+    /**
+     * Gets the name of the analysis module
+     *
+     * @return Name of the module
+     */
+    String getName();
+
+    /**
+     * Sets the id of the module
+     *
+     * @param id
+     *            id of the module
+     */
+    void setId(String id);
+
+    /**
+     * Gets the id of the analysis module
+     *
+     * @return The id of the module
+     */
+    String getId();
+
+    /**
+     * Sets whether this analysis should be run automatically at trace opening
+     *
+     * @param auto
+     *            True if analysis should be run automatically for a trace
+     */
+    void setAutomatic(boolean auto);
+
+    /**
+     * Gets whether the analysis should be run automatically at trace opening
+     *
+     * @return true if analysis is to be run automatically
+     */
+    boolean isAutomatic();
+
+    /**
+     * Sets the trace on which to run the analysis
+     *
+     * Note: The trace cannot be final since most modules are instantiated in a
+     * way that does not know about the trace, but it shouldn't be set more than
+     * once since an instance of a module belongs to a trace. It is up to each
+     * implementation to make sure the trace is set only once.
+     *
+     * @param trace
+     *            The trace to run the analysis on
+     * @throws TmfAnalysisException
+     */
+    void setTrace(ITmfTrace trace) throws TmfAnalysisException;
+
+    /**
+     * Add a parameter to this module
+     *
+     * @param name
+     *            Name of the parameter
+     */
+    void addParameter(String name);
+
+    /**
+     * Sets the value of a parameter
+     *
+     * @param name
+     *            The name of the parameter
+     * @param value
+     *            The value (subclasses may type-check it)
+     * @throws RuntimeException
+     */
+    void setParameter(String name, Object value);
+
+    /**
+     * Gets the value of a parameter
+     *
+     * @param name
+     *            Name of the parameter
+     * @return The value of a parameter
+     */
+    Object getParameter(String name);
+
+    // -----------------------------------------------------
+    // Functionalities
+    // -----------------------------------------------------
+
+    /**
+     * Can an analysis be executed on a given trace (otherwise, it is shown
+     * grayed out and a help message is available to see why it is not
+     * applicable)
+     *
+     * @param trace
+     *            The trace to analyze
+     * @return Whether the analysis can be executed
+     */
+    boolean canExecute(ITmfTrace trace);
+
+    /**
+     * Schedule the execution of the analysis. If the trace has been set and is
+     * opened, the analysis will be executed right away, otherwise it should
+     * scheduled for execution once all pre-conditions are satisfied.
+     *
+     * @return An IStatus indicating if the execution of the analysis could be
+     *         scheduled successfully or not.
+     */
+    IStatus schedule();
+
+    /**
+     * Gets a list of outputs
+     *
+     * @return The list of {@link IAnalysisOutput}
+     */
+    List<IAnalysisOutput> getOutputs();
+
+    /**
+     * Registers an output for this analysis
+     *
+     * @param output
+     *            The {@link IAnalysisOutput} object
+     */
+    void registerOutput(IAnalysisOutput output);
+
+    /**
+     * Typically the output of an analysis will be available only after it is
+     * completed. This method allows to wait until an analysis has been
+     * completed or the analysis has been cancelled
+     *
+     * To avoid UI freezes, it should not be called from the main thread of the
+     * application
+     *
+     * @param monitor
+     *            The progress monitor to check for cancellation
+     * @return If the analysis was successfully completed. If false is returned,
+     *         this either means there was a problem during the analysis, or it
+     *         got cancelled before it could finished or it has not been
+     *         scheduled to run at all. In all cases, the quality or
+     *         availability of the output(s) and results is not guaranteed.
+     */
+    boolean waitForCompletion(IProgressMonitor monitor);
+
+    /**
+     * Cancels the current analysis
+     */
+    public void cancel();
+
+    // -----------------------------------------------------
+    // Utilities
+    // -----------------------------------------------------
+
+    /**
+     * Gets a generic help message/documentation for this analysis module
+     *
+     * This help text will be displayed to the user and may contain information
+     * on what the module does, how to use it and how to correctly generate the
+     * trace to make it available
+     *
+     * TODO: Help texts could be quite long. They should reside in their own
+     * file and be accessed either with text, for a command line man page, or
+     * through the eclipse help context.
+     *
+     * @return The generic help text
+     */
+    String getHelpText();
+
+    /**
+     * Gets a help text specific for a given trace
+     *
+     * For instance, it may explain why the analysis module cannot be executed
+     * on a trace and how to correct this
+     *
+     * @param trace
+     *            The trace to analyze
+     * @return A help text with information on a specific trace
+     */
+    String getHelpText(ITmfTrace trace);
+
+    /**
+     * Notify the module that the value of a parameter has changed
+     *
+     * @param name
+     *            The of the parameter that changed
+     */
+    void notifyParameterChanged(String name);
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisModuleHelper.java
new file mode 100644 (file)
index 0000000..2d24065
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.osgi.framework.Bundle;
+
+/**
+ * Interface for modules helpers that provide basic module information and
+ * creates module from a source when requested.
+ *
+ * @author Geneviève Bastien
+ */
+public interface IAnalysisModuleHelper {
+
+    // ------------------------------------
+    // Getters
+    // ------------------------------------
+
+    /**
+     * Gets the id of the analysis module
+     *
+     * @return The id of the module
+     */
+    String getId();
+
+    /**
+     * Gets the name of the analysis module
+     *
+     * @return The id of the module
+     */
+    String getName();
+
+    /**
+     * Gets whether the analysis should be run automatically at trace opening
+     *
+     * @return true if analysis is to be run automatically
+     */
+    boolean isAutomatic();
+
+    /**
+     * Gets a generic help message/documentation for this analysis module
+     *
+     * This help text will be displayed to the user and may contain information
+     * on what the module does, how to use it and how to correctly generate the
+     * trace to make it available
+     *
+     * TODO: Help texts could be quite long. They should reside in their own
+     * file and be accessed either with text, for a command line man page, or
+     * through the eclipse help context. There should be a custom way to make it
+     * available through the helper, without instantiating the analysis, though
+     * help text after analysis instantiation may be richer.
+     *
+     * @return The generic help text
+     */
+    String getHelpText();
+
+    /**
+     * Gets the icon for this module
+     *
+     * @return The icon path
+     */
+    String getIcon();
+
+    /**
+     * Gets the bundle this analysis module is part of
+     *
+     * @return The bundle
+     */
+    Bundle getBundle();
+
+    /**
+     * Does an analysis apply to a given trace type (otherwise, it is not shown)
+     *
+     * @param traceclass
+     *            The trace to analyze
+     * @return whether the analysis applies
+     */
+    boolean appliesToTraceType(Class<? extends ITmfTrace> traceclass);
+
+    // ---------------------------------------
+    // Functionalities
+    // ---------------------------------------
+
+    /**
+     * Creates a new instance of the {@link IAnalysisModule} represented by this
+     * helper and initializes it with the trace.
+     *
+     * @param trace
+     *            The trace to be linked to the module
+     * @return A new {@link IAnalysisModule} instance initialized with the
+     *         trace.
+     * @throws TmfAnalysisException
+     *             Exceptions that occurred when setting trace
+     */
+    IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException;
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisOutput.java
new file mode 100644 (file)
index 0000000..2b574b7
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+/**
+ * Interface for all output types of analysis
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public interface IAnalysisOutput {
+
+    /**
+     * Gets the name of the output
+     *
+     * @return Name of the output
+     */
+    String getName();
+
+    /**
+     * Requests the output for an analysis module. This function does not
+     * necessarily output the analysis, it just specifies that the user wants
+     * this output.
+     */
+    void requestOutput();
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/IAnalysisParameterProvider.java
new file mode 100644 (file)
index 0000000..5b6e5d8
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Interface for classes that can provide parameters to analysis when they are
+ * not set manually
+ *
+ * @author Geneviève Bastien
+ */
+public interface IAnalysisParameterProvider {
+
+    // --------------------------------------------------------
+    // Getters and setters
+    // --------------------------------------------------------
+
+    /**
+     * Gets the name of the parameter provider
+     *
+     * @return Name of the parameter provider
+     */
+    String getName();
+
+    /**
+     * Gets the value of a parameter
+     *
+     * @param name
+     *            Name of the parameter
+     * @return The value of a parameter
+     */
+    Object getParameter(String name);
+
+    // --------------------------------------------------------
+    // Functionalities
+    // --------------------------------------------------------
+
+    /**
+     * Does this parameter provider apply to a given trace
+     *
+     * @param trace
+     *            The trace to analyse
+     * @return whether the parameter provider applies
+     */
+    boolean appliesToTrace(ITmfTrace trace);
+
+    /**
+     * Register an analysis module to be notified when a parameter value is
+     * changed
+     *
+     * @param module
+     *            The listening analysis module
+     */
+    void registerModule(IAnalysisModule module);
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/Messages.java
new file mode 100644 (file)
index 0000000..5b57833
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message bundle for org.eclipse.linuxtools.tmf.core.analysis
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.analysis.messages"; //$NON-NLS-1$
+
+    /** Trace was set more than once for this module */
+    public static String TmfAbstractAnalysisModule_TraceSetMoreThanOnce;
+
+    /** Analysis Module cannot execute on trace */
+    public static String TmfAbstractAnalysisModule_AnalysisCannotExecute;
+
+    /** Analysis Module does not apply to trace */
+    public static String TmfAnalysisModuleHelper_AnalysisDoesNotApply;
+
+    /** Analysis Module for trace */
+    public static String TmfAbstractAnalysisModule_AnalysisForTrace;
+
+    /** Analysis Module presentation */
+    public static String TmfAbstractAnalysisModule_AnalysisModule;
+
+    /** Parameter is invalid */
+    public static String TmfAbstractAnalysisModule_InvalidParameter;
+
+    /** Running analysis */
+    public static String TmfAbstractAnalysisModule_RunningAnalysis;
+
+    /** Error instantiating parameter provider */
+    public static String TmfAnalysisManager_ErrorParameterProvider;
+
+    /** Impossible to instantiate module from helper */
+    public static String TmfAnalysisModuleHelper_ImpossibleToCreateModule;
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisModule.java
new file mode 100644 (file)
index 0000000..ecad82d
--- /dev/null
@@ -0,0 +1,388 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.core.signal.TmfStartAnalysisSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Base class that analysis modules main class may extend. It provides default
+ * behavior to some methods of the analysis module
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public abstract class TmfAbstractAnalysisModule extends TmfComponent implements IAnalysisModule {
+
+    private String fName, fId;
+    private boolean fAutomatic = false, fStarted = false;
+    private ITmfTrace fTrace;
+    private final Map<String, Object> fParameters = new HashMap<String, Object>();
+    private final List<String> fParameterNames = new ArrayList<String>();
+    private final List<IAnalysisOutput> fOutputs = new ArrayList<IAnalysisOutput>();
+    private List<IAnalysisParameterProvider> fParameterProviders = new ArrayList<IAnalysisParameterProvider>();
+    private Job fJob = null;
+
+    private final Object syncObj = new Object();
+
+    /* Latch tracking if the analysis is completed or not */
+    private CountDownLatch fFinishedLatch = new CountDownLatch(0);
+
+    private boolean fAnalysisCancelled = false;
+
+    @Override
+    public boolean isAutomatic() {
+        return fAutomatic;
+    }
+
+    @Override
+    public String getName() {
+        return fName;
+    }
+
+    @Override
+    public void setName(String name) {
+        fName = name;
+    }
+
+    @Override
+    public void setId(String id) {
+        fId = id;
+    }
+
+    @Override
+    public String getId() {
+        return fId;
+    }
+
+    @Override
+    public void setAutomatic(boolean auto) {
+        fAutomatic = auto;
+    }
+
+    @Override
+    public void setTrace(ITmfTrace trace) throws TmfAnalysisException {
+        if (fTrace != null) {
+            throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_TraceSetMoreThanOnce, getName()));
+        }
+
+        /* Check that analysis can be executed */
+        if (!canExecute(trace)) {
+            throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName()));
+        }
+        fTrace = trace;
+        /* Get the parameter providers for this trace */
+        fParameterProviders = TmfAnalysisManager.getParameterProviders(this, fTrace);
+        for (IAnalysisParameterProvider provider : fParameterProviders) {
+            provider.registerModule(this);
+        }
+        resetAnalysis();
+        fStarted = false;
+    }
+
+    /**
+     * Gets the trace
+     *
+     * @return The trace
+     */
+    protected ITmfTrace getTrace() {
+        return fTrace;
+    }
+
+    @Override
+    public void addParameter(String name) {
+        fParameterNames.add(name);
+    }
+
+    @Override
+    public synchronized void setParameter(String name, Object value) {
+        if (!fParameterNames.contains(name)) {
+            throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName()));
+        }
+        Object oldValue = fParameters.get(name);
+        fParameters.put(name, value);
+        if ((value != null) && !(value.equals(oldValue))) {
+            parameterChanged(name);
+        }
+    }
+
+    @Override
+    public synchronized void notifyParameterChanged(String name) {
+        if (!fParameterNames.contains(name)) {
+            throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName()));
+        }
+        Object oldValue = fParameters.get(name);
+        Object value = getParameter(name);
+        if ((value != null) && !(value.equals(oldValue))) {
+            parameterChanged(name);
+        }
+    }
+
+    /**
+     * Used to indicate that a parameter value has been changed
+     *
+     * @param name
+     *            The name of the modified parameter
+     */
+    protected void parameterChanged(String name) {
+
+    }
+
+    @Override
+    public Object getParameter(String name) {
+        Object paramValue = fParameters.get(name);
+        /* The parameter is not set, maybe it can be provided by someone else */
+        if ((paramValue == null) && (fTrace != null)) {
+            for (IAnalysisParameterProvider provider : fParameterProviders) {
+                paramValue = provider.getParameter(name);
+                if (paramValue != null) {
+                    break;
+                }
+            }
+        }
+        return paramValue;
+    }
+
+    @Override
+    public boolean canExecute(ITmfTrace trace) {
+        return true;
+    }
+
+    /**
+     * Set the countdown latch back to 1 so the analysis can be executed again
+     */
+    protected void resetAnalysis() {
+        fFinishedLatch = new CountDownLatch(1);
+    }
+
+    /**
+     * Actually executes the analysis itself
+     *
+     * @param monitor
+     *            Progress monitor
+     * @return Whether the analysis was completed successfully or not
+     * @throws TmfAnalysisException
+     *             Method may throw an analysis exception
+     */
+    protected abstract boolean executeAnalysis(final IProgressMonitor monitor) throws TmfAnalysisException;
+
+    /**
+     * Indicate the analysis has been canceled. It is abstract to force
+     * implementing class to cleanup what they are running. This is called by
+     * the job's canceling. It does not need to be called directly.
+     */
+    protected abstract void canceling();
+
+    /**
+     * To be called when the analysis is completed, whether normally or because
+     * it was cancelled or for any other reason.
+     *
+     * It has to be called inside a synchronized block
+     */
+    private void setAnalysisCompleted() {
+        fStarted = false;
+        fJob = null;
+        fFinishedLatch.countDown();
+    }
+
+    /**
+     * Cancels the analysis if it is executing
+     */
+    @Override
+    public final void cancel() {
+        synchronized (syncObj) {
+            if (fJob != null) {
+                if (fJob.cancel()) {
+                    fAnalysisCancelled = true;
+                    setAnalysisCompleted();
+                }
+            }
+            fStarted = false;
+        }
+    }
+
+    private void execute() {
+
+        /*
+         * TODO: The analysis in a job should be done at the analysis manager
+         * level instead of depending on this abstract class implementation,
+         * otherwise another analysis implementation may block the main thread
+         */
+
+        /* Do not execute if analysis has already run */
+        if (fFinishedLatch.getCount() == 0) {
+            return;
+        }
+
+        /* Do not execute if analysis already running */
+        synchronized (syncObj) {
+            if (fStarted) {
+                return;
+            }
+            fStarted = true;
+        }
+
+        /*
+         * Actual analysis will be run on a separate thread
+         */
+        fJob = new Job(NLS.bind(Messages.TmfAbstractAnalysisModule_RunningAnalysis, getName())) {
+            @Override
+            protected IStatus run(final IProgressMonitor monitor) {
+                try {
+                    monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+                    broadcast(new TmfStartAnalysisSignal(TmfAbstractAnalysisModule.this, TmfAbstractAnalysisModule.this));
+                    fAnalysisCancelled = !executeAnalysis(monitor);
+                } catch (TmfAnalysisException e) {
+                    Activator.logError("Error executing analysis with trace " + getTrace().getName(), e); //$NON-NLS-1$
+                } finally {
+                    synchronized (syncObj) {
+                        monitor.done();
+                        setAnalysisCompleted();
+                    }
+                }
+                if (!fAnalysisCancelled) {
+                    return Status.OK_STATUS;
+                }
+                return Status.CANCEL_STATUS;
+            }
+
+            @Override
+            protected void canceling() {
+                TmfAbstractAnalysisModule.this.canceling();
+            }
+
+        };
+        fJob.schedule();
+    }
+
+    @Override
+    public IStatus schedule() {
+        if (fTrace == null) {
+            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("No trace specified for analysis %s", getName())); //$NON-NLS-1$
+        }
+        execute();
+
+        return Status.OK_STATUS;
+    }
+
+    @Override
+    public List<IAnalysisOutput> getOutputs() {
+        return Collections.unmodifiableList(fOutputs);
+    }
+
+    @Override
+    public void registerOutput(IAnalysisOutput output) {
+        if (!fOutputs.contains(output)) {
+            fOutputs.add(output);
+        }
+    }
+
+    @Override
+    public boolean waitForCompletion(IProgressMonitor monitor) {
+        try {
+            while (!fFinishedLatch.await(1, TimeUnit.MILLISECONDS)) {
+                if (monitor.isCanceled()) {
+                    fAnalysisCancelled = true;
+                    return false;
+                }
+            }
+        } catch (InterruptedException e) {
+            Activator.logError("Error while waiting for module completion", e); //$NON-NLS-1$
+        }
+        return !fAnalysisCancelled;
+    }
+
+    /**
+     * Signal handler for trace closing
+     *
+     * @param signal
+     *            Trace closed signal
+     */
+    @TmfSignalHandler
+    public void traceClosed(TmfTraceClosedSignal signal) {
+        /* Is the closing trace the one that was requested? */
+        if (signal.getTrace() == fTrace) {
+            cancel();
+            fTrace = null;
+        }
+    }
+
+    /**
+     * Returns a full help text to display
+     *
+     * @return Full help text for the module
+     */
+    protected String getFullHelpText() {
+        return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisModule, getName());
+    }
+
+    /**
+     * Gets a short help text, to display as header to other help text
+     *
+     * @param trace
+     *            The trace to show help for
+     *
+     * @return Short help text describing the module
+     */
+    protected String getShortHelpText(ITmfTrace trace) {
+        return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisForTrace, getName(), trace.getName());
+    }
+
+    /**
+     * Gets the help text specific for a trace who does not have required
+     * characteristics for module to execute
+     *
+     * @param trace
+     *            The trace to apply the analysis to
+     * @return Help text
+     */
+    protected String getTraceCannotExecuteHelpText(ITmfTrace trace) {
+        return Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute;
+    }
+
+    @Override
+    public String getHelpText() {
+        return getFullHelpText();
+    }
+
+    @Override
+    public String getHelpText(ITmfTrace trace) {
+        if (trace == null) {
+            return getHelpText();
+        }
+        String text = getShortHelpText(trace);
+        if (!canExecute(trace)) {
+            text = text + getTraceCannotExecuteHelpText(trace);
+        }
+        return text;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAbstractAnalysisParamProvider.java
new file mode 100644 (file)
index 0000000..cec9f21
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+/**
+ * Abstract class for parameter providers, implements methods and
+ * functionalities to warn the analysis module of parameter changed
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public abstract class TmfAbstractAnalysisParamProvider implements IAnalysisParameterProvider {
+
+    /**
+     * The module registered with this provider
+     */
+    private IAnalysisModule fModule;
+
+    @Override
+    public void registerModule(IAnalysisModule module) {
+        if (module == null) {
+            throw new IllegalArgumentException();
+        }
+        fModule = module;
+    }
+
+    /**
+     * Gets the analysis module
+     *
+     * @return the {@link IAnalysisModule} associated with this provider
+     */
+    protected IAnalysisModule getModule() {
+        return fModule;
+    }
+
+    /**
+     * Notify the registered module that the said parameter has a new value. The
+     * analysis module will decide what to do with this information
+     *
+     * @param name
+     *            Name of the modified parameter
+     */
+    protected void notifyParameterChanged(String name) {
+        if (fModule != null) {
+            fModule.notifyParameterChanged(name);
+        }
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisManager.java
new file mode 100644 (file)
index 0000000..9569bda
--- /dev/null
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.internal.tmf.core.analysis.TmfAnalysisType;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Manages the available analysis helpers from different sources and their
+ * parameter providers.
+ *
+ * TODO: Add the concept of analysis source. Now only a plugin's extension point
+ * is implemented
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfAnalysisManager {
+
+    private static final Map<String, IAnalysisModuleHelper> fAnalysisModules = new HashMap<String, IAnalysisModuleHelper>();
+    private static final Map<String, List<Class<? extends IAnalysisParameterProvider>>> fParameterProviders = new HashMap<String, List<Class<? extends IAnalysisParameterProvider>>>();
+    private static final Map<Class<? extends IAnalysisParameterProvider>, IAnalysisParameterProvider> fParamProviderInstances = new HashMap<Class<? extends IAnalysisParameterProvider>, IAnalysisParameterProvider>();
+
+    /**
+     * Gets all available analysis module helpers
+     *
+     * This map is read-only
+     *
+     * @return The map of available {@link IAnalysisModuleHelper}
+     */
+    public static Map<String, IAnalysisModuleHelper> getAnalysisModules() {
+        synchronized (fAnalysisModules) {
+            if (fAnalysisModules.isEmpty()) {
+                TmfAnalysisType analysis = TmfAnalysisType.getInstance();
+                fAnalysisModules.putAll(analysis.getAnalysisModules());
+            }
+        }
+        return Collections.unmodifiableMap(fAnalysisModules);
+    }
+
+    /**
+     * Gets all analysis module helpers that apply to a given trace type
+     *
+     * This map is read-only
+     *
+     * @param traceclass
+     *            The trace class to get modules for
+     * @return The map of available {@link IAnalysisModuleHelper}
+     */
+    public static Map<String, IAnalysisModuleHelper> getAnalysisModules(Class<? extends ITmfTrace> traceclass) {
+        Map<String, IAnalysisModuleHelper> allModules = getAnalysisModules();
+        Map<String, IAnalysisModuleHelper> map = new HashMap<String, IAnalysisModuleHelper>();
+        for (IAnalysisModuleHelper module : allModules.values()) {
+            if (module.appliesToTraceType(traceclass)) {
+                map.put(module.getId(), module);
+            }
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Gets an analysis module helper identified by an id
+     *
+     * @param id
+     *            Id of the analysis module to get
+     * @return The {@link IAnalysisModuleHelper}
+     */
+    public static IAnalysisModuleHelper getAnalysisModule(String id) {
+        Map<String, IAnalysisModuleHelper> map = getAnalysisModules();
+        return map.get(id);
+    }
+
+    /**
+     * Register a new parameter provider for an analysis
+     *
+     * @param analysisId
+     *            The id of the analysis
+     * @param paramProvider
+     *            The class of the parameter provider
+     */
+    public static void registerParameterProvider(String analysisId, Class<? extends IAnalysisParameterProvider> paramProvider) {
+        synchronized (fParameterProviders) {
+            if (!fParameterProviders.containsKey(analysisId)) {
+                fParameterProviders.put(analysisId, new ArrayList<Class<? extends IAnalysisParameterProvider>>());
+            }
+            fParameterProviders.get(analysisId).add(paramProvider);
+        }
+    }
+
+    /**
+     * Get a parameter provider that applies to the requested trace
+     *
+     * @param module
+     *            Analysis module
+     * @param trace
+     *            The trace
+     * @return A parameter provider if one applies to the trace, null otherwise
+     */
+    public static List<IAnalysisParameterProvider> getParameterProviders(IAnalysisModule module, ITmfTrace trace) {
+        List<IAnalysisParameterProvider> providerList = new ArrayList<IAnalysisParameterProvider>();
+        synchronized (fParameterProviders) {
+            if (!fParameterProviders.containsKey(module.getId())) {
+                return providerList;
+            }
+            for (Class<? extends IAnalysisParameterProvider> providerClass : fParameterProviders.get(module.getId())) {
+                try {
+                    IAnalysisParameterProvider provider = fParamProviderInstances.get(providerClass);
+                    if (provider == null) {
+                        provider = providerClass.newInstance();
+                        fParamProviderInstances.put(providerClass, provider);
+                    }
+                    if (provider != null) {
+                        if (provider.appliesToTrace(trace)) {
+                            providerList.add(provider);
+                        }
+                    }
+                } catch (IllegalArgumentException e) {
+                    Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e);
+                } catch (SecurityException e) {
+                    Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e);
+                } catch (InstantiationException e) {
+                    Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e);
+                } catch (IllegalAccessException e) {
+                    Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e);
+                }
+            }
+        }
+        return providerList;
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperCE.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/TmfAnalysisModuleHelperCE.java
new file mode 100644 (file)
index 0000000..74e0ae7
--- /dev/null
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.analysis;
+
+import org.eclipse.core.runtime.ContributorFactoryOSGi;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.internal.tmf.core.analysis.TmfAnalysisType;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+
+/**
+ * Analysis module helper for modules provided by a plugin's configuration
+ * elements.
+ *
+ * @author Geneviève Bastien
+ */
+public class TmfAnalysisModuleHelperCE implements IAnalysisModuleHelper {
+
+    private final IConfigurationElement fCe;
+
+    /**
+     * Constructor
+     *
+     * @param ce
+     *            The source {@link IConfigurationElement} of this module helper
+     */
+    public TmfAnalysisModuleHelperCE(IConfigurationElement ce) {
+        fCe = ce;
+    }
+
+    // ----------------------------------------
+    // Wrappers to {@link IAnalysisModule} methods
+    // ----------------------------------------
+
+    @Override
+    public String getId() {
+        return fCe.getAttribute(TmfAnalysisType.ID_ATTR);
+    }
+
+    @Override
+    public String getName() {
+        return fCe.getAttribute(TmfAnalysisType.NAME_ATTR);
+    }
+
+    @Override
+    public boolean isAutomatic() {
+        return Boolean.valueOf(fCe.getAttribute(TmfAnalysisType.AUTOMATIC_ATTR));
+    }
+
+    @Override
+    public String getHelpText() {
+        return new String();
+    }
+
+    @Override
+    public String getIcon() {
+        return fCe.getAttribute(TmfAnalysisType.ICON_ATTR);
+    }
+
+    @Override
+    public Bundle getBundle() {
+        return ContributorFactoryOSGi.resolve(fCe.getContributor());
+    }
+
+    @Override
+    public boolean appliesToTraceType(Class<? extends ITmfTrace> traceclass) {
+        boolean applies = false;
+
+        /* Get the module's applying tracetypes */
+        final IConfigurationElement[] tracetypeCE = fCe.getChildren(TmfAnalysisType.TRACETYPE_ELEM);
+        for (IConfigurationElement element : tracetypeCE) {
+            Class<?> applyclass;
+            try {
+                applyclass = getBundle().loadClass(element.getAttribute(TmfAnalysisType.CLASS_ATTR));
+                String classAppliesVal = element.getAttribute(TmfAnalysisType.APPLIES_ATTR);
+                boolean classApplies = true;
+                if (classAppliesVal != null) {
+                    classApplies = Boolean.valueOf(classAppliesVal);
+                }
+                if (classApplies) {
+                    applies = applyclass.isAssignableFrom(traceclass);
+                } else {
+                    applies = !applyclass.isAssignableFrom(traceclass);
+                }
+            } catch (ClassNotFoundException e) {
+                Activator.logError("Error in applies to trace", e); //$NON-NLS-1$
+            } catch (InvalidRegistryObjectException e) {
+                Activator.logError("Error in applies to trace", e); //$NON-NLS-1$
+            }
+        }
+        return applies;
+    }
+
+    // ---------------------------------------
+    // Functionalities
+    // ---------------------------------------
+
+    @Override
+    public IAnalysisModule newModule(ITmfTrace trace) throws TmfAnalysisException {
+
+        /* Check that analysis can be executed */
+        if (!appliesToTraceType(trace.getClass())) {
+            throw new TmfAnalysisException(NLS.bind(Messages.TmfAnalysisModuleHelper_AnalysisDoesNotApply, getName()));
+        }
+
+        IAnalysisModule module = null;
+        try {
+            module = (IAnalysisModule) fCe.createExecutableExtension(TmfAnalysisType.ANALYSIS_MODULE_ATTR);
+            module.setName(getName());
+            module.setId(getId());
+            module.setAutomatic(isAutomatic());
+
+            /* Get the module's parameters */
+            final IConfigurationElement[] parametersCE = fCe.getChildren(TmfAnalysisType.PARAMETER_ELEM);
+            for (IConfigurationElement element : parametersCE) {
+                module.addParameter(element.getAttribute(TmfAnalysisType.NAME_ATTR));
+                String defaultValue = element.getAttribute(TmfAnalysisType.DEFAULT_VALUE_ATTR);
+                if (defaultValue != null) {
+                    module.setParameter(element.getAttribute(TmfAnalysisType.NAME_ATTR), defaultValue);
+                }
+            }
+            module.setTrace(trace);
+        } catch (CoreException e) {
+            Activator.logError("Error getting analysis modules from configuration files", e); //$NON-NLS-1$
+        }
+        return module;
+
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/analysis/messages.properties
new file mode 100644 (file)
index 0000000..db37016
--- /dev/null
@@ -0,0 +1,9 @@
+TmfAbstractAnalysisModule_TraceSetMoreThanOnce=Trace was set more than once for analysis "{0}"
+TmfAbstractAnalysisModule_AnalysisCannotExecute=Cannot perform analysis "{0}" on this trace because the trace does not have the required characteristics
+TmfAnalysisModuleHelper_AnalysisDoesNotApply=Cannot perform analysis "{0}" on this trace because the trace is of the wrong type.
+TmfAbstractAnalysisModule_AnalysisForTrace=Analysis module: {0} for trace {1}
+TmfAbstractAnalysisModule_AnalysisModule=Analysis module: {0}
+TmfAbstractAnalysisModule_InvalidParameter=Parameter {0} is not valid for analysis module {1}
+TmfAbstractAnalysisModule_RunningAnalysis=Running analysis {0}
+TmfAnalysisManager_ErrorParameterProvider=Error instantiating parameter provider
+TmfAnalysisModuleHelper_ImpossibleToCreateModule=Could not instantiate module "{0}"
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/exceptions/TmfAnalysisException.java
new file mode 100644 (file)
index 0000000..8957d02
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.exceptions;
+
+/**
+ * Generic exception for an error or issue occurs in analysis setup and
+ * execution.
+ *
+ * For instance, to perform an analysis, a trace must be of the right type and
+ * have some characteristics. If trying to do an analysis on a trace that does
+ * not match, this exception is thrown.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfAnalysisException extends Exception {
+
+    private static final long serialVersionUID = -4567750551324478401L;
+
+    /**
+     * Default constructor
+     */
+    public TmfAnalysisException() {
+        super();
+    }
+
+    /**
+     * Constructor with a message
+     *
+     * @param message
+     *            Message to attach to this exception
+     */
+    public TmfAnalysisException(String message) {
+        super(message);
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfStartAnalysisSignal.java
new file mode 100644 (file)
index 0000000..5542a2c
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.signal;
+
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
+
+/**
+ * Signal indicating an analysis has started. Views and outputs may use it to
+ * update themselves with the results.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfStartAnalysisSignal extends TmfSignal {
+
+    private final IAnalysisModule fModule;
+
+    /**
+     * Constructor for a new signal.
+     *
+     * @param source
+     *            The object sending this signal
+     * @param module
+     *            The analysis module
+     */
+    public TmfStartAnalysisSignal(Object source, IAnalysisModule module) {
+        super(source);
+        fModule = module;
+    }
+
+    /**
+     * Get the trace object concerning this signal
+     *
+     * @return The trace
+     */
+    public IAnalysisModule getAnalysisModule() {
+        return fModule;
+    }
+
+    @Override
+    public String toString() {
+        return "[" + this.getClass().getSimpleName() + " (" + fModule.getName() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+}
index b0f0a38caefc934d65466e4418d4c8ff4449ce09..8d858d193f506aaa3156fd49743f6a17c6835dca 100644 (file)
 package org.eclipse.linuxtools.tmf.core.trace;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
 import org.eclipse.linuxtools.tmf.core.component.ITmfDataProvider;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
@@ -235,6 +237,35 @@ public interface ITmfTrace extends ITmfDataProvider {
      */
     void indexTrace(boolean waitForCompletion);
 
+    /**
+     * Returns an analysis module with the given id
+     *
+     * @param analysisId
+     *            The analysis module id
+     * @return The {@link IAnalysisModule} object
+     */
+    IAnalysisModule getAnalysisModule(String analysisId);
+
+    /**
+     * Return a list of analysis modules that are of a given class
+     *
+     * @param moduleclass
+     *            Class returned module must extend
+     * @return List of {@link IAnalysisModule} of class moduleclass
+     */
+    List<IAnalysisModule> getAnalysisModules(Class<? extends IAnalysisModule> moduleclass);
+
+    /**
+     * Returns a map of analysis modules applicable to this trace. The key is
+     * the analysis id.
+     *
+     * This view should be read-only (implementations should use
+     * {@link Collections#unmodifiableMap}).
+     *
+     * @return The map of analysis modules
+     */
+    Map<String, IAnalysisModule> getAnalysisModules();
+
     // ------------------------------------------------------------------------
     // Trace characteristics getters
     // ------------------------------------------------------------------------
index c5f0d16a61ed26b6f1ceaeaf565cf0baff35c71a..cf6e97e5e38be5c51c6c3a4421c8c07f1b9961a4 100644 (file)
@@ -23,9 +23,12 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IResource;
@@ -36,8 +39,12 @@ import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.linuxtools.internal.tmf.core.Activator;
 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
 import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
@@ -131,6 +138,9 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
 
     private ITmfTimestampTransform fTsTransform;
 
+    private final Map<String, IAnalysisModule> fAnalysisModules =
+            new LinkedHashMap<String, IAnalysisModule>();
+
     private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$
 
     // ------------------------------------------------------------------------
@@ -310,6 +320,52 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
         return Status.OK_STATUS;
     }
 
+    /**
+     * Instantiate the applicable analysis modules and executes the analysis
+     * modules that are meant to be automatically executed
+     *
+     * @return An IStatus indicating whether the analysis could be run
+     *         successfully or not
+     * @since 3.0
+     */
+    protected IStatus executeAnalysis() {
+        MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
+        Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules(this.getClass());
+        for (IAnalysisModuleHelper helper : modules.values()) {
+            try {
+                IAnalysisModule module = helper.newModule(this);
+                fAnalysisModules.put(module.getId(), module);
+                if (module.isAutomatic()) {
+                    status.add(module.schedule());
+                }
+            } catch (TmfAnalysisException e) {
+                status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
+            }
+        }
+        return status;
+    }
+
+    @Override
+    public final IAnalysisModule getAnalysisModule(String analysisId) {
+        return fAnalysisModules.get(analysisId);
+    }
+
+    @Override
+    public List<IAnalysisModule> getAnalysisModules(Class<? extends IAnalysisModule> moduleclass) {
+        List<IAnalysisModule> modules = new ArrayList<IAnalysisModule>();
+        for (Entry<String, IAnalysisModule> entry : fAnalysisModules.entrySet()) {
+            if (moduleclass.isAssignableFrom(entry.getValue().getClass())) {
+                modules.add(entry.getValue());
+            }
+        }
+        return modules;
+    }
+
+    @Override
+    public Map<String, IAnalysisModule> getAnalysisModules() {
+        return Collections.unmodifiableMap(fAnalysisModules);
+    }
+
     /**
      * Clears the trace
      */
@@ -695,6 +751,7 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
         MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
         status.add(buildStatistics());
         status.add(buildStateSystem());
+        status.add(executeAnalysis());
         if (!status.isOK()) {
             Activator.log(status);
         }
index bca93b451c86f7758bea5587a344728c932b7e8c..99128a39f9c710f45bbd210dd67f26ccd818ad91 100644 (file)
         name="TestSDView2Loaders"
         restorable="true">
   </view>
-       </extension>
+  <view
+        category="org.eclipse.linuxtools.tmf.ui.stubs"
+        class="org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDView"
+        id="org.eclipse.linuxtools.tmf.ui.tests.testAnalysisView"
+        name="Test Analysis View"
+        restorable="true">
+  </view>
+ </extension>
  <extension
        point="org.eclipse.linuxtools.tmf.ui.uml2SDLoader">
     <uml2SDLoader
             trace_type="org.eclipse.linuxtools.tmf.tests.stubs.ctf.CtfTmfTraceStub">
       </type>
    </extension>
+   <extension
+         point="org.eclipse.linuxtools.tmf.core.analysis">
+      <module
+            analysis_module="org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis.TestAnalysisUi"
+            id="org.eclipse.linuxtools.tmf.ui.tests.test"
+            name="Test analysis in UI">
+         <tracetype
+               class="org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub">
+         </tracetype>
+         <tracetype
+               class="org.eclipse.linuxtools.tmf.tests.stubs.ctf.CtfTmfTraceStub">
+         </tracetype>
+      </module>
+   </extension>
 
 </plugin>
index 57af25c4d4c10c3714e1b343b5f0b65ea5e40782..d74726b7f4102d4c94b0cb62e36cb2fcfc7a44ec 100644 (file)
@@ -16,11 +16,13 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
 /**
- *  Test suite for org.eclipse.linuxtools.tmf.ui.project.model
+ * Test suite for org.eclipse.linuxtools.tmf.ui.project.model
  */
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
-    ProjectModelTraceTest.class
+        ProjectModelAnalysisTest.class,
+        ProjectModelOutputTest.class,
+        ProjectModelTraceTest.class
 })
 public class AllTests {
 
diff --git a/org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java b/org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelAnalysisTest.java
new file mode 100644 (file)
index 0000000..b999f88
--- /dev/null
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.tests.project.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfNavigatorContentProvider;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
+import org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis.TestAnalysisUi;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test suite for the {@link TmfAnalysisElement} class.
+ *
+ * @author Geneviève Bastien
+ */
+public class ProjectModelAnalysisTest {
+
+    /** ID of analysis module in UI */
+    public static final String MODULE_UI = "org.eclipse.linuxtools.tmf.ui.tests.test";
+    private TmfProjectElement fixture;
+
+    /**
+     * Perform pre-test initialization.
+     */
+    @Before
+    public void setUp() {
+        assumeTrue(CtfTmfTestTrace.KERNEL.exists());
+        try {
+            fixture = ProjectModelTestData.getFilledProject();
+        } catch (CoreException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Cleans up the project after tests have been executed
+     */
+    @After
+    public void cleanUp() {
+        ProjectModelTestData.deleteProject(fixture);
+    }
+
+    private TmfTraceElement getTraceElement() {
+        TmfTraceElement trace = null;
+        for (ITmfProjectModelElement element : fixture.getTracesFolder().getChildren()) {
+            if (element instanceof TmfTraceElement) {
+                TmfTraceElement traceElement = (TmfTraceElement) element;
+                if (traceElement.getName().equals(ProjectModelTestData.getTraceName())) {
+                    trace = traceElement;
+                }
+            }
+        }
+        assertNotNull(trace);
+        return trace;
+    }
+
+    /**
+     * Test the getAvailableAnalysis() method
+     */
+    @Test
+    public void testListAnalysis() {
+        TmfTraceElement trace = getTraceElement();
+
+        /* Make sure the analysis list is not empty */
+        List<TmfAnalysisElement> analysisList = trace.getAvailableAnalysis();
+        assertFalse(analysisList.isEmpty());
+
+        /* Make sure TestAnalysisUi is there */
+        TmfAnalysisElement analysis = null;
+        for (TmfAnalysisElement analysisElement : analysisList) {
+            if (analysisElement.getAnalysisId().equals(MODULE_UI)) {
+                analysis = analysisElement;
+            }
+        }
+        assertNotNull(analysis);
+
+        assertEquals("Test analysis in UI", analysis.getName());
+    }
+
+    /**
+     * Test if the list of available analysis is correctly populated by the
+     * content provider
+     */
+    @Test
+    public void testPopulate() {
+        TmfTraceElement trace = getTraceElement();
+
+        final TmfNavigatorContentProvider ncp = new TmfNavigatorContentProvider();
+        // force the model to be populated
+        ncp.getChildren(fixture);
+
+        /* Make sure the analysis list is not empty */
+        List<ITmfProjectModelElement> analysisList = trace.getChildren();
+        assertFalse(analysisList.isEmpty());
+
+        /* Make sure TestAnalysisUi is there */
+        TmfAnalysisElement analysis = null;
+        for (ITmfProjectModelElement element : analysisList) {
+            if (element instanceof TmfAnalysisElement) {
+                TmfAnalysisElement analysisElement = (TmfAnalysisElement) element;
+                if (analysisElement.getAnalysisId().equals(MODULE_UI)) {
+                    analysis = analysisElement;
+                }
+            }
+        }
+        assertNotNull(analysis);
+
+        assertEquals("Test analysis in UI", analysis.getName());
+    }
+
+    /**
+     * Test the instantiateAnalysis method
+     */
+    @Test
+    public void testInstantiate() {
+        TmfTraceElement traceElement = getTraceElement();
+
+        TmfAnalysisElement analysis = null;
+        for (TmfAnalysisElement analysisElement : traceElement.getAvailableAnalysis()) {
+            if (analysisElement.getAnalysisId().equals(MODULE_UI)) {
+                analysis = analysisElement;
+            }
+        }
+        assertNotNull(analysis);
+
+        /* Instantiate an analysis on a trace that is closed */
+        traceElement.closeEditors();
+        analysis.activateParent();
+
+        /* Give some time to the trace to open */
+        ProjectModelTestData.delayThread(1000);
+
+        /* Get the analysis module associated with the element */
+        ITmfTrace trace = traceElement.getTrace();
+        assertNotNull(trace);
+        TestAnalysisUi module = (TestAnalysisUi) trace.getAnalysisModule(analysis.getAnalysisId());
+        assertNotNull(module);
+
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java b/org.eclipse.linuxtools.tmf.ui.tests/src/org/eclipse/linuxtools/tmf/ui/tests/project/model/ProjectModelOutputTest.java
new file mode 100644 (file)
index 0000000..52a5cf6
--- /dev/null
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.tests.project.model;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
+import org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis.TestAnalysisUi;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test suite for the {@link TmfAnalysisOutputElement} class.
+ *
+ * @author Geneviève Bastien
+ */
+public class ProjectModelOutputTest {
+
+    private TmfProjectElement fixture;
+
+    /**
+     * Perform pre-test initialization.
+     */
+    @Before
+    public void setUp() {
+        try {
+            fixture = ProjectModelTestData.getFilledProject();
+        } catch (CoreException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Cleans up the project after tests have been executed
+     */
+    @After
+    public void cleanUp() {
+        ProjectModelTestData.deleteProject(fixture);
+    }
+
+    private TmfTraceElement getTraceElement() {
+        TmfTraceElement trace = null;
+        for (ITmfProjectModelElement element : fixture.getTracesFolder().getChildren()) {
+            if (element instanceof TmfTraceElement) {
+                TmfTraceElement traceElement = (TmfTraceElement) element;
+                if (traceElement.getName().equals(ProjectModelTestData.getTraceName())) {
+                    trace = traceElement;
+                }
+            }
+        }
+        assertNotNull(trace);
+        return trace;
+    }
+
+    private TmfAnalysisElement getTestAnalysisUi() {
+        TmfTraceElement trace = getTraceElement();
+
+        /* Make sure the analysis list is not empty */
+        List<TmfAnalysisElement> analysisList = trace.getAvailableAnalysis();
+        assertFalse(analysisList.isEmpty());
+
+        /* Make sure TestAnalysisUi is there */
+        TmfAnalysisElement analysis = null;
+        for (TmfAnalysisElement analysisElement : analysisList) {
+            if (analysisElement.getAnalysisId().equals(ProjectModelAnalysisTest.MODULE_UI)) {
+                analysis = analysisElement;
+            }
+        }
+        assertNotNull(analysis);
+        return analysis;
+    }
+
+    /**
+     * Test the getAvailableOutputs() method
+     */
+    @Test
+    public void testListOutputs() {
+        TmfAnalysisElement analysis = getTestAnalysisUi();
+
+        /* To get the list of outputs the trace needs to be opened */
+        analysis.activateParent();
+        ProjectModelTestData.delayThread(500);
+
+        /* Make sure the output list is not empty */
+        List<TmfAnalysisOutputElement> outputList = analysis.getAvailableOutputs();
+        assertFalse(outputList.isEmpty());
+        boolean found = false;
+        for (ITmfProjectModelElement element : outputList) {
+            if (element instanceof TmfAnalysisOutputElement) {
+                TmfAnalysisOutputElement outputElement = (TmfAnalysisOutputElement) element;
+                if (outputElement.getName().equals("Test Analysis View")) {
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+    }
+
+    /**
+     * Test the outputAnalysis method for a view
+     */
+    @Test
+    public void testOpenView() {
+        TmfAnalysisElement analysis = getTestAnalysisUi();
+
+        analysis.activateParent();
+        ProjectModelTestData.delayThread(1000);
+
+        List<TmfAnalysisOutputElement> outputList = analysis.getAvailableOutputs();
+        assertFalse(outputList.isEmpty());
+
+        final IWorkbench wb = PlatformUI.getWorkbench();
+        final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
+
+        IViewPart view = activePage.findView(TestAnalysisUi.VIEW_ID);
+        if (view != null) {
+            activePage.hideView(view);
+        }
+
+        TmfAnalysisOutputElement outputElement = null;
+        for (ITmfProjectModelElement element : outputList) {
+            if (element instanceof TmfAnalysisOutputElement) {
+                TmfAnalysisOutputElement el = (TmfAnalysisOutputElement) element;
+                if (el.getName().equals("Test Analysis View")) {
+                    outputElement = el;
+                }
+            }
+        }
+        assertNotNull(outputElement);
+
+        outputElement.outputAnalysis();
+        ProjectModelTestData.delayThread(1000);
+        view = activePage.findView(TestAnalysisUi.VIEW_ID);
+        assertNotNull(view);
+    }
+}
index 8eec93b64395ca6f5465bd251458bbe7ccf6bbfb..05619b91b1ec57ab8a56c7558494e8e477d187dc 100644 (file)
@@ -12,6 +12,8 @@
 
 package org.eclipse.linuxtools.tmf.ui.tests.project.model;
 
+import static org.junit.Assume.assumeTrue;
+
 import java.io.File;
 
 import org.eclipse.core.resources.IFolder;
@@ -21,6 +23,7 @@ import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
+import org.eclipse.linuxtools.internal.tmf.ui.Activator;
 import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfImportHelper;
 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
 import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace;
@@ -34,6 +37,8 @@ import org.eclipse.swt.widgets.Display;
 
 /**
  * Creates objects used for this package's testing purposes
+ *
+ * @author Geneviève Bastien
  */
 public class ProjectModelTestData {
 
@@ -51,6 +56,8 @@ public class ProjectModelTestData {
      */
     public static TmfProjectElement getFilledProject() throws CoreException {
 
+        assumeTrue(CtfTmfTestTrace.KERNEL.exists());
+
         IProject project = TmfProjectRegistry.createProject(PROJECT_NAME, null, null);
         IFolder traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
 
@@ -63,7 +70,7 @@ public class ProjectModelTestData {
             return null;
         }
         linkedTrace.setPersistentProperty(TmfCommonConstants.TRACETYPE,
-                "org.eclipse.linuxtools.tmf.ui.type.ctf");
+                "org.eclipse.linuxtools.tmf.tests.ctf.tracetype");
 
         final TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
         TmfTraceElement traceElement = projectElement.getTracesFolder().getTraces().get(0);
@@ -89,10 +96,8 @@ public class ProjectModelTestData {
      *
      * @param project
      *            Project to delete
-     * @throws CoreException
-     *             Thrown by the resource deletion
      */
-    public static void deleteProject(TmfProjectElement project) throws CoreException {
+    public static void deleteProject(TmfProjectElement project) {
         /* Delete experiments */
         for (ITmfProjectModelElement element : project.getExperimentsFolder().getChildren()) {
             if (element instanceof TmfExperimentElement) {
@@ -109,7 +114,11 @@ public class ProjectModelTestData {
                 }
 
                 /* Finally, delete the experiment */
-                resource.delete(true, null);
+                try {
+                    resource.delete(true, null);
+                } catch (CoreException e) {
+                    Activator.getDefault().logError("Error deleting experiment element", e);
+                }
             }
         }
 
@@ -129,12 +138,20 @@ public class ProjectModelTestData {
                 }
 
                 /* Finally, delete the trace */
-                resource.delete(true, new NullProgressMonitor());
+                try {
+                    resource.delete(true, new NullProgressMonitor());
+                } catch (CoreException e) {
+                    Activator.getDefault().logError("Error deleting trace element", e);
+                }
             }
         }
 
         /* Delete the project itself */
-        project.getResource().delete(true, null);
+        try {
+            project.getResource().delete(true, null);
+        } catch (CoreException e) {
+            Activator.getDefault().logError("Error deleting project", e);
+        }
     }
 
     /**
index ba3260d7d63bfbbb2cc14c7d7567c90dbfc74cf7..ff3ed43b54a3b87ac8b79538d97bf4c184d42e1c 100644 (file)
@@ -31,6 +31,8 @@ import org.junit.Test;
 
 /**
  * Test suite for the TmfTraceElement class.
+ *
+ * @author Geneviève Bastien
  */
 public class ProjectModelTraceTest {
 
@@ -54,11 +56,7 @@ public class ProjectModelTraceTest {
      */
     @After
     public void cleanUp() {
-        try {
-            ProjectModelTestData.deleteProject(fixture);
-        } catch (CoreException e) {
-            fail(e.getMessage());
-        }
+        ProjectModelTestData.deleteProject(fixture);
     }
 
     /**
@@ -79,7 +77,7 @@ public class ProjectModelTraceTest {
         TmfOpenTraceHelper.openTraceFromElement(traceElement);
 
         /* Give the trace a chance to open */
-        ProjectModelTestData.delayThread(5000);
+        ProjectModelTestData.delayThread(500);
 
         trace = traceElement.getTrace();
         assertNotNull(trace);
@@ -89,7 +87,7 @@ public class ProjectModelTraceTest {
          * the exact same element as the active trace
          */
         TmfOpenTraceHelper.openTraceFromElement(traceElement);
-        ProjectModelTestData.delayThread(5000);
+        ProjectModelTestData.delayThread(500);
 
         ITmfTrace trace2 = TmfTraceManager.getInstance().getActiveTrace();
 
diff --git a/org.eclipse.linuxtools.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java b/org.eclipse.linuxtools.tmf.ui.tests/widgetStubs/org/eclipse/linuxtools/tmf/ui/tests/stubs/analysis/TestAnalysisUi.java
new file mode 100644 (file)
index 0000000..b56a9ec
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.tests.stubs.analysis;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAbstractAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.ui.analysis.TmfAnalysisViewOutput;
+
+/**
+ * Stub for an analysis module with outputs
+ */
+public class TestAnalysisUi extends TmfAbstractAnalysisModule {
+
+    /** ID of the view opened by this analysis module */
+    public static final String VIEW_ID = "org.eclipse.linuxtools.tmf.ui.tests.testAnalysisView";
+
+    private String fTraceName;
+
+    /**
+     * Constructor
+     */
+    public TestAnalysisUi() {
+        super();
+        registerOutput(new TmfAnalysisViewOutput(VIEW_ID));
+    }
+
+    @Override
+    protected boolean executeAnalysis(final IProgressMonitor monitor) {
+        return false;
+    }
+
+    @Override
+    protected void canceling() {
+
+    }
+
+    @Override
+    public ITmfTrace getTrace() {
+        return super.getTrace();
+    }
+
+    /**
+     * Returns the name of the trace that should be set
+     *
+     * @return Name of the trace
+     */
+    public String getTraceName() {
+        return fTraceName;
+    }
+
+}
index 5c14b587518c823c25165ad474f0ffa5717806d6..d8878da334eaf75f774a92ac79abc9c64309a495 100644 (file)
@@ -26,6 +26,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.ui;x-friends:="org.eclipse.l
  org.eclipse.linuxtools.internal.tmf.ui.project.dialogs;x-internal:=true,
  org.eclipse.linuxtools.internal.tmf.ui.project.handlers;x-internal:=true,
  org.eclipse.linuxtools.internal.tmf.ui.project.model;x-friends:="org.eclipse.linuxtools.lttng2.ui,org.eclipse.linuxtools.tmf.ui.tests",
+ org.eclipse.linuxtools.tmf.ui.analysis,
  org.eclipse.linuxtools.tmf.ui.editors,
  org.eclipse.linuxtools.tmf.ui.project.model,
  org.eclipse.linuxtools.tmf.ui.project.wizards,
index 363e56b37f415277e7636aef5b07d229fcbfafd6..dc1feac866230a495d29e84fe94c80ba308b467e 100644 (file)
@@ -132,7 +132,12 @@ commands.parser.category.name = Parser Commands
 commands.parser.category.description = Parser Commands
 commands.parser.manage = Manage Custom Parsers...
 commands.parser.manage.description = Manage Custom Parsers
+
+## Analysis and views
+command.analysis_help = Help
+command.analysis_help.mnemonic = H
+command.analysis_help.description = Help
+
 contenttype.trace = TMF Trace
 
 parser.provider.extension-point.name = Parser Providers
index bfce198952c7dc90490c5e13e26fadd670ef6494..e57b56be64a1a0e70d0c2a82cfbab2ab4891b4d9 100644 (file)
                         <instanceof
                               value="org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement">
                         </instanceof>
+                        <instanceof
+                              value="org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement">
+                        </instanceof>
                      </or>
                   </iterate>
                </with>
                </with>
             </visibleWhen>
          </command>
+         <command
+               commandId="org.eclipse.linuxtools.tmf.ui.command.analysis_help"
+               icon="icons/dlcl16/open.gif"
+               label="%command.analysis_help"
+               mnemonic="%command.analysis_help.mnemonic"
+               style="push"
+               tooltip="%command.analysis_help.description">
+            <visibleWhen
+                  checkEnabled="false">
+               <with
+                     variable="selection">
+                  <count
+                        value="1">
+                  </count>
+                  <iterate
+                        ifEmpty="false"
+                        operator="and">
+                     <instanceof
+                           value="org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement">
+                     </instanceof>
+                  </iterate>
+               </with>
+            </visibleWhen>
+         </command>
       </menuContribution>
    </extension>
    <extension
             id="org.eclipse.linuxtools.tmf.ui.command.new_experiment"
             name="%command.new_experiment">
       </command>
+      <command
+            categoryId="org.eclipse.linuxtools.tmf.ui.commands.category"
+            description="%command.analysis_help.description"
+            id="org.eclipse.linuxtools.tmf.ui.command.analysis_help"
+            name="%command.analysis_help">
+      </command>
       <command
             categoryId="org.eclipse.linuxtools.tmf.ui.commands.category"
             description="%command.select_trace_type.description"
             </and>
          </activeWhen>
       </handler>
+      <handler
+            class="org.eclipse.linuxtools.internal.tmf.ui.project.handlers.OpenAnalysisHelpHandler"
+            commandId="org.eclipse.linuxtools.tmf.ui.command.analysis_help">
+         <activeWhen>
+            <and>
+               <count
+                     value="1">
+               </count>
+               <iterate
+                     operator="and">
+                  <instanceof
+                        value="org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement">
+                  </instanceof>
+               </iterate>
+            </and>
+         </activeWhen>
+      </handler>
+      <handler
+            class="org.eclipse.linuxtools.internal.tmf.ui.project.handlers.OpenAnalysisOutputHandler"
+            commandId="org.eclipse.ui.navigate.openResource">
+         <activeWhen>
+            <and>
+               <count
+                     value="1">
+               </count>
+               <iterate
+                     operator="and">
+                  <instanceof
+                        value="org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement">
+                  </instanceof>
+               </iterate>
+            </and>
+         </activeWhen>
+      </handler>
       <handler
             class="org.eclipse.linuxtools.internal.tmf.ui.project.handlers.CopyTraceHandler"
             commandId="org.eclipse.ui.edit.copy">
index e4294017718f43b74254a183660b86006f7b6cf2..50dd428bf52a71f21ed63d1346a4e90a6fd38b97 100644 (file)
@@ -50,6 +50,8 @@ public class Messages extends NLS {
     public static String SynchronizeTracesHandler_ErrorSynchingExperiment;
     public static String SynchronizeTracesHandler_ErrorSynchingForTrace;
 
+    public static String AnalysisModule_Help;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
index 5ce88c7fdbfee7d79f170430fde18e3d32cabe52..70b418bb6b9125216da23794146a723e2bee5b7b 100644 (file)
@@ -21,6 +21,7 @@ import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement;
 import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement;
 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectModelElement;
 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
@@ -29,9 +30,6 @@ import org.eclipse.ui.handlers.IHandlerService;
 
 /**
  * <b><u>OpenAction</u></b>
- * <p>
- * Implement me. Please.
- * <p>
  */
 public class OpenAction extends Action {
 
@@ -58,7 +56,8 @@ public class OpenAction extends Action {
             IStructuredSelection sSelection = (IStructuredSelection) selection;
             if (sSelection.size() == 1) {
                 if (sSelection.getFirstElement() instanceof TmfTraceElement ||
-                        sSelection.getFirstElement() instanceof TmfExperimentElement) {
+                        sSelection.getFirstElement() instanceof TmfExperimentElement ||
+                        sSelection.getFirstElement() instanceof TmfAnalysisOutputElement) {
                     element = (TmfProjectModelElement) sSelection.getFirstElement();
                     return true;
                 }
@@ -71,7 +70,7 @@ public class OpenAction extends Action {
     public void run() {
         try {
             IHandlerService handlerService = (IHandlerService) page.getActivePart().getSite().getService(IHandlerService.class);
-            boolean executeCommand = (element instanceof TmfTraceElement);
+            boolean executeCommand = ((element instanceof TmfTraceElement) || (element instanceof TmfAnalysisOutputElement));
 
             if (!executeCommand && element instanceof TmfExperimentElement) {
                 TmfExperimentElement experiment = (TmfExperimentElement) element;
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisHelpHandler.java
new file mode 100644 (file)
index 0000000..6ad18fc
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.tmf.ui.project.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisElement;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Handler for when user wants to open the analysis help text
+ *
+ * @author Geneviève Bastien
+ */
+public class OpenAnalysisHelpHandler extends AbstractHandler {
+
+    private TmfAnalysisElement fAnalysis;
+
+    @Override
+    public boolean isEnabled() {
+        // Check if we are closing down
+        final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return false;
+        }
+
+        // Get the selection
+        final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        final IWorkbenchPart part = page.getActivePart();
+        if (part == null) {
+            return false;
+        }
+        final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider();
+        if (selectionProvider == null) {
+            return false;
+        }
+        final ISelection selection = selectionProvider.getSelection();
+
+        // Make sure there is only one selection and that it is a trace
+        fAnalysis = null;
+        if (selection instanceof TreeSelection) {
+            final TreeSelection sel = (TreeSelection) selection;
+            // There should be only one item selected as per the plugin.xml
+            final Object element = sel.getFirstElement();
+            if (element instanceof TmfAnalysisElement) {
+                fAnalysis = (TmfAnalysisElement) element;
+            }
+        }
+
+        return (fAnalysis != null);
+    }
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+
+        // Check if we are closing down
+        final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return null;
+        }
+
+        // Check that the trace is valid
+        if (fAnalysis == null) {
+            return null;
+        }
+
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                displayHelpMsg(fAnalysis.getHelpMessage());
+            }
+        };
+
+        thread.start();
+
+        return null;
+    }
+
+    private static void displayHelpMsg(final String errorMsg) {
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                /*
+                 * TODO: A message box is not the best place to show help.
+                 * Something should be done with the Eclipse help
+                 */
+                final MessageBox mb = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+                mb.setText(Messages.AnalysisModule_Help);
+                mb.setMessage(errorMsg);
+                mb.open();
+            }
+        });
+    }
+
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenAnalysisOutputHandler.java
new file mode 100644 (file)
index 0000000..772450d
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.tmf.ui.project.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfAnalysisOutputElement;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Handler to programatically open a view
+ *
+ * @author Geneviève Bastien
+ */
+public class OpenAnalysisOutputHandler extends AbstractHandler {
+
+    private TmfAnalysisOutputElement fOutputElement;
+
+    @Override
+    public boolean isEnabled() {
+        /* Check if we are closing down */
+        final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return false;
+        }
+
+        /* Get the selection */
+        final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        final IWorkbenchPart part = page.getActivePart();
+        if (part == null) {
+            return false;
+        }
+        final ISelectionProvider selectionProvider = part.getSite().getSelectionProvider();
+        if (selectionProvider == null) {
+            return false;
+        }
+        final ISelection selection = selectionProvider.getSelection();
+
+        /* Make sure there is only one selection and that it is an analysis output */
+        fOutputElement = null;
+        if (selection instanceof TreeSelection) {
+            final TreeSelection sel = (TreeSelection) selection;
+            // There should be only one item selected as per the plugin.xml
+            final Object element = sel.getFirstElement();
+            if (element instanceof TmfAnalysisOutputElement) {
+                fOutputElement = (TmfAnalysisOutputElement) element;
+            }
+        }
+
+        return (fOutputElement != null);
+    }
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+
+        /* Check if we are closing down */
+        final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (window == null) {
+            return null;
+        }
+
+        /* Check that the view is valid */
+        if (fOutputElement == null) {
+            return null;
+        }
+
+        fOutputElement.outputAnalysis();
+
+        return null;
+    }
+
+}
index ba2d8e31cef6cf657dc143efffe506affb39ecc7..a284e5fbfaad012d835e692fe122321cb014e6cf 100644 (file)
@@ -38,3 +38,6 @@ SynchronizeTracesHandler_Error=Error synchronizing experiment
 
 SynchronizeTracesHandler_ErrorSynchingExperiment=Error synchronizing experiment %s
 SynchronizeTracesHandler_ErrorSynchingForTrace=Error synchronizing experiment %s for trace %s
+
+# Analysis modules
+AnalysisModule_Help=Help
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/analysis/TmfAnalysisViewOutput.java
new file mode 100644 (file)
index 0000000..d5de7d0
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.analysis;
+
+import org.eclipse.linuxtools.internal.tmf.ui.Activator;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput;
+import org.eclipse.linuxtools.tmf.ui.project.model.Messages;
+import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.views.IViewDescriptor;
+
+/**
+ * Class that implements analysis output as a view. This just opens the view.
+ * The view itself needs to manage how and when it will execute the analysis and
+ * display which output.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfAnalysisViewOutput implements IAnalysisOutput {
+
+    private final String fViewId;
+
+    /**
+     * Constructor
+     *
+     * @param viewid
+     *            id of the view to display as output
+     */
+    public TmfAnalysisViewOutput(String viewid) {
+        fViewId = viewid;
+    }
+
+    /**
+     * Returns the view id of the corresponding view
+     *
+     * @return The view id
+     */
+    public String getViewId() {
+        return fViewId;
+    }
+
+    @Override
+    public String getName() {
+        IViewDescriptor descr = PlatformUI.getWorkbench().getViewRegistry().find(fViewId);
+        String viewName = (descr != null) ? descr.getLabel() : fViewId + Messages.TmfAnalysisViewOutput_ViewUnavailable;
+        return viewName;
+    }
+
+    @Override
+    public void requestOutput() {
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+
+                try {
+                    final IWorkbench wb = PlatformUI.getWorkbench();
+                    final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
+
+                    activePage.showView(fViewId);
+
+                } catch (final PartInitException e) {
+                    TraceUtils.displayErrorMsg(Messages.TmfAnalysisViewOutput_Title, "Error opening view " + getName() + e.getMessage()); //$NON-NLS-1$
+                    Activator.getDefault().logError("Error opening view " + getName(), e); //$NON-NLS-1$
+                }
+            }
+        });
+    }
+}
index cce6f8e33fa487cfdcfca2de8360e10980707ee7..ea715be924ebcb1b3a1277703f2692778bb0794d 100644 (file)
@@ -24,6 +24,12 @@ public class Messages extends NLS {
 
     private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.project.model.messages"; //$NON-NLS-1$
 
+    /** Instantiate analysis message box title */
+    public static String TmfAnalysisElement_InstantiateAnalysis;
+
+    /** The message when analysis view is not available */
+    public static String TmfAnalysisViewOutput_ViewUnavailable;
+
     /** The category of the resource properties */
     public static String TmfTraceElement_ResourceProperties;
 
@@ -68,6 +74,9 @@ public class Messages extends NLS {
     /** Init error */
     public static String TmfOpenTraceHelper_InitError;
 
+    /** Analysis view title */
+    public static String TmfAnalysisViewOutput_Title;
+
     static {
         // initialize resource bundle
         NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisElement.java
new file mode 100644 (file)
index 0000000..559a655
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.project.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.osgi.framework.Bundle;
+
+/**
+ * Class for project elements of type analysis modules
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfAnalysisElement extends TmfProjectModelElement {
+
+    private final String fAnalysisId;
+
+    /**
+     * Constructor
+     *
+     * @param name
+     *            Name of the analysis
+     * @param resource
+     *            The resource
+     * @param parent
+     *            Parent of the analysis
+     * @param id
+     *            The analysis module id
+     */
+    protected TmfAnalysisElement(String name, IResource resource, ITmfProjectModelElement parent, String id) {
+        super(name, resource, parent);
+        fAnalysisId = id;
+        refreshOutputs();
+    }
+
+    private void refreshOutputs() {
+        List<TmfAnalysisOutputElement> outputs = getAvailableOutputs();
+
+        /* Remove children */
+        getChildren().clear();
+
+        /* Add the children again */
+        for (TmfAnalysisOutputElement module : outputs) {
+            addChild(module);
+        }
+
+    }
+
+    /**
+     * Get the list of analysis elements
+     *
+     * @return Array of analysis elements
+     */
+    public List<TmfAnalysisOutputElement> getAvailableOutputs() {
+        List<TmfAnalysisOutputElement> list = new ArrayList<TmfAnalysisOutputElement>();
+
+        IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId);
+        if (helper == null) {
+            return list;
+        }
+
+        /** Get base path for resource */
+        IPath path = getProject().getTracesFolder().getPath();
+        if (fResource instanceof IFolder) {
+            path = ((IFolder) fResource).getFullPath();
+        }
+
+        /* We can get a list of available outputs once the analysis is instantiated when the trace is opened */
+        ITmfProjectModelElement parent = getParent();
+        if (parent instanceof TmfTraceElement) {
+            ITmfTrace trace = ((TmfTraceElement) parent).getTrace();
+            if (trace == null) {
+                return list;
+            }
+
+            IAnalysisModule module = trace.getAnalysisModule(fAnalysisId);
+            if (module == null) {
+                return list;
+            }
+
+            for (IAnalysisOutput output : module.getOutputs()) {
+                if (fResource instanceof IFolder) {
+                    IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path.append(output.getName()));
+                    TmfAnalysisOutputElement out = new TmfAnalysisOutputElement(output.getName(), newresource, this, output);
+                    list.add(out);
+                }
+            }
+        }
+        return list;
+    }
+
+    @Override
+    public TmfProjectElement getProject() {
+        return getParent().getProject();
+    }
+
+    /**
+     * Gets the analysis id of this module
+     *
+     * @return The analysis id
+     */
+    public String getAnalysisId() {
+        return fAnalysisId;
+    }
+
+    /**
+     * Gets the help message for this analysis
+     *
+     * @return The help message
+     */
+    public String getHelpMessage() {
+        IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId);
+        if (helper == null) {
+            return new String();
+        }
+
+        return helper.getHelpText();
+    }
+
+    /**
+     * Gets the icon file name for the analysis
+     *
+     * @return The analysis icon file name
+     */
+    public String getIconFile() {
+        IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId);
+        if (helper == null) {
+            return null;
+        }
+        return helper.getIcon();
+    }
+
+    /**
+     * Gets the bundle this analysis is from
+     *
+     * @return The analysis bundle
+     */
+    public Bundle getBundle() {
+        IAnalysisModuleHelper helper = TmfAnalysisManager.getAnalysisModule(fAnalysisId);
+        if (helper == null) {
+            return null;
+        }
+        return helper.getBundle();
+    }
+
+    /**
+     * Make sure the trace this analysis is associated to is the currently selected one
+     */
+    public void activateParent() {
+        ITmfProjectModelElement parent = getParent();
+
+        if (parent instanceof TmfTraceElement) {
+            TmfTraceElement traceElement = (TmfTraceElement) parent;
+            TmfOpenTraceHelper.openTraceFromElement(traceElement);
+        }
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfAnalysisOutputElement.java
new file mode 100644 (file)
index 0000000..ad2154f
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Geneviève Bastien - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.project.model;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisOutput;
+import org.eclipse.linuxtools.tmf.ui.analysis.TmfAnalysisViewOutput;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.views.IViewDescriptor;
+
+/**
+ * Class for project elements of type analysis output
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfAnalysisOutputElement extends TmfProjectModelElement {
+
+    private final IAnalysisOutput fOutput;
+
+    /**
+     * Constructor
+     *
+     * @param name
+     *            Name of the view
+     * @param resource
+     *            Resource for the view
+     * @param parent
+     *            Parent analysis of the view
+     * @param output
+     *            The output object
+     */
+    protected TmfAnalysisOutputElement(String name, IResource resource, ITmfProjectModelElement parent, IAnalysisOutput output) {
+        super(name, resource, parent);
+        fOutput = output;
+    }
+
+    @Override
+    public TmfProjectElement getProject() {
+        return getParent().getProject();
+    }
+
+    /**
+     * Gets the icon of the view, if applicable
+     *
+     * @return The view icon or null if output is not a view
+     */
+    public Image getIcon() {
+        if (fOutput instanceof TmfAnalysisViewOutput) {
+            IViewDescriptor descr = PlatformUI.getWorkbench().getViewRegistry().find(
+                    ((TmfAnalysisViewOutput) fOutput).getViewId());
+            if (descr != null) {
+                return descr.getImageDescriptor().createImage();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Outputs the analysis
+     */
+    public void outputAnalysis() {
+        ITmfProjectModelElement parent = getParent();
+        if (parent instanceof TmfAnalysisElement) {
+            ((TmfAnalysisElement) parent).activateParent();
+            fOutput.requestOutput();
+        }
+    }
+
+}
index 5e8074a9ba7c1b9e30fdf8dc38723f8a4485f542..add5be9aab73791a4ed51821373b0af3a7de0160 100644 (file)
@@ -312,4 +312,21 @@ public class TmfExperimentElement extends TmfWithFolderElement implements IPrope
             }
         }
     }
+
+    /**
+     * Get the list of analysis elements
+     *
+     * @return Array of analysis elements
+     * @since 3.0
+     */
+    public List<TmfAnalysisElement> getAvailableAnalysis() {
+        List<TmfAnalysisElement> list = new ArrayList<TmfAnalysisElement>();
+
+        /**
+         * TODO : implement this cleanly and test it when experiment types are
+         * available
+         */
+
+        return list;
+    }
 }
index 296037a67fe7838fdef1dd6781eba430ceebf555..afdf7af31d1bd3ef83f9e9a819ded45df1beb9f0 100644 (file)
@@ -86,17 +86,9 @@ public class TmfNavigatorContentProvider implements IPipelinedTreeContentProvide
             IProject project = (IProject) element;
             return project.isAccessible();
         }
-        if (element instanceof TmfTraceFolder) {
-            TmfTraceFolder folder = (TmfTraceFolder) element;
-            return folder.hasChildren();
-        }
-        if (element instanceof TmfExperimentFolder) {
-            TmfExperimentFolder folder = (TmfExperimentFolder) element;
-            return folder.hasChildren();
-        }
-        if (element instanceof TmfExperimentElement) {
-            TmfExperimentElement folder = (TmfExperimentElement) element;
-            return folder.hasChildren();
+        if (element instanceof TmfProjectModelElement) {
+            TmfProjectModelElement modelElement = (TmfProjectModelElement) element;
+            return modelElement.hasChildren();
         }
         return false;
     }
@@ -148,6 +140,16 @@ public class TmfNavigatorContentProvider implements IPipelinedTreeContentProvide
             return getExperimentChildren((TmfExperimentElement) parentElement);
         }
 
+        // Traces
+        if (parentElement instanceof TmfTraceElement) {
+            return getTraceChildren((TmfTraceElement) parentElement);
+        }
+
+        // Analysis
+        if (parentElement instanceof TmfAnalysisElement) {
+            return getAnalysisChildren((TmfAnalysisElement) parentElement);
+        }
+
         return new Object[0];
     }
 
@@ -232,6 +234,7 @@ public class TmfNavigatorContentProvider implements IPipelinedTreeContentProvide
                 }
                 children.add(trace);
                 childrenMap.remove(name);
+                getTraceChildren((TmfTraceElement) trace);
             }
         } catch (CoreException e) {
         }
@@ -315,6 +318,32 @@ public class TmfNavigatorContentProvider implements IPipelinedTreeContentProvide
         // project)
         cleanupModel(tmfExperiment, childrenMap);
 
+        for (TmfAnalysisElement analysis : tmfExperiment.getAvailableAnalysis()) {
+            children.add(analysis);
+        }
+
+        return children.toArray();
+    }
+
+    private static Object[] getTraceChildren(TmfTraceElement parentElement) {
+        // The children structure
+        List<Object> children = new ArrayList<Object>();
+
+        for (TmfAnalysisElement analysis : parentElement.getAvailableAnalysis()) {
+            children.add(analysis);
+        }
+
+        return children.toArray();
+    }
+
+    private static Object[] getAnalysisChildren(TmfAnalysisElement parentElement) {
+        // The children structure
+        List<Object> children = new ArrayList<Object>();
+
+        for (TmfAnalysisOutputElement output : parentElement.getAvailableOutputs()) {
+            children.add(output);
+        }
+
         return children.toArray();
     }
 
index a420a41e76382a243f4364f5f558e63b8c82f356..960661e856edea4ff3780769f32a061e3c9a2537 100644 (file)
@@ -45,6 +45,8 @@ public class TmfNavigatorLabelProvider implements ICommonLabelProvider {
     private static final String fTraceIconFile = "icons/elcl16/trace.gif"; //$NON-NLS-1$
     private static final String fUnknownIconFile = "icons/elcl16/unknown_parser.gif"; //$NON-NLS-1$
     private static final String fExperimentIconFile = "icons/elcl16/experiment.gif"; //$NON-NLS-1$
+    private static final String fAnalysisIconFile = "icons/ovr16/experiment_folder_ovr.png"; //$NON-NLS-1$
+    private static final String fViewIconFile = "icons/obj16/node_obj.gif"; //$NON-NLS-1$
 
     // ------------------------------------------------------------------------
     // Attributes
@@ -56,6 +58,8 @@ public class TmfNavigatorLabelProvider implements ICommonLabelProvider {
     private final Image fDefaultTraceIcon;
     private final Image fUnknownTraceIcon;
     private final Image fExperimentIcon;
+    private final Image fDefaultAnalysisIcon;
+    private final Image fDefaultViewIcon;
 
     // ------------------------------------------------------------------------
     // Constructors
@@ -71,6 +75,8 @@ public class TmfNavigatorLabelProvider implements ICommonLabelProvider {
         fDefaultTraceIcon = loadIcon(bundle, fTraceIconFile);
         fUnknownTraceIcon = loadIcon(bundle, fUnknownIconFile);
         fExperimentIcon = loadIcon(bundle, fExperimentIconFile);
+        fDefaultAnalysisIcon = loadIcon(bundle, fAnalysisIconFile);
+        fDefaultViewIcon = loadIcon(bundle, fViewIconFile);
     }
 
     private static Image loadIcon(Bundle bundle, String url) {
@@ -130,6 +136,28 @@ public class TmfNavigatorLabelProvider implements ICommonLabelProvider {
             return fTraceFolderIcon;
         }
 
+        if (element instanceof TmfAnalysisOutputElement) {
+            TmfAnalysisOutputElement output = (TmfAnalysisOutputElement) element;
+            Image icon = output.getIcon();
+            if (icon == null) {
+                return fDefaultViewIcon;
+            }
+            return icon;
+        }
+
+        if (element instanceof TmfAnalysisElement) {
+            TmfAnalysisElement analysis = (TmfAnalysisElement) element;
+            String iconFile = analysis.getIconFile();
+            if (iconFile != null) {
+                Bundle bundle = analysis.getBundle();
+                if (bundle != null) {
+                    Image icon = loadIcon(bundle, iconFile);
+                    return icon;
+                }
+            }
+            return fDefaultAnalysisIcon;
+        }
+
         return null;
     }
 
index 6fea774ca16cfcae0d6ae8791b7c8d88fb34020d..1f17f243dc27014e2c11b709763654e58e7ed200 100644 (file)
@@ -20,15 +20,19 @@ package org.eclipse.linuxtools.tmf.ui.project.model;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtEvent;
@@ -38,7 +42,12 @@ import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlEvent;
 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTrace;
 import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition;
 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
+import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
+import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties;
 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
@@ -177,6 +186,7 @@ public class TmfTraceElement extends TmfWithFolderElement implements IActionFilt
         super(name, trace, parent);
         parent.addChild(this);
         refreshTraceType();
+        TmfSignalManager.register(this);
     }
 
     // ------------------------------------------------------------------------
@@ -198,6 +208,7 @@ public class TmfTraceElement extends TmfWithFolderElement implements IActionFilt
     public void refreshTraceType() {
         try {
             fTraceTypeId = getResource().getPersistentProperty(TmfCommonConstants.TRACETYPE);
+            refreshAnalysis();
         } catch (CoreException e) {
             Activator.getDefault().logError("Error refreshing trace type pesistent property for trace " + getName(), e); //$NON-NLS-1$
         }
@@ -591,4 +602,84 @@ public class TmfTraceElement extends TmfWithFolderElement implements IActionFilt
         }
         return null;
     }
+
+    private void refreshAnalysis() {
+        List<TmfAnalysisElement> list = getAvailableAnalysis();
+
+        /* Remove children */
+        getChildren().clear();
+
+        /* Add the children again */
+        for (TmfAnalysisElement module : list) {
+            addChild(module);
+        }
+
+    }
+
+    /**
+     * Get the list of analysis elements
+     *
+     * @return Array of analysis elements
+     * @since 3.0
+     */
+    public List<TmfAnalysisElement> getAvailableAnalysis() {
+        List<TmfAnalysisElement> list = new ArrayList<TmfAnalysisElement>();
+
+        TraceTypeHelper helper = TmfTraceType.getInstance().getTraceType(getTraceType());
+
+        Class<? extends ITmfTrace> traceClass = null;
+
+        if (helper == null && fTraceTypeId != null) {
+            if (fTraceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName())) {
+                for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
+                    if (fTraceTypeId.equals(CustomTxtTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
+                        traceClass = CustomTxtTrace.class;
+                    }
+                }
+            }
+            if (fTraceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName())) {
+                for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
+                    if (fTraceTypeId.equals(CustomXmlTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
+                        traceClass = CustomTxtTrace.class;
+                    }
+                }
+            }
+        } else if (helper != null) {
+            traceClass = helper.getTraceClass();
+        }
+
+        if (traceClass == null) {
+            return list;
+        }
+
+        /** Get the base path to put the resource to */
+        IPath path = fResource.getFullPath();
+
+        for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules(traceClass).values()) {
+
+            /** No need for the resource to exist, nothing will be done with it */
+            IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(path.append(module.getId()));
+
+            TmfAnalysisElement analysis = new TmfAnalysisElement(module.getName(), newresource, this, module.getId());
+            list.add(analysis);
+        }
+
+        return list;
+    }
+
+    /**
+     * Handler for the Trace Opened signal
+     *
+     * @param signal
+     *            The incoming signal
+     */
+    @TmfSignalHandler
+    public void traceOpened(TmfTraceOpenedSignal signal) {
+        if (!signal.getTrace().getResource().equals(getResource())) {
+            return;
+        }
+
+        refreshAnalysis();
+        getParent().refresh();
+    }
 }
index ea48fcf9012d91c6faf369dae9bc5100b19bb7a4..b1219623768608ca0000b4227fa8e9947b41819a 100644 (file)
@@ -106,6 +106,16 @@ public class TraceTypeHelper {
         return valid;
     }
 
+    /**
+     * Get the class associated with this trace type
+     *
+     * @return The trace class
+     * @since 3.0
+     */
+    public Class<? extends ITmfTrace> getTraceClass() {
+        return fTrace.getClass();
+    }
+
     @Override
     public String toString() {
         return fName;
index 51325d69f45a4019e50ce16dee73e42229e3d389..ecf75e985266ba3796d14936ea34f6e5f3f6008c 100644 (file)
@@ -11,6 +11,9 @@
 ###############################################################################
 
 # Environment properties dialog
+TmfAnalysisElement_InstantiateAnalysis=Instantiate analysis
+TmfAnalysisViewOutput_ViewUnavailable=\ (view unavailable)
+TmfAnalysisViewOutput_Title=Open analysis output
 TmfTraceElement_ResourceProperties = Resource properties
 TmfTraceElement_TraceProperties = Trace properties
 TmfTraceElement_Name = name
@@ -30,4 +33,4 @@ TmfOpenTraceHelper_ReduceError=Something went wrong
 TmfOpenTraceHelper_NoTraceType=No trace type associated to that trace\nPlease select a valid type
 TmfOpenTraceHelper_ErrorTrace=Error opening trace.
 TmfOpenTraceHelper_ErrorExperiment=Error opening experiment.
-TmfOpenTraceHelper_InitError = Error initializing trace.
\ No newline at end of file
+TmfOpenTraceHelper_InitError = Error initializing trace.
This page took 0.095906 seconds and 5 git commands to generate.