Skip to content

Commit c534dc9

Browse files
MatthewKhouzambhufmann
authored andcommitted
tmf.core: Introduce arbitrary/abstract data provider ITmfDataProvider
Add methods in IDataProviderFactory to create provider returning only this new ITmfDataProvider interface. Deprecate existing createProvider methods in IDataProviderFactory. Add new methods to fetch and create data providers implementing ITmfDataProvider interface. Deprecate existing get and create methods for data providers in DataProviderManager. [Added] base data provider ITmfDataProvider interface [Added] IDataProviderFactory.createDataProvider(ITmfTrace) [Added] IDataProviderFactory.createDataProvider(ITmfTrace, String) [Added] DataProviderManager.fetchExistingDataProvider(ITmfTrace, String, Class) [Added] DataProviderManager.fetchOrCreateDataProvider(ITmfTrace, String, Class) [Deprecated] IDataProviderFactory.createProvider(ITmfTrace) [Deprecated] IDataProviderFactory.createProvider(ITmfTrace, String) [Deprecated] DataProviderManager.getExistingDataProvider(ITmfTrace, String, Class) [Deprecated] DataProviderManager.getOrCreateDataProvider(ITmfTrace, String, Class) Change-Id: I8861028af4c368e2bbd610dd10d4b7b20d7a05de Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com> Signed-off-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
1 parent 7cd8fc5 commit c534dc9

5 files changed

Lines changed: 225 additions & 41 deletions

File tree

releng/org.eclipse.tracecompass.integration.core.tests/src/org/eclipse/tracecompass/integration/core/tests/dataproviders/DataProviderManagerTest.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,45 @@ public void test() {
415415
public void testGetter() {
416416
ITmfTrace trace = fKernelTrace;
417417
assertNotNull(trace);
418-
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp = DataProviderManager.getInstance().getExistingDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
419-
assertNull(dp);
420-
dp = DataProviderManager.getInstance().getOrCreateDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
421-
assertNotNull(dp);
422-
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp2 = DataProviderManager.getInstance().getExistingDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
423-
assertNotNull(dp2);
424-
assertTrue(dp == dp2);
425-
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp3 = DataProviderManager.getInstance().getOrCreateDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
426-
assertNotNull(dp3);
427-
assertTrue(dp == dp3);
428-
assertTrue(dp == dp2);
418+
try {
419+
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp = DataProviderManager.getInstance().getExistingDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
420+
assertNull(dp);
421+
dp = DataProviderManager.getInstance().getOrCreateDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
422+
assertNotNull(dp);
423+
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp2 = DataProviderManager.getInstance().getExistingDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
424+
assertNotNull(dp2);
425+
assertTrue(dp == dp2);
426+
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp3 = DataProviderManager.getInstance().getOrCreateDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
427+
assertNotNull(dp3);
428+
assertTrue(dp == dp3);
429+
assertTrue(dp == dp2);
430+
} finally {
431+
DataProviderManager.getInstance().removeDataProvider(trace, CPU_USAGE_DP_ID);
432+
}
433+
}
434+
435+
/**
436+
* Test different get methods
437+
*/
438+
@Test
439+
public void testGetterNew() {
440+
ITmfTrace trace = fKernelTrace;
441+
assertNotNull(trace);
442+
try {
443+
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp = DataProviderManager.getInstance().fetchExistingDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
444+
assertNull(dp);
445+
dp = DataProviderManager.getInstance().fetchOrCreateDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
446+
assertNotNull(dp);
447+
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp2 = DataProviderManager.getInstance().fetchExistingDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
448+
assertNotNull(dp2);
449+
assertTrue(dp == dp2);
450+
ITmfTreeXYDataProvider<@NonNull ITmfTreeDataModel> dp3 = DataProviderManager.getInstance().fetchOrCreateDataProvider(trace, CPU_USAGE_DP_ID, ITmfTreeXYDataProvider.class);
451+
assertNotNull(dp3);
452+
assertTrue(dp == dp3);
453+
assertTrue(dp == dp2);
454+
} finally {
455+
DataProviderManager.getInstance().removeDataProvider(trace, CPU_USAGE_DP_ID);
456+
}
429457
}
430458

431459
/**

tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/DataProviderManager.java

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.eclipse.tracecompass.internal.tmf.core.Activator;
4646
import org.eclipse.tracecompass.tmf.core.component.DataProviderConstants;
4747
import org.eclipse.tracecompass.tmf.core.config.ITmfConfiguration;
48+
import org.eclipse.tracecompass.tmf.core.model.ITmfDataProvider;
4849
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
4950
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
5051
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
@@ -88,7 +89,7 @@ public class DataProviderManager {
8889
private Multimap<String, Pattern> fHideDataProviders = HashMultimap.create();
8990
private Multimap<String, Pattern> fShowDataProviders = HashMultimap.create();
9091

91-
private final Multimap<ITmfTrace, ITmfTreeDataProvider<? extends ITmfTreeDataModel>> fInstances = LinkedHashMultimap.create();
92+
private final Multimap<ITmfTrace, ITmfDataProvider> fInstances = LinkedHashMultimap.create();
9293

9394
/**
9495
* Get the instance of the manager
@@ -219,15 +220,38 @@ private void loadHiddenDataProviders() {
219220
* @return the data provider or null if no data provider is found for the
220221
* input parameter.
221222
* @since 8.0
223+
*
224+
* @deprecated As of version 9.7, use {@link #fetchOrCreateDataProvider(ITmfTrace, String, Class)} instead
222225
*/
226+
@Deprecated(since = "9.7", forRemoval = true)
223227
public synchronized @Nullable <T extends ITmfTreeDataProvider<? extends ITmfTreeDataModel>> T getOrCreateDataProvider(@NonNull ITmfTrace trace, String id, Class<T> dataProviderClass) {
224-
ITmfTreeDataProvider<? extends ITmfTreeDataModel> dataProvider = getExistingDataProvider(trace, id, dataProviderClass);
228+
return fetchOrCreateDataProvider(trace, id, dataProviderClass);
229+
}
230+
231+
/**
232+
* Gets or creates the data provider for the given trace.
233+
* <p>
234+
* This method should never be called from within a
235+
* {@link TmfSignalHandler}.
236+
*
237+
* @param trace
238+
* An instance of {@link ITmfTrace}. Note, that trace can be an
239+
* instance of TmfExperiment, too.
240+
* @param id
241+
* Id of the data provider. This ID can be the concatenation of a
242+
* provider ID + ':' + a secondary ID used to differentiate
243+
* multiple instances of a same provider.
244+
* @param dataProviderClass
245+
* Returned data provider must extend this class
246+
* @return the data provider or null if no data provider is found for the
247+
* input parameter.
248+
* @since 9.7
249+
*/
250+
public synchronized @Nullable <T extends ITmfDataProvider> T fetchOrCreateDataProvider(@NonNull ITmfTrace trace, String id, Class<T> dataProviderClass) {
251+
ITmfDataProvider dataProvider = fetchExistingDataProvider(trace, id, dataProviderClass);
225252
if (dataProvider != null) {
226253
return dataProviderClass.cast(dataProvider);
227254
}
228-
if (isHidden(id, trace)) {
229-
return null;
230-
}
231255
String[] ids = id.split(DataProviderConstants.ID_SEPARATOR, 2);
232256
for (ITmfTrace opened : TmfTraceManager.getInstance().getOpenedTraces()) {
233257
if (TmfTraceManager.getTraceSetWithExperiment(opened).contains(trace)) {
@@ -236,7 +260,7 @@ private void loadHiddenDataProviders() {
236260
*/
237261
IDataProviderFactory providerFactory = fDataProviderFactories.get(ids[0]);
238262
if (providerFactory != null) {
239-
dataProvider = ids.length > 1 ? providerFactory.createProvider(trace, String.valueOf(ids[1])) : providerFactory.createProvider(trace);
263+
dataProvider = ids.length > 1 ? providerFactory.createDataProvider(trace, String.valueOf(ids[1])) : providerFactory.createDataProvider(trace);
240264
if (dataProvider != null && id.equals(dataProvider.getId()) && dataProviderClass.isAssignableFrom(dataProvider.getClass())) {
241265
fInstances.put(trace, dataProvider);
242266
return dataProviderClass.cast(dataProvider);
@@ -268,9 +292,36 @@ private void loadHiddenDataProviders() {
268292
* Returned data provider must extend this class
269293
* @return the data provider or null
270294
* @since 8.0
295+
* @deprecated As of version 9.7, use {@link #fetchExistingDataProvider(ITmfTrace, String, Class)} instead
271296
*/
297+
@Deprecated(since = "9.7", forRemoval = true)
272298
public synchronized @Nullable <T extends ITmfTreeDataProvider<? extends ITmfTreeDataModel>> T getExistingDataProvider(@NonNull ITmfTrace trace, String id, Class<T> dataProviderClass) {
273-
for (ITmfTreeDataProvider<? extends ITmfTreeDataModel> dataProvider : fInstances.get(trace)) {
299+
return fetchExistingDataProvider(trace, id, dataProviderClass);
300+
}
301+
302+
/**
303+
* Get a data provider for the given trace if it already exists due to
304+
* calling {@link #fetchOrCreateDataProvider(ITmfTrace, String, Class)}
305+
* before.
306+
*
307+
* <p>
308+
* This method should never be called from within a
309+
* {@link TmfSignalHandler}.
310+
*
311+
* @param trace
312+
* An instance of {@link ITmfTrace}. Note, that trace can be an
313+
* instance of TmfExperiment, too.
314+
* @param id
315+
* Id of the data provider. This ID can be the concatenation of a
316+
* provider ID + ':' + a secondary ID used to differentiate
317+
* multiple instances of a same provider.
318+
* @param dataProviderClass
319+
* Returned data provider must extend this class
320+
* @return the data provider or null
321+
* @since 9.7
322+
*/
323+
public synchronized @Nullable <T extends ITmfDataProvider> T fetchExistingDataProvider(@NonNull ITmfTrace trace, String id, Class<T> dataProviderClass) {
324+
for (ITmfDataProvider dataProvider : fInstances.get(trace)) {
274325
if (id.equals(dataProvider.getId()) && dataProviderClass.isAssignableFrom(dataProvider.getClass()) && !isHidden(id, trace)) {
275326
return dataProviderClass.cast(dataProvider);
276327
}
@@ -290,7 +341,7 @@ public void traceClosed(final TmfTraceClosedSignal signal) {
290341
new Thread(() -> {
291342
synchronized (DataProviderManager.this) {
292343
for (ITmfTrace trace : TmfTraceManager.getTraceSetWithExperiment(signal.getTrace())) {
293-
fInstances.removeAll(trace).forEach(ITmfTreeDataProvider::dispose);
344+
fInstances.removeAll(trace).forEach(ITmfDataProvider::dispose);
294345
}
295346
}
296347
}).start();
@@ -402,9 +453,9 @@ public <T extends ITmfTreeDataProvider<? extends ITmfTreeDataModel>> boolean rem
402453
* @since 9.7
403454
*/
404455
public void removeDataProvider(ITmfTrace trace, String id) {
405-
Iterator<ITmfTreeDataProvider<? extends ITmfTreeDataModel>> iter = fInstances.get(trace).iterator();
456+
Iterator<ITmfDataProvider> iter = fInstances.get(trace).iterator();
406457
while (iter.hasNext()) {
407-
ITmfTreeDataProvider<? extends ITmfTreeDataModel> dp = iter.next();
458+
ITmfDataProvider dp = iter.next();
408459
if (dp.getId().equals(id)) {
409460
dp.dispose();
410461
iter.remove();
@@ -487,9 +538,9 @@ public synchronized void removeDataProviderFactory(String id) {
487538
private void removeExistingDataProviders(IDataProviderFactory factory, String passedFactoryId) {
488539
if (factory != null) {
489540
for (ITmfTrace trace : fInstances.keySet()) {
490-
Iterator<ITmfTreeDataProvider<? extends ITmfTreeDataModel>> iter = fInstances.get(trace).iterator();
541+
Iterator<ITmfDataProvider> iter = fInstances.get(trace).iterator();
491542
while (iter.hasNext()) {
492-
ITmfTreeDataProvider<? extends ITmfTreeDataModel> dp = iter.next();
543+
ITmfDataProvider dp = iter.next();
493544
String factoryId = extractFactoryId(dp.getId());
494545
if (passedFactoryId.equals(factoryId)) {
495546
dp.dispose();

tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/dataprovider/IDataProviderFactory.java

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Ericsson
2+
* Copyright (c) 2017, 2025 Ericsson
33
*
44
* All rights reserved. This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0 which
@@ -18,6 +18,7 @@
1818
import org.eclipse.jdt.annotation.NonNull;
1919
import org.eclipse.jdt.annotation.Nullable;
2020
import org.eclipse.tracecompass.tmf.core.config.ITmfDataProviderConfigurator;
21+
import org.eclipse.tracecompass.tmf.core.model.ITmfDataProvider;
2122
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
2223
import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
2324
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -40,11 +41,28 @@ public interface IDataProviderFactory extends IAdaptable {
4041
* A trace
4142
* @return {@link ITmfTreeDataProvider} that can be use for the given trace
4243
* @since 4.0
44+
* @deprecated As of version 9.7, use {@link #createDataProvider(ITmfTrace)} instead
4345
*/
44-
@Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace);
46+
@Deprecated(since = "9.7", forRemoval = true)
47+
@Nullable default ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace) {
48+
return null;
49+
}
4550

4651
/**
47-
* Create a {@link ITmfTreeDataProvider} for the given trace. If this factory
52+
* Create a {@link ITmfDataProvider} for the given trace. If this factory
53+
* does not know how to handle the given trace it will return null
54+
*
55+
* @param trace
56+
* A trace
57+
* @return {@link ITmfDataProvider} that can be use for the given trace
58+
* @since 9.7
59+
*/
60+
@Nullable default ITmfDataProvider createDataProvider(@NonNull ITmfTrace trace) {
61+
return createProvider(trace);
62+
}
63+
64+
/**
65+
D * Create a {@link ITmfTreeDataProvider} for the given trace. If this factory
4866
* does not know how to handle the given trace it will return null. The
4967
* resulting provider should have an ID that is an aggregate of the provider's
5068
* own ID and the secondaryId as such: <provider ID>:<secondaryId>
@@ -59,11 +77,34 @@ public interface IDataProviderFactory extends IAdaptable {
5977
* ID <provider ID>:<secondaryId>, or <code>null</code> if no provider
6078
* is available for this trace and ID
6179
* @since 4.0
80+
* @deprecated As of version 9.7, use {@link #createDataProvider(ITmfTrace)} instead
6281
*/
82+
@Deprecated(since = "9.7", forRemoval = true)
6383
default @Nullable ITmfTreeDataProvider<? extends ITmfTreeDataModel> createProvider(@NonNull ITmfTrace trace, @NonNull String secondaryId) {
6484
return createProvider(trace);
6585
}
6686

87+
/**
88+
* Create a {@link ITmfDataProvider} for the given trace. If this factory
89+
* does not know how to handle the given trace it will return null. The
90+
* resulting provider should have an ID that is an aggregate of the provider's
91+
* own ID and the secondaryId as such: <provider ID>:<secondaryId>
92+
*
93+
* @param trace
94+
* A trace
95+
* @param secondaryId
96+
* Additional ID to identify different instances of the same
97+
* provider, for instance, when the same provider can be used for
98+
* different analysis modules
99+
* @return {@link ITmfDataProvider} that can be use for the given trace with
100+
* ID <provider ID>:<secondaryId>, or <code>null</code> if no provider
101+
* is available for this trace and ID
102+
* @since 9.7
103+
*/
104+
default @Nullable ITmfDataProvider createDataProvider(@NonNull ITmfTrace trace, @NonNull String secondaryId) {
105+
return createProvider(trace, secondaryId);
106+
}
107+
67108
/**
68109
* Gets the collection of data provider descriptors for this trace that this
69110
* data provider factory can create, if the trace supports it, else
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**********************************************************************
2+
* Copyright (c) 2025 Ericsson
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License 2.0 which
6+
* accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
**********************************************************************/
11+
12+
package org.eclipse.tracecompass.tmf.core.model;
13+
14+
/**
15+
* Base interface that each data provider has to implement.
16+
*
17+
* Each data provider needs to provide at least one fetch method, that is
18+
* typical for this data provider type and which returns @link TmfModelResponse}
19+
* with a defined serializable model.
20+
*
21+
* <p>
22+
* Example interface:
23+
* <pre>{@code
24+
* public ICustomDataProvider implements ITmfDataProvider {
25+
* TmfModelResponse<CustomModel> fetchCustomData(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor);
26+
* }
27+
* }</pre>
28+
* </p>
29+
* Example implementation:
30+
* <pre>{@code
31+
* public class CustomModel {
32+
* private final String fValue = value;
33+
* public CustomModel(String value) {
34+
* fValue = value;
35+
* }
36+
* String getValue() {
37+
* return fValue;
38+
* }
39+
* }
40+
*
41+
* public class CustomDataProvider implements ICustomDataProvider {
42+
* // ITmfDataProvider
43+
* public String getId() {
44+
* return "customId";
45+
* }
46+
* public void dispose() {}
47+
*
48+
* // ICustomDataProvider
49+
* TmfModelResponse<CustomModel> fetchCustomData(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
50+
* CustomModel model = new CustomModel("my data");
51+
* return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
52+
* }
53+
* }
54+
* }</pre>
55+
*
56+
*
57+
* @since 9.7
58+
* @author Matthew Khouzam
59+
* @auther Bernd Hufmann
60+
*
61+
*/
62+
public interface ITmfDataProvider {
63+
/**
64+
* This method return the extension point ID of this provider
65+
*
66+
* @return The ID
67+
*/
68+
String getId();
69+
70+
/**
71+
* Dispose of the provider to avoid resource leakage.
72+
*/
73+
public default void dispose() {
74+
// Do nothing for now
75+
}
76+
}

tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/model/tree/ITmfTreeDataProvider.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import org.eclipse.core.runtime.IProgressMonitor;
1717
import org.eclipse.jdt.annotation.Nullable;
18+
import org.eclipse.tracecompass.tmf.core.model.ITmfDataProvider;
1819
import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
1920

2021
/**
@@ -26,7 +27,7 @@
2627
* Tree model extending {@link ITmfTreeDataModel}
2728
* @since 4.0
2829
*/
29-
public interface ITmfTreeDataProvider<T extends ITmfTreeDataModel> {
30+
public interface ITmfTreeDataProvider<T extends ITmfTreeDataModel> extends ITmfDataProvider{
3031

3132
/**
3233
* This methods computes a tree model. Then, it returns a
@@ -42,19 +43,6 @@ public interface ITmfTreeDataProvider<T extends ITmfTreeDataModel> {
4243
* @since 5.0
4344
*/
4445
TmfModelResponse<TmfTreeModel<T>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor);
46+
}
4547

46-
/**
47-
* This method return the extension point ID of this provider
48-
*
49-
* @return The ID
50-
*/
51-
String getId();
5248

53-
/**
54-
* Dispose of the provider to avoid resource leakage.
55-
*
56-
* @since 4.0
57-
*/
58-
public default void dispose() {
59-
}
60-
}

0 commit comments

Comments
 (0)