1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.config.composite;
18
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.logging.log4j.Level;
24 import org.apache.logging.log4j.core.Filter;
25 import org.apache.logging.log4j.core.config.AbstractConfiguration;
26 import org.apache.logging.log4j.core.config.Node;
27 import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
28 import org.apache.logging.log4j.core.config.plugins.util.PluginType;
29 import org.apache.logging.log4j.core.filter.CompositeFilter;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class DefaultMergeStrategy implements MergeStrategy {
55
56 private static final String APPENDERS = "appenders";
57 private static final String PROPERTIES = "properties";
58 private static final String LOGGERS = "loggers";
59 private static final String SCRIPTS = "scripts";
60 private static final String FILTERS = "filters";
61 private static final String STATUS = "status";
62 private static final String NAME = "name";
63 private static final String REF = "ref";
64
65
66
67
68
69
70 @Override
71 public void mergeRootProperties(Node rootNode, AbstractConfiguration configuration) {
72 for (Map.Entry<String, String> attribute : configuration.getRootNode().getAttributes().entrySet()) {
73 boolean isFound = false;
74 for (Map.Entry<String, String> targetAttribute : rootNode.getAttributes().entrySet()) {
75 if (targetAttribute.getKey().equalsIgnoreCase(attribute.getKey())) {
76 if (attribute.getKey().equalsIgnoreCase(STATUS)) {
77 Level targetLevel = Level.getLevel(targetAttribute.getValue().toUpperCase());
78 Level sourceLevel = Level.getLevel(attribute.getValue().toUpperCase());
79 if (targetLevel != null && sourceLevel != null) {
80 if (sourceLevel.isLessSpecificThan(targetLevel)) {
81 targetAttribute.setValue(attribute.getValue());
82 }
83 } else
84 if (sourceLevel != null) {
85 targetAttribute.setValue(attribute.getValue());
86 }
87 } else {
88 if (attribute.getKey().equalsIgnoreCase("monitorInterval")) {
89 int sourceInterval = Integer.parseInt(attribute.getValue());
90 int targetInterval = Integer.parseInt(targetAttribute.getValue());
91 if (targetInterval == 0 || sourceInterval < targetInterval) {
92 targetAttribute.setValue(attribute.getValue());
93 }
94 } else {
95 targetAttribute.setValue(attribute.getValue());
96 }
97 }
98 isFound = true;
99 }
100 }
101 if (!isFound) {
102 rootNode.getAttributes().put(attribute.getKey(), attribute.getValue());
103 }
104 }
105 }
106
107
108
109
110
111
112
113
114 @Override
115 public void mergConfigurations(Node target, Node source, PluginManager pluginManager) {
116 for (Node sourceChildNode : source.getChildren()) {
117 boolean isFilter = isFilterNode(sourceChildNode);
118 boolean isMerged = false;
119 for (Node targetChildNode : target.getChildren()) {
120 if (isFilter) {
121 if (isFilterNode(targetChildNode)) {
122 updateFilterNode(target, targetChildNode, sourceChildNode, pluginManager);
123 isMerged = true;
124 break;
125 } else {
126 continue;
127 }
128 }
129
130 if (!targetChildNode.getName().equalsIgnoreCase(sourceChildNode.getName())) {
131 continue;
132 }
133
134 switch (targetChildNode.getName().toLowerCase()) {
135 case PROPERTIES:
136 case SCRIPTS:
137 case APPENDERS: {
138 for (Node node : sourceChildNode.getChildren()) {
139 for (Node targetNode : targetChildNode.getChildren()) {
140 if (targetNode.getAttributes().get(NAME).equals(node.getAttributes().get(NAME))) {
141 targetChildNode.getChildren().remove(targetNode);
142 break;
143 }
144 }
145 targetChildNode.getChildren().add(node);
146 }
147 isMerged = true;
148 break;
149 }
150 case LOGGERS: {
151 Map<String, Node> targetLoggers = new HashMap<>();
152 for (Node node : targetChildNode.getChildren()) {
153 targetLoggers.put(node.getName(), node);
154 }
155 for (Node node : sourceChildNode.getChildren()) {
156 Node targetNode = getLoggerNode(targetChildNode, node.getAttributes().get(NAME));
157 Node loggerNode = new Node(targetChildNode, node.getName(), node.getType());
158 if (targetNode != null) {
159 for (Node sourceLoggerChild : node.getChildren()) {
160 if (isFilterNode(sourceLoggerChild)) {
161 boolean foundFilter = false;
162 for (Node targetChild : targetNode.getChildren()) {
163 if (isFilterNode(targetChild)) {
164 updateFilterNode(loggerNode, targetChild, sourceLoggerChild,
165 pluginManager);
166 foundFilter = true;
167 break;
168 }
169 }
170 if (!foundFilter) {
171 Node childNode = new Node(loggerNode, sourceLoggerChild.getName(),
172 sourceLoggerChild.getType());
173 targetNode.getChildren().add(childNode);
174 }
175 } else {
176 Node childNode = new Node(loggerNode, sourceLoggerChild.getName(),
177 sourceLoggerChild.getType());
178 childNode.getAttributes().putAll(sourceLoggerChild.getAttributes());
179 if (childNode.getName().equalsIgnoreCase("AppenderRef")) {
180 for (Node targetChild : targetNode.getChildren()) {
181 if (isSameReference(targetChild, childNode)) {
182 targetNode.getChildren().remove(targetChild);
183 break;
184 }
185 }
186 } else {
187 for (Node targetChild : targetNode.getChildren()) {
188 if (isSameName(targetChild, childNode)) {
189 targetNode.getChildren().remove(targetChild);
190 break;
191 }
192 }
193 }
194
195 targetNode.getChildren().add(childNode);
196 }
197 }
198 } else {
199 loggerNode.getAttributes().putAll(node.getAttributes());
200 loggerNode.getChildren().addAll(node.getChildren());
201 targetChildNode.getChildren().add(loggerNode);
202 }
203 }
204 isMerged = true;
205 break;
206 }
207 default: {
208 targetChildNode.getChildren().addAll(sourceChildNode.getChildren());
209 isMerged = true;
210 break;
211 }
212
213 }
214 }
215 if (!isMerged) {
216 if (sourceChildNode.getName().equalsIgnoreCase("Properties")) {
217 target.getChildren().add(0, sourceChildNode);
218 } else {
219 target.getChildren().add(sourceChildNode);
220 }
221 }
222 }
223 }
224
225 private Node getLoggerNode(Node parentNode, String name) {
226 for (Node node : parentNode.getChildren()) {
227 String nodeName = node.getAttributes().get(NAME);
228 if (name == null && nodeName == null) {
229 return node;
230 }
231 if (nodeName != null && nodeName.equals(name)) {
232 return node;
233 }
234 }
235 return null;
236 }
237
238 private void updateFilterNode(Node target, Node targetChildNode, Node sourceChildNode,
239 PluginManager pluginManager) {
240 if (CompositeFilter.class.isAssignableFrom(targetChildNode.getType().getPluginClass())) {
241 Node node = new Node(targetChildNode, sourceChildNode.getName(), sourceChildNode.getType());
242 node.getChildren().addAll(sourceChildNode.getChildren());
243 node.getAttributes().putAll(sourceChildNode.getAttributes());
244 targetChildNode.getChildren().add(node);
245 } else {
246 PluginType pluginType = pluginManager.getPluginType(FILTERS);
247 Node filtersNode = new Node(targetChildNode, FILTERS, pluginType);
248 Node node = new Node(filtersNode, sourceChildNode.getName(), sourceChildNode.getType());
249 node.getAttributes().putAll(sourceChildNode.getAttributes());
250 List<Node> children = filtersNode.getChildren();
251 children.add(targetChildNode);
252 children.add(node);
253 List<Node> nodes = target.getChildren();
254 nodes.remove(targetChildNode);
255 nodes.add(filtersNode);
256 }
257 }
258
259 private boolean isFilterNode(Node node) {
260 return Filter.class.isAssignableFrom(node.getType().getPluginClass());
261 }
262
263 private boolean isSameName(Node node1, Node node2) {
264 return node1.getAttributes().get(NAME).toLowerCase().equals(node2.getAttributes().get(NAME).toLowerCase());
265 }
266
267 private boolean isSameReference(Node node1, Node node2) {
268 return node1.getAttributes().get(REF).toLowerCase().equals(node2.getAttributes().get(REF).toLowerCase());
269 }
270 }