Commit | Line | Data |
---|---|---|
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 | 13 | package org.eclipse.tracecompass.tmf.core.analysis; |
c068a752 | 14 | |
5db5a3a4 AM |
15 | import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
16 | ||
c068a752 | 17 | import java.util.ArrayList; |
55d8eb5e | 18 | import java.util.Collections; |
c068a752 GB |
19 | import java.util.HashMap; |
20 | import java.util.List; | |
21 | import java.util.Map; | |
55d8eb5e | 22 | import java.util.Set; |
c068a752 | 23 | |
ba27dd38 | 24 | import org.eclipse.jdt.annotation.NonNullByDefault; |
9897c39c | 25 | import org.eclipse.tracecompass.common.core.NonNullUtils; |
2bdf0193 AM |
26 | import org.eclipse.tracecompass.internal.tmf.core.Activator; |
27 | import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisModuleSources; | |
55d8eb5e | 28 | import org.eclipse.tracecompass.internal.tmf.core.analysis.TmfAnalysisParameterProviders; |
2bdf0193 | 29 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
c068a752 | 30 | |
9897c39c | 31 | import com.google.common.collect.HashMultimap; |
5db5a3a4 | 32 | import com.google.common.collect.ImmutableMap; |
9897c39c GB |
33 | import com.google.common.collect.ImmutableMultimap; |
34 | import 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 |
43 | public class TmfAnalysisManager { |
44 | ||
df2597e0 | 45 | private static final Multimap<String, IAnalysisModuleHelper> fAnalysisModules = NonNullUtils.checkNotNull(HashMultimap.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 | } | |
4c4e2816 | 219 | if (provider.appliesToTrace(trace)) { |
55d8eb5e | 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 | } |