01f67cafb8098902f5856514e60f8ffcb66079c0
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / symbols / SymbolProviderManager.java
1 /*******************************************************************************
2 * Copyright (c) 2016 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
11 package org.eclipse.tracecompass.tmf.ui.symbols;
12
13 import java.lang.ref.WeakReference;
14 import java.util.ArrayList;
15 import java.util.Comparator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.WeakHashMap;
19
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;
26
27 /**
28 * This class offer services around the
29 * <code>org.eclipse.tracecompass.tmf.ui.symbolProvider</code> extension point.
30 *
31 * @author Robert Kiss
32 * @since 2.0
33 *
34 */
35 public final class SymbolProviderManager {
36
37 /**
38 * The singleton instance of this manager
39 */
40 private static SymbolProviderManager INSTANCE;
41
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$
46
47 private final List<SymbolProviderFactoryWrapper> fProviders;
48
49 private final Map<ITmfTrace, WeakReference<ISymbolProvider>> fInstances = new WeakHashMap<>();
50
51 /**
52 * Internal class used to store extension point information
53 *
54 */
55 private static class SymbolProviderFactoryWrapper {
56
57 public final ISymbolProviderFactory factory;
58 public final int priority;
59
60 private SymbolProviderFactoryWrapper(ISymbolProviderFactory factory, int priority) {
61 this.factory = factory;
62 this.priority = priority;
63
64 }
65
66 }
67
68 /**
69 *
70 * @return the singleton instance of this class
71 */
72 @SuppressWarnings("null")
73 public static synchronized @NonNull SymbolProviderManager getInstance() {
74 if (INSTANCE == null) {
75 INSTANCE = new SymbolProviderManager();
76 }
77 return INSTANCE;
78 }
79
80 /**
81 * The private constructor of this manager
82 */
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())) {
88 try {
89 Object extension = element.createExecutableExtension(ATTR_CLASS);
90 int priority = 0;
91 try {
92 priority = Integer.parseInt(element.getAttribute(ATTR_PRIORITY));
93 } catch (NumberFormatException e) {
94 // safe to ignore
95 }
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$
99 }
100 }
101 }
102 // Those with a higher priority need to be on top
103 fProviders.sort(Comparator.comparingLong(o -> -o.priority));
104 }
105
106 /**
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
110 *
111 * @param trace
112 * The trace to create a provider for
113 * @return a valid {@link ISymbolProvider}, never null
114 */
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) {
122 return provider;
123 }
124 }
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));
131 return provider;
132 }
133 }
134 }
135 // No provider found, return the default one
136 return new DefaultSymbolProvider(trace);
137 }
138
139 }
This page took 0.042093 seconds and 4 git commands to generate.