1 package com.atlassian.plugin.manager;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4 import com.atlassian.plugin.PluginAccessor;
5 import com.atlassian.plugin.event.PluginEventListener;
6 import com.atlassian.plugin.event.PluginEventManager;
7 import com.atlassian.plugin.event.events.PluginDisabledEvent;
8 import com.atlassian.plugin.tracker.PluginModuleTracker;
9 import com.atlassian.plugin.cache.ConcurrentCacheFactory;
10 import com.google.common.base.Function;
11 import com.google.common.cache.Cache;
12 import com.google.common.cache.CacheBuilder;
13 import com.google.common.cache.CacheLoader;
14
15 import java.util.List;
16
17 import static com.atlassian.plugin.tracker.DefaultPluginModuleTracker.create;
18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static com.google.common.collect.ImmutableList.copyOf;
20
21
22
23
24
25
26 public final class EnabledModuleCachingPluginAccessor extends ForwardingPluginAccessor implements PluginAccessor
27 {
28 private final PluginEventManager pluginEventManager;
29 private final Cache<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>> cache;
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 this.cache = new DefaultPluginModuleTrackerCacheFactory().createCache();
37 }
38
39 public EnabledModuleCachingPluginAccessor(final PluginAccessor delegate, final PluginEventManager pluginEventManager, final ConcurrentCacheFactory<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>> pluginModuleTrackerCacheFactory)
40 {
41 super(delegate);
42 this.pluginEventManager = checkNotNull(pluginEventManager);
43 this.pluginEventManager.register(this);
44 this.cache = pluginModuleTrackerCacheFactory.createCache();
45 }
46
47
48 @Override
49 public <D extends ModuleDescriptor<?>> List<D> getEnabledModuleDescriptorsByClass(final Class<D> descriptorClazz)
50 {
51 return copyOf(descriptors(descriptorClazz));
52 }
53
54
55
56
57
58
59
60 @PluginEventListener
61 public void onPluginDisable(PluginDisabledEvent event)
62 {
63 cache.invalidateAll();
64 }
65
66
67
68
69 @SuppressWarnings("unchecked")
70 <D> Iterable<D> descriptors(final Class<D> moduleDescriptorClass)
71 {
72 PluginModuleTracker<Object, ModuleDescriptor<Object>> tracker = cache.getUnchecked((Class<ModuleDescriptor<Object>>) moduleDescriptorClass);
73 return (Iterable<D>) tracker.getModuleDescriptors();
74 }
75
76 private class DefaultPluginModuleTrackerCacheFactory implements ConcurrentCacheFactory<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>>
77 {
78 @Override
79 public Cache<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>> createCache()
80 {
81 return CacheBuilder.newBuilder().weakKeys().weakValues().build(CacheLoader.from(new PluginModuleTrackerFactory()));
82 }
83 }
84
85 private class PluginModuleTrackerFactory implements Function<Class<ModuleDescriptor<Object>>, PluginModuleTracker<Object, ModuleDescriptor<Object>>>
86 {
87 public PluginModuleTracker<Object, ModuleDescriptor<Object>> apply(final Class<ModuleDescriptor<Object>> moduleDescriptorClass)
88 {
89 return create(delegate, pluginEventManager, moduleDescriptorClass);
90 }
91 }
92 }