6d17ff15f49168059c006b464872cdb390d7901d
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / symbols / SymbolProviderManager.java
1 /*******************************************************************************
2 * Copyright (c) 2016-2017 Movidius Inc. and others
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10 package org.eclipse.tracecompass.tmf.core.symbols;
11
12 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
13
14 import java.lang.ref.WeakReference;
15 import java.util.ArrayList;
16 import java.util.Comparator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.WeakHashMap;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IConfigurationElement;
23 import org.eclipse.core.runtime.Platform;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.eclipse.tracecompass.internal.tmf.core.Activator;
26 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
27
28 /**
29 * This class offer services around the
30 * <code>org.eclipse.tracecompass.tmf.core.symbolProvider</code> extension
31 * point.
32 *
33 * @author Robert Kiss
34 * @since 2.4
35 */
36 public final class SymbolProviderManager {
37
38 /**
39 * The singleton instance of this manager
40 */
41 private static @Nullable SymbolProviderManager INSTANCE;
42
43 private static final String OLD_EXTENSION_POINT_ID = "org.eclipse.tracecompass.tmf.ui.symbolProvider"; //$NON-NLS-1$
44 private static final String EXTENSION_POINT_ID = "org.eclipse.tracecompass.tmf.core.symbolProvider"; //$NON-NLS-1$
45 private static final String ELEM_NAME_PROVIDER = "providerFactory"; //$NON-NLS-1$
46 private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
47 private static final String ATTR_PRIORITY = "priority"; //$NON-NLS-1$
48
49 private final List<SymbolProviderFactoryWrapper> fProviders;
50
51 private final Map<ITmfTrace, WeakReference<ISymbolProvider>> fInstances = new WeakHashMap<>();
52
53 /**
54 * Internal class used to store extension point information
55 *
56 */
57 private static class SymbolProviderFactoryWrapper {
58
59 public final ISymbolProviderFactory factory;
60 public final int priority;
61
62 private SymbolProviderFactoryWrapper(ISymbolProviderFactory factory, int priority) {
63 this.factory = factory;
64 this.priority = priority;
65 }
66 }
67
68 /**
69 *
70 * @return the singleton instance of this class
71 */
72 public static synchronized SymbolProviderManager getInstance() {
73 SymbolProviderManager manager = INSTANCE;
74 if (manager == null) {
75 manager = new SymbolProviderManager();
76 INSTANCE = manager;
77 }
78 return manager;
79 }
80
81 /**
82 * The private constructor of this manager
83 */
84 private SymbolProviderManager() {
85 fProviders = new ArrayList<>();
86 load(OLD_EXTENSION_POINT_ID);
87 load(EXTENSION_POINT_ID);
88 // Those with a higher priority need to be on top
89 fProviders.sort(Comparator.comparingLong(o -> -o.priority));
90 }
91
92 private void load(String configElemPath) {
93 IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(configElemPath);
94 for (IConfigurationElement element : configElements) {
95 if (element != null && ELEM_NAME_PROVIDER.equals(element.getName())) {
96 try {
97 Object extension = checkNotNull(element.createExecutableExtension(ATTR_CLASS));
98 int priority = 0;
99 try {
100 priority = Integer.parseInt(element.getAttribute(ATTR_PRIORITY));
101 } catch (NumberFormatException e) {
102 // safe to ignore
103 }
104 fProviders.add(new SymbolProviderFactoryWrapper((ISymbolProviderFactory) extension, priority));
105 } catch (CoreException | ClassCastException e) {
106 Activator.logError("Exception while loading extensions", e); //$NON-NLS-1$
107 }
108 }
109 }
110 }
111
112 /**
113 * Locate an {@link ISymbolProvider} capable to resolve symbols from the
114 * given trace. If no such provider is defined an instance of
115 * {@link DefaultSymbolProvider} will be returned
116 *
117 * @param trace
118 * The trace to create a provider for
119 * @return a valid {@link ISymbolProvider}, never null
120 */
121 public ISymbolProvider getSymbolProvider(ITmfTrace trace) {
122 // Check to see if we already have a provider for this trace
123 synchronized (fInstances) {
124 WeakReference<ISymbolProvider> reference = fInstances.get(trace);
125 if (reference != null) {
126 ISymbolProvider provider = reference.get();
127 if (provider != null) {
128 return provider;
129 }
130 }
131 // we don't have yet an instance, build one
132 for (SymbolProviderFactoryWrapper wrapper : fProviders) {
133 ISymbolProviderFactory factory = wrapper.factory;
134 ISymbolProvider provider = factory.createProvider(trace);
135 if (provider != null) {
136 fInstances.put(trace, new WeakReference<>(provider));
137 return provider;
138 }
139 }
140 }
141 // No provider found, return the default one
142 return new DefaultSymbolProvider(trace);
143 }
144
145 }
This page took 0.033316 seconds and 4 git commands to generate.