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