TMF: Add extension point for parameter providers
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / analysis / TmfAnalysisManager.java
CommitLineData
c068a752 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2013, 2014 École Polytechnique de Montréal
c068a752
GB
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.tmf.core.analysis;
c068a752 14
5db5a3a4
AM
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
c068a752 17import java.util.ArrayList;
55d8eb5e 18import java.util.Collections;
c068a752
GB
19import java.util.HashMap;
20import java.util.List;
21import java.util.Map;
55d8eb5e 22import java.util.Set;
c068a752 23
ba27dd38 24import org.eclipse.jdt.annotation.NonNullByDefault;
9897c39c 25import org.eclipse.tracecompass.common.core.NonNullUtils;
2bdf0193
AM
26import org.eclipse.tracecompass.internal.tmf.core.Activator;
27import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisModuleSources;
55d8eb5e 28import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisParameterProviders;
2bdf0193 29import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
c068a752 30
9897c39c 31import com.google.common.collect.HashMultimap;
5db5a3a4 32import com.google.common.collect.ImmutableMap;
9897c39c
GB
33import com.google.common.collect.ImmutableMultimap;
34import com.google.common.collect.Multimap;
5db5a3a4 35
c068a752
GB
36/**
37 * Manages the available analysis helpers from different sources and their
38 * parameter providers.
39 *
c068a752 40 * @author Geneviève Bastien
c068a752 41 */
ba27dd38 42@NonNullByDefault
c068a752
GB
43public class TmfAnalysisManager {
44
9897c39c 45 private static final Multimap<String, IAnalysisModuleHelper> fAnalysisModules = NonNullUtils.checkNotNull(HashMultimap.<String, IAnalysisModuleHelper> create());
a4524c1b
AM
46 private static final Map<String, List<Class<? extends IAnalysisParameterProvider>>> fParameterProviders = new HashMap<>();
47 private static final Map<Class<? extends IAnalysisParameterProvider>, IAnalysisParameterProvider> fParamProviderInstances = new HashMap<>();
b3b03da0 48 private static final List<IAnalysisModuleSource> fSources = new ArrayList<>();
3a26292f 49 private static final List<ITmfNewAnalysisModuleListener> fListeners = new ArrayList<>();
b3b03da0 50
7eb0d2dc
GB
51 /**
52 * Constructor, not to be used
7eb0d2dc 53 */
9897c39c 54 private TmfAnalysisManager() {
7eb0d2dc
GB
55
56 }
57
b3b03da0
GB
58 /**
59 * Registers a new source of modules
60 *
61 * @param source
62 * A {@link IAnalysisModuleSource} instance
63 */
41ad3673
GB
64 public static synchronized void registerModuleSource(IAnalysisModuleSource source) {
65 fSources.add(source);
66 refreshModules();
b3b03da0
GB
67 }
68
69 /**
b63291e6 70 * Initializes sources and new module listeners from the extension point
b3b03da0 71 */
41ad3673
GB
72 public static synchronized void initialize() {
73 fSources.clear();
74 fListeners.clear();
b63291e6
GB
75 initializeModuleSources();
76 initializeNewModuleListeners();
77 }
78
79 /**
80 * Cleans the module sources list and initialize it from the extension point
81 */
41ad3673
GB
82 private static synchronized void initializeModuleSources() {
83 for (IAnalysisModuleSource source : TmfAnalysisModuleSources.getSources()) {
84 fSources.add(source);
b3b03da0
GB
85 }
86 }
c068a752 87
b63291e6
GB
88 /**
89 * Cleans the new module listeners list and initialize it from the extension
90 * point
91 */
41ad3673
GB
92 private static synchronized void initializeNewModuleListeners() {
93 for (ITmfNewAnalysisModuleListener output : TmfAnalysisModuleOutputs.getOutputListeners()) {
94 fListeners.add(output);
b63291e6
GB
95 }
96 }
97
41ad3673
GB
98 /**
99 * Add a new module listener to the list of listeners
100 *
101 * @param listener
102 * The new module listener
103 */
104 public static synchronized void addNewModuleListener(ITmfNewAnalysisModuleListener listener) {
105 fListeners.add(listener);
106 }
107
c068a752
GB
108 /**
109 * Gets all available analysis module helpers
110 *
111 * This map is read-only
112 *
113 * @return The map of available {@link IAnalysisModuleHelper}
dbc7991d 114 * @since 1.0
c068a752 115 */
9897c39c 116 public static synchronized Multimap<String, IAnalysisModuleHelper> getAnalysisModules() {
41ad3673
GB
117 if (fAnalysisModules.isEmpty()) {
118 for (IAnalysisModuleSource source : fSources) {
119 for (IAnalysisModuleHelper helper : source.getAnalysisModules()) {
120 fAnalysisModules.put(helper.getId(), helper);
b3b03da0 121 }
c068a752
GB
122 }
123 }
9897c39c 124 return checkNotNull(ImmutableMultimap.copyOf(fAnalysisModules));
c068a752
GB
125 }
126
127 /**
9897c39c
GB
128 * Gets all analysis module helpers that apply to a given trace type. For
129 * each analysis ID, only one helper will be returned if more than one
130 * applies.
c068a752
GB
131 *
132 * This map is read-only
133 *
ff7b95a5
GB
134 * TODO: This method is only used to populate the project view in the UI. It
135 * should be deprecated eventually, after some UI rework, so that the trace
136 * type does not drive whether the analysis module applies or not to a
137 * trace, but rather the content of the trace or experiment (once it is
138 * opened)
139 *
c068a752
GB
140 * @param traceclass
141 * The trace class to get modules for
142 * @return The map of available {@link IAnalysisModuleHelper}
143 */
144 public static Map<String, IAnalysisModuleHelper> getAnalysisModules(Class<? extends ITmfTrace> traceclass) {
9897c39c 145 Multimap<String, IAnalysisModuleHelper> allModules = getAnalysisModules();
a4524c1b 146 Map<String, IAnalysisModuleHelper> map = new HashMap<>();
c068a752
GB
147 for (IAnalysisModuleHelper module : allModules.values()) {
148 if (module.appliesToTraceType(traceclass)) {
149 map.put(module.getId(), module);
150 }
151 }
5db5a3a4 152 return checkNotNull(ImmutableMap.copyOf(map));
c068a752
GB
153 }
154
c068a752
GB
155 /**
156 * Register a new parameter provider for an analysis
157 *
158 * @param analysisId
159 * The id of the analysis
160 * @param paramProvider
161 * The class of the parameter provider
162 */
163 public static void registerParameterProvider(String analysisId, Class<? extends IAnalysisParameterProvider> paramProvider) {
164 synchronized (fParameterProviders) {
165 if (!fParameterProviders.containsKey(analysisId)) {
166 fParameterProviders.put(analysisId, new ArrayList<Class<? extends IAnalysisParameterProvider>>());
167 }
202956f1
AM
168 /* We checked via containsKey() above, get() should not return null */
169 checkNotNull(fParameterProviders.get(analysisId)).add(paramProvider);
c068a752
GB
170 }
171 }
172
173 /**
55d8eb5e 174 * Get the parameter providers that apply to the requested trace
c068a752
GB
175 *
176 * @param module
177 * Analysis module
178 * @param trace
179 * The trace
55d8eb5e
FG
180 * @return The set of parameter providers that apply to a trace for this module
181 * @deprecated Use the
182 * {@link #getParameterProvidersForModule(IAnalysisModule, ITmfTrace)}
183 * method that returns a set instead.
c068a752 184 */
55d8eb5e 185 @Deprecated
c068a752 186 public static List<IAnalysisParameterProvider> getParameterProviders(IAnalysisModule module, ITmfTrace trace) {
55d8eb5e
FG
187 /* Call the method that returns a set */
188 Set<IAnalysisParameterProvider> providerList = getParameterProvidersForModule(module, trace);
189 return new ArrayList<>(providerList);
190 }
191
192 /**
193 * Get the parameter providers that apply to the requested trace
194 *
195 * @param module
196 * Analysis module
197 * @param trace
198 * The trace
199 * @return The set of parameter providers that apply to a trace for this module
200 * @since 2.0
201 */
202 public static Set<IAnalysisParameterProvider> getParameterProvidersForModule(IAnalysisModule module, ITmfTrace trace) {
203 /* First, get the parameter providers from the extension point */
204 Set<IAnalysisParameterProvider> providerSet = TmfAnalysisParameterProviders.getParameterProvidersFor(module.getId());
205 /* Then add any new parameter provider coming from other sources */
c068a752
GB
206 synchronized (fParameterProviders) {
207 if (!fParameterProviders.containsKey(module.getId())) {
55d8eb5e 208 return providerSet;
c068a752 209 }
202956f1
AM
210 /* We checked via containsKey, get() should not return null */
211 List<Class<? extends IAnalysisParameterProvider>> parameterProviders = checkNotNull(fParameterProviders.get(module.getId()));
212 for (Class<? extends IAnalysisParameterProvider> providerClass : parameterProviders) {
c068a752
GB
213 try {
214 IAnalysisParameterProvider provider = fParamProviderInstances.get(providerClass);
215 if (provider == null) {
216 provider = providerClass.newInstance();
217 fParamProviderInstances.put(providerClass, provider);
218 }
55d8eb5e
FG
219 if (provider != null && provider.appliesToTrace(trace)) {
220 providerSet.add(provider);
c068a752 221 }
6c66e2a6 222 } catch (IllegalArgumentException | SecurityException | InstantiationException | IllegalAccessException e) {
c068a752
GB
223 Activator.logError(Messages.TmfAnalysisManager_ErrorParameterProvider, e);
224 }
225 }
226 }
55d8eb5e 227 return NonNullUtils.checkNotNull(Collections.unmodifiableSet(providerSet));
c068a752
GB
228 }
229
b3b03da0
GB
230 /**
231 * Clear the list of modules so that next time, it is computed again from
232 * sources
233 */
41ad3673
GB
234 public static synchronized void refreshModules() {
235 fAnalysisModules.clear();
b3b03da0
GB
236 }
237
3a26292f
GB
238 /**
239 * This method should be called when new analysis modules have been created
240 * by module helpers to that the {@link ITmfNewAnalysisModuleListener} can
241 * be executed on the module instance.
242 *
243 * @param module
244 * The newly created analysis module
245 */
41ad3673
GB
246 public static synchronized void analysisModuleCreated(IAnalysisModule module) {
247 for (ITmfNewAnalysisModuleListener listener : fListeners) {
248 listener.moduleCreated(module);
3a26292f
GB
249 }
250 }
251
c068a752 252}
This page took 0.081829 seconds and 5 git commands to generate.