1 package com.atlassian.plugin.manager;
2
3 import static com.atlassian.plugin.tracker.DefaultPluginModuleTracker.create;
4 import static com.google.common.base.Preconditions.checkNotNull;
5 import static com.google.common.collect.ImmutableList.copyOf;
6
7 import com.atlassian.plugin.ModuleDescriptor;
8 import com.atlassian.plugin.PluginAccessor;
9 import com.atlassian.plugin.event.PluginEventListener;
10 import com.atlassian.plugin.event.PluginEventManager;
11 import com.atlassian.plugin.event.events.PluginDisabledEvent;
12 import com.atlassian.plugin.tracker.PluginModuleTracker;
13
14 import com.google.common.base.Function;
15 import com.google.common.collect.MapMaker;
16
17 import java.util.List;
18 import java.util.concurrent.ConcurrentMap;
19
20
21
22
23
24
25 public final class EnabledModuleCachingPluginAccessor extends ForwardingPluginAccessor implements PluginAccessor
26 {
27 private final PluginEventManager pluginEventManager;
28 private final ConcurrentMap<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>> cache = new MapMaker()
29 .weakKeys().weakValues().makeComputingMap(new PluginModuleTrackerFactory());
30
31 public EnabledModuleCachingPluginAccessor(final PluginAccessor delegate, final PluginEventManager pluginEventManager)
32 {
33 super(delegate);
34 this.pluginEventManager = checkNotNull(pluginEventManager);
35 this.pluginEventManager.register(this);
36 }
37
38 @Override
39 public <D extends ModuleDescriptor<?>> List<D> getEnabledModuleDescriptorsByClass(final Class<D> descriptorClazz)
40 {
41 return copyOf(descriptors(descriptorClazz));
42 }
43
44
45
46
47
48
49
50 @PluginEventListener
51 public void onPluginDisable(PluginDisabledEvent event)
52 {
53 cache.clear();
54 }
55
56
57
58
59 <D> Iterable<D> descriptors(final Class<D> moduleDescriptorClass)
60 {
61 @SuppressWarnings("unchecked")
62 final Iterable<D> descriptors = (Iterable<D>) cache.get(moduleDescriptorClass).getModuleDescriptors();
63 return descriptors;
64 }
65
66 final class PluginModuleTrackerFactory implements Function<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>>
67 {
68 public PluginModuleTracker<Object, ModuleDescriptor<Object>> apply(final Class<ModuleDescriptor<Object>> moduleDescriptorClass)
69 {
70 return create(delegate, pluginEventManager, moduleDescriptorClass);
71 }
72 }
73 }