1
2
3
4
5
6
7
8
9
10
11
12
13
14 package com.addthis.codec.plugins;
15
16 import javax.annotation.Nonnull;
17
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Set;
22
23 import com.google.common.annotations.Beta;
24 import com.google.common.base.Objects;
25 import com.google.common.collect.BiMap;
26 import com.google.common.collect.HashBiMap;
27 import com.google.common.collect.Maps;
28
29 import com.typesafe.config.Config;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 @Beta
35 public class PluginRegistry {
36
37 private static final Logger log = LoggerFactory.getLogger(PluginRegistry.class);
38
39 public static final String PLUGIN_DEFAULTS_PATH = "addthis.codec.plugins.defaults";
40 public static final String PLUGINS_PATH_PATH = "addthis.codec.plugins.path";
41
42 public static PluginRegistry defaultRegistry() {
43 return DefaultRegistry.DEFAULT;
44 }
45
46 @Nonnull private final Map<String, PluginMap> pluginMapsByCategory;
47 @Nonnull private final BiMap<Class<?>, PluginMap> pluginMapsByClass;
48 @Nonnull private final Config config;
49
50 public PluginRegistry(@Nonnull Config config) {
51 this.config = config;
52 Config defaultPluginMapSettings = config.getConfig(PLUGIN_DEFAULTS_PATH);
53 String pluginPath = config.getString(PLUGINS_PATH_PATH);
54 Config pluginConfigs = config.getConfig(pluginPath);
55
56 Set<String> categories = pluginConfigs.root().keySet();
57 Map<String, PluginMap> mapsFromConfig = new HashMap<>(categories.size());
58 BiMap<Class<?>, PluginMap> mapsFromConfigByClass = HashBiMap.create(categories.size());
59 for (String category : categories) {
60 Config pluginConfig = pluginConfigs.getConfig(category)
61 .withFallback(defaultPluginMapSettings);
62 PluginMap pluginMap = new PluginMap(category, pluginConfig);
63 mapsFromConfig.put(category, pluginMap);
64 if (pluginMap.baseClass() != null) {
65 mapsFromConfigByClass.put(pluginMap.baseClass(), pluginMap);
66 }
67 }
68 pluginMapsByCategory = Collections.unmodifiableMap(mapsFromConfig);
69 pluginMapsByClass = Maps.unmodifiableBiMap(mapsFromConfigByClass);
70 }
71
72
73 private PluginRegistry(@Nonnull Config config,
74 @Nonnull Map<String, PluginMap> pluginMapsByCategory,
75 @Nonnull BiMap<Class<?>, PluginMap> pluginMapsByClass) {
76 this.config = config;
77 this.pluginMapsByCategory = pluginMapsByCategory;
78 this.pluginMapsByClass = pluginMapsByClass;
79 }
80
81
82
83
84
85
86 public PluginRegistry withOverrides(Config overrides) {
87 Config newConfig = overrides.withFallback(config);
88 String pluginPath = config.getString(PLUGINS_PATH_PATH);
89 if (overrides.hasPath(PLUGIN_DEFAULTS_PATH)
90 || overrides.hasPath(PLUGINS_PATH_PATH)
91 || overrides.hasPath(pluginPath)) {
92 return new PluginRegistry(newConfig);
93 } else {
94 return new PluginRegistry(newConfig, pluginMapsByCategory, pluginMapsByClass);
95 }
96 }
97
98 public Config config() {
99 return config;
100 }
101
102 public Map<String, PluginMap> asMap() {
103 return pluginMapsByCategory;
104 }
105
106 public Map<String, PluginMap> byCategory() {
107 return pluginMapsByCategory;
108 }
109
110 public Map<Class<?>, PluginMap> byClass() {
111 return pluginMapsByClass;
112 }
113
114 @Override public String toString() {
115 return Objects.toStringHelper(this)
116 .add("config.origin", config.origin())
117 .add("pluginMapsByCategory", pluginMapsByCategory)
118 .add("pluginMapsByClass", pluginMapsByClass)
119 .toString();
120 }
121 }