1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.logging.log4j.core.config.plugins.util;
19
20 import org.apache.logging.log4j.Logger;
21 import org.apache.logging.log4j.status.StatusLogger;
22 import org.apache.logging.log4j.util.Strings;
23
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.concurrent.CopyOnWriteArrayList;
30
31
32
33
34 public class PluginManager {
35
36 private static final CopyOnWriteArrayList<String> PACKAGES = new CopyOnWriteArrayList<String>();
37 private static final String LOG4J_PACKAGES = "org.apache.logging.log4j.core";
38
39 private static final Logger LOGGER = StatusLogger.getLogger();
40
41 private Map<String, PluginType<?>> plugins = new HashMap<String, PluginType<?>>();
42 private final String category;
43
44
45
46
47
48
49 public PluginManager(final String category) {
50 this.category = category;
51 }
52
53
54
55
56
57
58
59
60
61 @Deprecated
62
63 public static void main(final String[] args) {
64 System.err.println("ERROR: this tool is superseded by the annotation processor included in log4j-core.");
65 System.err.println("If the annotation processor does not work for you, please see the manual page:");
66 System.err.println("http://logging.apache.org/log4j/2.x/manual/configuration.html#ConfigurationSyntax");
67 System.exit(-1);
68 }
69
70
71
72
73
74
75 public static void addPackage(final String p) {
76 if (Strings.isBlank(p)) {
77 return;
78 }
79 PACKAGES.addIfAbsent(p);
80 }
81
82
83
84
85
86
87 public static void addPackages(final Collection<String> packages) {
88 for (final String pkg : packages) {
89 if (Strings.isNotBlank(pkg)) {
90 PACKAGES.addIfAbsent(pkg);
91 }
92 }
93 }
94
95
96
97
98
99
100
101 public PluginType<?> getPluginType(final String name) {
102 return plugins.get(name.toLowerCase());
103 }
104
105
106
107
108
109
110 public Map<String, PluginType<?>> getPlugins() {
111 return plugins;
112 }
113
114
115
116
117 public void collectPlugins() {
118 collectPlugins(null);
119 }
120
121
122
123
124
125
126
127 public void collectPlugins(final List<String> packages) {
128 final String categoryLowerCase = category.toLowerCase();
129 final Map<String, PluginType<?>> newPlugins = new LinkedHashMap<String, PluginType<?>>();
130
131
132 Map<String, List<PluginType<?>>> builtInPlugins = PluginRegistry.getInstance().loadFromMainClassLoader();
133 if (builtInPlugins.isEmpty()) {
134
135
136 builtInPlugins = PluginRegistry.getInstance().loadFromPackage(LOG4J_PACKAGES);
137 }
138 mergeByName(newPlugins, builtInPlugins.get(categoryLowerCase));
139
140
141 for (final Map<String, List<PluginType<?>>> pluginsByCategory : PluginRegistry.getInstance().getPluginsByCategoryByBundleId().values()) {
142 mergeByName(newPlugins, pluginsByCategory.get(categoryLowerCase));
143 }
144
145
146 for (final String pkg : PACKAGES) {
147 mergeByName(newPlugins, PluginRegistry.getInstance().loadFromPackage(pkg).get(categoryLowerCase));
148 }
149
150 if (packages != null) {
151 for (final String pkg : packages) {
152 mergeByName(newPlugins, PluginRegistry.getInstance().loadFromPackage(pkg).get(categoryLowerCase));
153 }
154 }
155
156 LOGGER.debug("PluginManager '{}' found {} plugins", category, newPlugins.size());
157
158 plugins = newPlugins;
159 }
160
161 private static void mergeByName(final Map<String, PluginType<?>> newPlugins, final List<PluginType<?>> plugins) {
162 if (plugins == null) {
163 return;
164 }
165 for (final PluginType<?> pluginType : plugins) {
166 final String key = pluginType.getKey();
167 final PluginType<?> existing = newPlugins.get(key);
168 if (existing == null) {
169 newPlugins.put(key, pluginType);
170 } else if (!existing.getPluginClass().equals(pluginType.getPluginClass())) {
171 LOGGER.warn("Plugin [{}] is already mapped to {}, ignoring {}",
172 key, existing.getPluginClass(), pluginType.getPluginClass());
173 }
174 }
175 }
176 }