1 /*******************************************************************************
2 * Copyright (c) 2016 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
9 *******************************************************************************/
11 package org
.eclipse
.tracecompass
.tmf
.ui
.symbols
;
13 import java
.lang
.ref
.WeakReference
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Comparator
;
16 import java
.util
.List
;
18 import java
.util
.WeakHashMap
;
20 import org
.eclipse
.core
.runtime
.CoreException
;
21 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
22 import org
.eclipse
.core
.runtime
.Platform
;
23 import org
.eclipse
.jdt
.annotation
.NonNull
;
24 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
28 * This class offer services around the
29 * <code>org.eclipse.tracecompass.tmf.ui.symbolProvider</code> extension point.
35 public final class SymbolProviderManager
{
38 * The singleton instance of this manager
40 private static SymbolProviderManager INSTANCE
;
42 private static final String EXTENSION_POINT_ID
= "org.eclipse.tracecompass.tmf.ui.symbolProvider"; //$NON-NLS-1$
43 private static final String ELEM_NAME_PROVIDER
= "providerFactory"; //$NON-NLS-1$
44 private static final String ATTR_CLASS
= "class"; //$NON-NLS-1$
45 private static final String ATTR_PRIORITY
= "priority"; //$NON-NLS-1$
47 private final List
<SymbolProviderFactoryWrapper
> fProviders
;
49 private final Map
<ITmfTrace
, WeakReference
<ISymbolProvider
>> fInstances
= new WeakHashMap
<>();
52 * Internal class used to store extension point information
55 private static class SymbolProviderFactoryWrapper
{
57 public final ISymbolProviderFactory factory
;
58 public final int priority
;
60 private SymbolProviderFactoryWrapper(ISymbolProviderFactory factory
, int priority
) {
61 this.factory
= factory
;
62 this.priority
= priority
;
70 * @return the singleton instance of this class
72 @SuppressWarnings("null")
73 public static synchronized @NonNull SymbolProviderManager
getInstance() {
74 if (INSTANCE
== null) {
75 INSTANCE
= new SymbolProviderManager();
81 * The private constructor of this manager
83 private SymbolProviderManager() {
84 fProviders
= new ArrayList
<>();
85 IConfigurationElement
[] configElements
= Platform
.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID
);
86 for (IConfigurationElement element
: configElements
) {
87 if (ELEM_NAME_PROVIDER
.equals(element
.getName())) {
89 Object extension
= element
.createExecutableExtension(ATTR_CLASS
);
92 priority
= Integer
.parseInt(element
.getAttribute(ATTR_PRIORITY
));
93 } catch (NumberFormatException e
) {
96 fProviders
.add(new SymbolProviderFactoryWrapper((ISymbolProviderFactory
) extension
, priority
));
97 } catch (CoreException
| ClassCastException e
) {
98 Activator
.getDefault().logError("Exception while loading extensions", e
); //$NON-NLS-1$
102 // Those with a higher priority need to be on top
103 fProviders
.sort(Comparator
.comparingLong(o
-> -o
.priority
));
107 * Locate an {@link ISymbolProvider} capable to resolve symbols from the
108 * given trace. If no such provider is defined an instance of
109 * {@link DefaultSymbolProvider} will be returned
112 * The trace to create a provider for
113 * @return a valid {@link ISymbolProvider}, never null
115 public @NonNull ISymbolProvider
getSymbolProvider(@NonNull ITmfTrace trace
) {
116 // Check to see if we already have a provider for this trace
117 synchronized (fInstances
) {
118 WeakReference
<ISymbolProvider
> reference
= fInstances
.get(trace
);
119 if (reference
!= null) {
120 ISymbolProvider provider
= reference
.get();
121 if (provider
!= null) {
125 // we don't have yet an instance, build one
126 for (SymbolProviderFactoryWrapper wrapper
: fProviders
) {
127 ISymbolProviderFactory factory
= wrapper
.factory
;
128 ISymbolProvider provider
= factory
.createProvider(trace
);
129 if (provider
!= null) {
130 fInstances
.put(trace
, new WeakReference
<>(provider
));
135 // No provider found, return the default one
136 return new DefaultSymbolProvider(trace
);