TMF: Add extension point for parameter providers
authorFrancis Giraldeau <francis.giraldeau@gmail.com>
Wed, 4 Feb 2015 04:28:57 +0000 (23:28 -0500)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Wed, 21 Oct 2015 12:56:15 +0000 (08:56 -0400)
It associates a parameter provider to an analysis. Previous way was to
register the parameter provider in the plugin's Activator, but in case
of lazy
loading of the plugin, it sometimes was not registered.

Change-Id: I409593d23971b41b0efc777b69a4aaa469da9339
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Signed-off-by: Francis Giraldeau <francis.giraldeau@gmail.com>
Reviewed-on: https://git.eclipse.org/r/41120
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.core.tests/plugin.xml
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/AnalysisParameterProviderTest.java
tmf/org.eclipse.tracecompass.tmf.core/schema/org.eclipse.linuxtools.tmf.core.analysis.exsd
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisParameterProviders.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAbstractAnalysisModule.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/TmfAnalysisManager.java

index e91409d034dfe16d528723750bfd63644b419115..ece4ff3c5a91fb5abd5237868b7bf82b5633f625 100644 (file)
                class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub">
          </tracetype>
       </module>
+      <module
+         id="org.eclipse.linuxtools.tmf.core.tests.analysis.testParamProvider"
+         name="Test analysis with param provider"
+         analysis_module="org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis">
+         <parameter
+               name="test">
+         </parameter>
+         <tracetype
+               class="org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub">
+         </tracetype>
+      </module>
+      <parameterProvider
+            class="org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysisParameterProvider">
+         <analysisId
+               id="org.eclipse.linuxtools.tmf.core.tests.analysis.testParamProvider">
+         </analysisId>
+      </parameterProvider>
    </extension>
    <extension
          point="org.eclipse.linuxtools.tmf.core.tracetype">
index f86f1492f6362c05abd7b8798331c091084b113c..26fd92325f8b03c4498fa7dd8b9dc302d90bf123 100644 (file)
@@ -5,18 +5,16 @@
  * 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.tracecompass.tmf.core.tests.analysis;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.util.List;
+import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
@@ -29,7 +27,6 @@ import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis;
 import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysisParameterProvider;
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 
 import com.google.common.collect.Multimap;
@@ -47,13 +44,7 @@ public class AnalysisParameterProviderTest {
         return helpers.get(moduleId).iterator().next();
     }
 
-    /**
-     * Registers the parameter provider
-     */
-    @Before
-    public void setup() {
-        TmfAnalysisManager.registerParameterProvider(AnalysisManagerTest.MODULE_PARAM, TestAnalysisParameterProvider.class);
-    }
+    private static final @NonNull String MODULE_ID = "org.eclipse.linuxtools.tmf.core.tests.analysis.testParamProvider";
 
     /**
      * Cleanup the trace after testing
@@ -70,9 +61,10 @@ public class AnalysisParameterProviderTest {
     public void testProviderTmfTrace() {
         ITmfTrace trace = TmfTestTrace.A_TEST_10K.getTrace();
         /* Make sure the value is set to null */
-        IAnalysisModuleHelper helper = getModuleHelper(AnalysisManagerTest.MODULE_PARAM);
+        IAnalysisModuleHelper helper = getModuleHelper(MODULE_ID);
         assertNotNull(helper);
         IAnalysisModule module = null;
+        IAnalysisModule module2 = null;
         try {
             module = helper.newModule(trace);
             assertNotNull(module);
@@ -80,18 +72,31 @@ public class AnalysisParameterProviderTest {
             assertEquals(10, module.getParameter(TestAnalysis.PARAM_TEST));
 
             /* Change the value of the parameter in the provider */
-            List<IAnalysisParameterProvider> providers = TmfAnalysisManager.getParameterProviders(module, trace);
+            Set<IAnalysisParameterProvider> providers = TmfAnalysisManager.getParameterProvidersForModule(module, trace);
             assertEquals(1, providers.size());
-            TestAnalysisParameterProvider provider = (TestAnalysisParameterProvider) providers.get(0);
+            TestAnalysisParameterProvider provider = (TestAnalysisParameterProvider) providers.iterator().next();
             provider.setValue(5);
             assertEquals(5, module.getParameter(TestAnalysis.PARAM_TEST));
 
+            /* Make sure the parameter provider is the same instance for another module */
+            module2 = helper.newModule(trace);
+            assertNotNull(module2);
+            assertTrue(module != module2);
+
+            providers = TmfAnalysisManager.getParameterProvidersForModule(module2, trace);
+            assertEquals(1, providers.size());
+            TestAnalysisParameterProvider provider2 = (TestAnalysisParameterProvider) providers.iterator().next();
+            assertTrue(provider == provider2);
+
         } catch (TmfAnalysisException e) {
             fail(e.getMessage());
         } finally {
             if (module != null) {
                 module.dispose();
             }
+            if (module2 != null) {
+                module2.dispose();
+            }
         }
     }
 
index cac141633e5843c0bdc7f96c5b62fb137afc557d..9695d50abaa9cea64d85bd762bf23a50f7c9ca59 100644 (file)
@@ -21,6 +21,7 @@
             <element ref="module"/>
             <element ref="source"/>
             <element ref="output"/>
+            <element ref="parameterProvider"/>
          </sequence>
          <attribute name="point" type="string" use="required">
             <annotation>
       </complexType>
    </element>
 
+   <element name="parameterProvider">
+      <annotation>
+         <documentation>
+            Associates a parameter provider class with an analysis ID.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="analysisId"/>
+         </sequence>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The class that contains this analysis parameter provider.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.linuxtools.tmf.core.analysis.IAnalysisParameterProvider"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
    <element name="analysisId">
       <annotation>
          <documentation>
diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisParameterProviders.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/analysis/TmfAnalysisParameterProviders.java
new file mode 100644 (file)
index 0000000..0681f0c
--- /dev/null
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2015 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.core.analysis;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tracecompass.internal.tmf.core.Activator;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisParameterProvider;
+
+/**
+ * Utility class for accessing TMF analysis parameter providers extensions from
+ * the platform's extensions registry and returning the module parameter
+ * providers.
+ *
+ * @author Geneviève Bastien
+ */
+public final class TmfAnalysisParameterProviders {
+
+    /** 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 PARAMETER_PROVIDER_ELEM = "parameterProvider"; //$NON-NLS-1$
+
+    /** Extension point attribute 'class' */
+    public static final String CLASS_ATTR = "class"; //$NON-NLS-1$
+
+    /** Extension point attribute 'id' */
+    public static final String ID_ATTR = "id"; //$NON-NLS-1$
+
+    /**
+     * Extension point element 'analysisId' to associate the output to a single
+     * analysis
+     */
+    public static final String ANALYSIS_ID_ELEM = "analysisId"; //$NON-NLS-1$
+
+    /* Maps a class name to an instance of a parameter provider */
+    private static final Map<String, IAnalysisParameterProvider> fParamProviderInstances = new HashMap<>();
+
+    private TmfAnalysisParameterProviders() {
+
+    }
+
+    /**
+     * Return the analysis parameter providers advertised in the extension
+     * point, and associated with an analysis ID.
+     *
+     * @param analysisId
+     *            Get the parameter providers for an analysis identified by its
+     *            ID
+     * @return Map of analysis ID mapped to parameter provider classes
+     */
+    public static Set<IAnalysisParameterProvider> getParameterProvidersFor(String analysisId) {
+        Set<IAnalysisParameterProvider> providers = new HashSet<>();
+        // Get the parameter provider elements from the extension point
+        IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TMF_ANALYSIS_TYPE_ID);
+        for (IConfigurationElement ce : config) {
+            String elementName = ce.getName();
+            if (elementName.equals(PARAMETER_PROVIDER_ELEM)) {
+                try {
+                    IConfigurationElement[] children = ce.getChildren(ANALYSIS_ID_ELEM);
+                    if (children.length == 0) {
+                        throw new IllegalStateException();
+                    }
+                    String id = children[0].getAttribute(ID_ATTR);
+                    String className = ce.getAttribute(CLASS_ATTR);
+                    if (id == null || className == null) {
+                        continue;
+                    }
+                    if (analysisId.equals(id)) {
+                        if (fParamProviderInstances.containsKey(className)) {
+                            providers.add(fParamProviderInstances.get(className));
+                        } else {
+                            IAnalysisParameterProvider provider = (IAnalysisParameterProvider) ce.createExecutableExtension(CLASS_ATTR);
+                            fParamProviderInstances.put(className, provider);
+                            providers.add(provider);
+                        }
+                    }
+                } catch (InvalidRegistryObjectException | CoreException e) {
+                    Activator.logError("Error creating module parameter provider", e); //$NON-NLS-1$
+                }
+            }
+        }
+        return providers;
+    }
+
+}
index fc1955e852e285b0d172c559080c2736dfe348bc..7502b608981e3374296bb158cba58b499e15ee80 100644 (file)
@@ -17,6 +17,7 @@ import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -59,7 +60,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
     private final Map<String, Object> fParameters = new HashMap<>();
     private final List<String> fParameterNames = new ArrayList<>();
     private final List<IAnalysisOutput> fOutputs = new ArrayList<>();
-    private List<IAnalysisParameterProvider> fParameterProviders = new ArrayList<>();
+    private Set<IAnalysisParameterProvider> fParameterProviders = new HashSet<>();
     private @Nullable Job fJob = null;
 
     private final Object syncObj = new Object();
@@ -130,7 +131,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
         }
 
         /* Get the parameter providers for this trace */
-        fParameterProviders = TmfAnalysisManager.getParameterProviders(this, trace);
+        fParameterProviders = TmfAnalysisManager.getParameterProvidersForModule(this, trace);
         for (IAnalysisParameterProvider provider : fParameterProviders) {
             TmfCoreTracer.traceAnalysis(getId(), trace, "registered to parameter provider " + provider.getName()); //$NON-NLS-1$
             provider.registerModule(this);
index f284f5fff06eab42984387cf040a33c17cd8e1ea..f32e5f1631791bf456e2d35b82938afda6159b0b 100644 (file)
@@ -15,14 +15,17 @@ package org.eclipse.tracecompass.tmf.core.analysis;
 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.tracecompass.common.core.NonNullUtils;
 import org.eclipse.tracecompass.internal.tmf.core.Activator;
 import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisModuleSources;
+import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisParameterProviders;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 
 import com.google.common.collect.HashMultimap;
@@ -168,19 +171,41 @@ public class TmfAnalysisManager {
     }
 
     /**
-     * Get a parameter provider that applies to the requested trace
+     * Get the parameter providers that apply to the requested trace
      *
      * @param module
      *            Analysis module
      * @param trace
      *            The trace
-     * @return A parameter provider if one applies to the trace, null otherwise
+     * @return The set of parameter providers that apply to a trace for this module
+     * @deprecated Use the
+     *             {@link #getParameterProvidersForModule(IAnalysisModule, ITmfTrace)}
+     *             method that returns a set instead.
      */
+    @Deprecated
     public static List<IAnalysisParameterProvider> getParameterProviders(IAnalysisModule module, ITmfTrace trace) {
-        List<IAnalysisParameterProvider> providerList = new ArrayList<>();
+        /* Call the method that returns a set */
+        Set<IAnalysisParameterProvider> providerList = getParameterProvidersForModule(module, trace);
+        return new ArrayList<>(providerList);
+    }
+
+    /**
+     * Get the parameter providers that apply to the requested trace
+     *
+     * @param module
+     *            Analysis module
+     * @param trace
+     *            The trace
+     * @return The set of parameter providers that apply to a trace for this module
+     * @since 2.0
+     */
+    public static Set<IAnalysisParameterProvider> getParameterProvidersForModule(IAnalysisModule module, ITmfTrace trace) {
+        /* First, get the parameter providers from the extension point */
+        Set<IAnalysisParameterProvider> providerSet = TmfAnalysisParameterProviders.getParameterProvidersFor(module.getId());
+        /* Then add any new parameter provider coming from other sources */
         synchronized (fParameterProviders) {
             if (!fParameterProviders.containsKey(module.getId())) {
-                return providerList;
+                return providerSet;
             }
             /* We checked  via containsKey, get() should not return null */
             List<Class<? extends IAnalysisParameterProvider>> parameterProviders = checkNotNull(fParameterProviders.get(module.getId()));
@@ -191,15 +216,15 @@ public class TmfAnalysisManager {
                         provider = providerClass.newInstance();
                         fParamProviderInstances.put(providerClass, provider);
                     }
-                    if (provider.appliesToTrace(trace)) {
-                        providerList.add(provider);
+                    if (provider != null && provider.appliesToTrace(trace)) {
+                        providerSet.add(provider);
                     }
                 } catch (IllegalArgumentException | SecurityException | InstantiationException | IllegalAccessException e) {
                     Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e);
                 }
             }
         }
-        return providerList;
+        return NonNullUtils.checkNotNull(Collections.unmodifiableSet(providerSet));
     }
 
     /**
This page took 0.0326 seconds and 5 git commands to generate.