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
;
27 import com
.google
.common
.collect
.ImmutableList
;
30 * This class offer services around the
31 * <code>org.eclipse.tracecompass.tmf.ui.symbolProvider</code> extension point.
37 public final class SymbolProviderManager
{
40 * The singleton instance of this manager
42 private static SymbolProviderManager INSTANCE
;
44 private static final String EXTENSION_POINT_ID
= "org.eclipse.tracecompass.tmf.ui.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
;
71 * Get the instance of the {@link SymbolProviderManager}
72 * @return the singleton instance of this class
74 @SuppressWarnings("null")
75 public static synchronized @NonNull SymbolProviderManager
getInstance() {
76 if (INSTANCE
== null) {
77 List
<@NonNull SymbolProviderFactoryWrapper
> providers
= new ArrayList
<>();
78 IConfigurationElement
[] configElements
= Platform
.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID
);
79 for (IConfigurationElement element
: configElements
) {
80 if (ELEM_NAME_PROVIDER
.equals(element
.getName())) {
82 Object extension
= element
.createExecutableExtension(ATTR_CLASS
);
85 priority
= Integer
.parseInt(element
.getAttribute(ATTR_PRIORITY
));
86 } catch (NumberFormatException e
) {
89 providers
.add(new SymbolProviderFactoryWrapper((ISymbolProviderFactory
) extension
, priority
));
90 } catch (CoreException
| ClassCastException e
) {
91 Activator
.getDefault().logError("Exception while loading extensions", e
); //$NON-NLS-1$
96 * Those with a higher priority need to be on top
98 * Note: we cannot simply sort by negative priority because
99 * (-Long.MIN_VAL) == Long.MIN_VAL
101 providers
.sort(Comparator
.<SymbolProviderFactoryWrapper
> comparingLong(o
-> o
.priority
).reversed());
102 INSTANCE
= new SymbolProviderManager(providers
);
108 * The private constructor of this manager
110 private SymbolProviderManager(@NonNull List
<@NonNull SymbolProviderFactoryWrapper
> providers
) {
111 fProviders
= ImmutableList
.copyOf(providers
);
115 * Locate an {@link ISymbolProvider} capable to resolve symbols from the
116 * given trace. If no such provider is defined an instance of
117 * {@link DefaultSymbolProvider} will be returned
120 * The trace to create a provider for
121 * @return a valid {@link ISymbolProvider}, never null
123 public @NonNull ISymbolProvider
getSymbolProvider(@NonNull ITmfTrace trace
) {
124 // Check to see if we already have a provider for this trace
125 synchronized (fInstances
) {
126 WeakReference
<ISymbolProvider
> reference
= fInstances
.get(trace
);
127 if (reference
!= null) {
128 ISymbolProvider provider
= reference
.get();
129 if (provider
!= null) {
133 // we don't have yet an instance, build one
134 for (SymbolProviderFactoryWrapper wrapper
: fProviders
) {
135 ISymbolProviderFactory factory
= wrapper
.factory
;
136 ISymbolProvider provider
= factory
.createProvider(trace
);
137 if (provider
!= null) {
138 fInstances
.put(trace
, new WeakReference
<>(provider
));
143 // No provider found, return the default one
144 return new DefaultSymbolProvider(trace
);