* 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>
bin.includes = META-INF/,\
.,\
plugin.properties,\
- testfiles/
+ testfiles/,\
+ plugin.xml
src.includes = about.html
--- /dev/null
+<?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>
@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,
--- /dev/null
+/*******************************************************************************
+ * 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 {
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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));
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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
+ */
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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));
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
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",
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,
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
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>
--- /dev/null
+<?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'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 <samp>IAnalysisModule</samp> 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>
+ <p>
+For an example implementation of an analysis module see:
+<pre>
+plug-in: org.eclipse.linuxtools.tmf.core.tests
+package: org.eclipse.linuxtools.tmf.core.tests.stubs.analysis
+class: TestCtfAnalysis
+</pre>
+</p>
+
+<p>
+The following is an example of the extension point:
+<pre>
+<extension
+ point="org.eclipse.linuxtools.tmf.core.analysis">
+ <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">
+ </module>
+ </extension>
+</pre>
+</p>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ <p>
+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's, the analysis' execution, cancellation, completion, the help texts, etc.
+</p>
+<p>
+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.
+</p>
+ </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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+ </documentation>
+ </annotation>
+
+</schema>
--- /dev/null
+/*******************************************************************************
+ * 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));
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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();
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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() {
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+
+ }
+
+}
--- /dev/null
+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}"
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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$
+ }
+}
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;
*/
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
// ------------------------------------------------------------------------
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;
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;
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$
// ------------------------------------------------------------------------
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
*/
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);
}
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>
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 {
--- /dev/null
+/*******************************************************************************
+ * 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);
+
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+}
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;
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;
/**
* Creates objects used for this package's testing purposes
+ *
+ * @author Geneviève Bastien
*/
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);
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);
*
* @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) {
}
/* Finally, delete the experiment */
- resource.delete(true, null);
+ try {
+ resource.delete(true, null);
+ } catch (CoreException e) {
+ Activator.getDefault().logError("Error deleting experiment element", e);
+ }
}
}
}
/* 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);
+ }
}
/**
/**
* Test suite for the TmfTraceElement class.
+ *
+ * @author Geneviève Bastien
*/
public class ProjectModelTraceTest {
*/
@After
public void cleanUp() {
- try {
- ProjectModelTestData.deleteProject(fixture);
- } catch (CoreException e) {
- fail(e.getMessage());
- }
+ ProjectModelTestData.deleteProject(fixture);
}
/**
TmfOpenTraceHelper.openTraceFromElement(traceElement);
/* Give the trace a chance to open */
- ProjectModelTestData.delayThread(5000);
+ ProjectModelTestData.delayThread(500);
trace = traceElement.getTrace();
assertNotNull(trace);
* the exact same element as the active trace
*/
TmfOpenTraceHelper.openTraceFromElement(traceElement);
- ProjectModelTestData.delayThread(5000);
+ ProjectModelTestData.delayThread(500);
ITmfTrace trace2 = TmfTraceManager.getInstance().getActiveTrace();
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
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,
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
<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">
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);
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;
/**
* <b><u>OpenAction</u></b>
- * <p>
- * Implement me. Please.
- * <p>
*/
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;
}
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;
--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+ });
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
SynchronizeTracesHandler_ErrorSynchingExperiment=Error synchronizing experiment %s
SynchronizeTracesHandler_ErrorSynchingForTrace=Error synchronizing experiment %s for trace %s
+
+# Analysis modules
+AnalysisModule_Help=Help
--- /dev/null
+/*******************************************************************************
+ * 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$
+ }
+ }
+ });
+ }
+}
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;
/** 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);
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+ }
+
+}
}
}
}
+
+ /**
+ * 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;
+ }
}
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;
}
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];
}
}
children.add(trace);
childrenMap.remove(name);
+ getTraceChildren((TmfTraceElement) trace);
}
} catch (CoreException e) {
}
// 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();
}
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
private final Image fDefaultTraceIcon;
private final Image fUnknownTraceIcon;
private final Image fExperimentIcon;
+ private final Image fDefaultAnalysisIcon;
+ private final Image fDefaultViewIcon;
// ------------------------------------------------------------------------
// Constructors
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) {
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;
}
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;
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;
super(name, trace, parent);
parent.addChild(this);
refreshTraceType();
+ TmfSignalManager.register(this);
}
// ------------------------------------------------------------------------
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$
}
}
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();
+ }
}
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;
###############################################################################
# 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
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.