1 /*******************************************************************************
2 * Copyright (c) 2016-2017 Movidius Inc. and others
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.tmf
.core
.symbols
;
12 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
14 import java
.lang
.ref
.WeakReference
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Comparator
;
17 import java
.util
.List
;
19 import java
.util
.WeakHashMap
;
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
;
29 * This class offer services around the
30 * <code>org.eclipse.tracecompass.tmf.core.symbolProvider</code> extension
36 public final class SymbolProviderManager
{
39 * The singleton instance of this manager
41 private static @Nullable SymbolProviderManager INSTANCE
;
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$
49 private final List
<SymbolProviderFactoryWrapper
> fProviders
;
51 private final Map
<ITmfTrace
, WeakReference
<ISymbolProvider
>> fInstances
= new WeakHashMap
<>();
54 * Internal class used to store extension point information
57 private static class SymbolProviderFactoryWrapper
{
59 public final ISymbolProviderFactory factory
;
60 public final int priority
;
62 private SymbolProviderFactoryWrapper(ISymbolProviderFactory factory
, int priority
) {
63 this.factory
= factory
;
64 this.priority
= priority
;
70 * @return the singleton instance of this class
72 public static synchronized SymbolProviderManager
getInstance() {
73 SymbolProviderManager manager
= INSTANCE
;
74 if (manager
== null) {
75 manager
= new SymbolProviderManager();
82 * The private constructor of this manager
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
));
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())) {
97 Object extension
= checkNotNull(element
.createExecutableExtension(ATTR_CLASS
));
100 priority
= Integer
.parseInt(element
.getAttribute(ATTR_PRIORITY
));
101 } catch (NumberFormatException e
) {
104 fProviders
.add(new SymbolProviderFactoryWrapper((ISymbolProviderFactory
) extension
, priority
));
105 } catch (CoreException
| ClassCastException e
) {
106 Activator
.logError("Exception while loading extensions", e
); //$NON-NLS-1$
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
118 * The trace to create a provider for
119 * @return a valid {@link ISymbolProvider}, never null
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) {
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
));
141 // No provider found, return the default one
142 return new DefaultSymbolProvider(trace
);