1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.config;
18
19 import org.apache.logging.log4j.Level;
20 import org.apache.logging.log4j.core.Appender;
21 import org.apache.logging.log4j.core.Filter;
22 import org.apache.logging.log4j.core.Layout;
23 import org.apache.logging.log4j.core.LogEvent;
24 import org.apache.logging.log4j.core.appender.AsyncAppender;
25 import org.apache.logging.log4j.core.appender.ConsoleAppender;
26 import org.apache.logging.log4j.core.async.AsyncLoggerConfig;
27 import org.apache.logging.log4j.core.async.AsyncLoggerConfigDelegate;
28 import org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor;
29 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
30 import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
31 import org.apache.logging.log4j.core.config.plugins.util.PluginType;
32 import org.apache.logging.log4j.core.filter.AbstractFilterable;
33 import org.apache.logging.log4j.core.layout.PatternLayout;
34 import org.apache.logging.log4j.core.lookup.Interpolator;
35 import org.apache.logging.log4j.core.lookup.MapLookup;
36 import org.apache.logging.log4j.core.lookup.StrLookup;
37 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
38 import org.apache.logging.log4j.core.net.Advertiser;
39 import org.apache.logging.log4j.core.script.AbstractScript;
40 import org.apache.logging.log4j.core.script.ScriptManager;
41 import org.apache.logging.log4j.core.script.ScriptRef;
42 import org.apache.logging.log4j.core.util.Constants;
43 import org.apache.logging.log4j.core.util.Loader;
44 import org.apache.logging.log4j.core.util.NameUtil;
45 import org.apache.logging.log4j.core.util.WatchManager;
46 import org.apache.logging.log4j.util.PropertiesUtil;
47
48 import java.io.ByteArrayOutputStream;
49 import java.io.IOException;
50 import java.io.InputStream;
51 import java.io.Serializable;
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.Collection;
55 import java.util.Collections;
56 import java.util.HashSet;
57 import java.util.LinkedHashMap;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.Objects;
61 import java.util.Set;
62 import java.util.concurrent.ConcurrentHashMap;
63 import java.util.concurrent.ConcurrentMap;
64 import java.util.concurrent.CopyOnWriteArrayList;
65
66
67
68
69 public abstract class AbstractConfiguration extends AbstractFilterable implements Configuration {
70
71 private static final long serialVersionUID = 1L;
72
73 private static final int BUF_SIZE = 16384;
74
75
76
77
78 protected Node rootNode;
79
80
81
82
83 protected final List<ConfigurationListener> listeners = new CopyOnWriteArrayList<>();
84
85
86
87
88 protected final List<String> pluginPackages = new ArrayList<>();
89
90
91
92
93 protected PluginManager pluginManager;
94
95
96
97
98 protected boolean isShutdownHookEnabled = true;
99
100
101
102
103 private Advertiser advertiser = new DefaultAdvertiser();
104 private Node advertiserNode = null;
105 private Object advertisement;
106 private String name;
107 private ConcurrentMap<String, Appender> appenders = new ConcurrentHashMap<>();
108 private ConcurrentMap<String, LoggerConfig> loggerConfigs = new ConcurrentHashMap<>();
109 private List<CustomLevelConfig> customLevels = Collections.emptyList();
110 private final ConcurrentMap<String, String> properties = new ConcurrentHashMap<>();
111 private final StrLookup tempLookup = new Interpolator(properties);
112 private final StrSubstitutor subst = new StrSubstitutor(tempLookup);
113 private LoggerConfig root = new LoggerConfig();
114 private final ConcurrentMap<String, Object> componentMap = new ConcurrentHashMap<>();
115 private final ConfigurationSource configurationSource;
116 private ScriptManager scriptManager;
117 private ConfigurationScheduler configurationScheduler = new ConfigurationScheduler();
118 private final WatchManager watchManager = new WatchManager(configurationScheduler);
119 private AsyncLoggerConfigDisruptor asyncLoggerConfigDisruptor;
120
121
122
123
124
125 protected AbstractConfiguration(final ConfigurationSource configurationSource) {
126 this.configurationSource = Objects.requireNonNull(configurationSource, "configurationSource is null");
127 componentMap.put(Configuration.CONTEXT_PROPERTIES, properties);
128 pluginManager = new PluginManager(Node.CATEGORY);
129 rootNode = new Node();
130 setState(State.INITIALIZING);
131
132 }
133
134 @Override
135 public ConfigurationSource getConfigurationSource() {
136 return configurationSource;
137 }
138
139 @Override
140 public List<String> getPluginPackages() {
141 return pluginPackages;
142 }
143
144 @Override
145 public Map<String, String> getProperties() {
146 return properties;
147 }
148
149 @Override
150 public ScriptManager getScriptManager() {
151 return scriptManager;
152 }
153
154 public WatchManager getWatchManager() {
155 return watchManager;
156 }
157
158 @Override
159 public ConfigurationScheduler getScheduler() {
160 return configurationScheduler;
161 }
162
163 @Override
164 public AsyncLoggerConfigDelegate getAsyncLoggerConfigDelegate() {
165
166
167 if (asyncLoggerConfigDisruptor == null) {
168 asyncLoggerConfigDisruptor = new AsyncLoggerConfigDisruptor();
169 }
170 return asyncLoggerConfigDisruptor;
171 }
172
173
174
175
176 @Override
177 public void initialize() {
178 LOGGER.debug("Initializing configuration {}", this);
179 scriptManager = new ScriptManager(watchManager);
180 pluginManager.collectPlugins(pluginPackages);
181 final PluginManager levelPlugins = new PluginManager(Level.CATEGORY);
182 levelPlugins.collectPlugins(pluginPackages);
183 final Map<String, PluginType<?>> plugins = levelPlugins.getPlugins();
184 if (plugins != null) {
185 for (final PluginType<?> type : plugins.values()) {
186 try {
187
188 Loader.initializeClass(type.getPluginClass().getName(), type.getPluginClass().getClassLoader());
189 } catch (final Exception e) {
190 LOGGER.error("Unable to initialize {} due to {}", type.getPluginClass().getName(), e.getClass()
191 .getSimpleName(), e);
192 }
193 }
194 }
195 setup();
196 setupAdvertisement();
197 doConfigure();
198 setState(State.INITIALIZED);
199 LOGGER.debug("Configuration {} initialized", this);
200 }
201
202
203
204
205 @Override
206 public void start() {
207
208 if (getState().equals(State.INITIALIZING)) {
209 initialize();
210 }
211 LOGGER.debug("Starting configuration {}", this);
212 this.setStarting();
213 if (watchManager.getIntervalSeconds() > 0) {
214 watchManager.start();
215 }
216 if (hasAsyncLoggers()) {
217 asyncLoggerConfigDisruptor.start();
218 }
219 final Set<LoggerConfig> alreadyStarted = new HashSet<>();
220 for (final LoggerConfig logger : loggerConfigs.values()) {
221 logger.start();
222 alreadyStarted.add(logger);
223 }
224 for (final Appender appender : appenders.values()) {
225 appender.start();
226 }
227 if (!alreadyStarted.contains(root)) {
228 root.start();
229 }
230 super.start();
231 LOGGER.debug("Started configuration {} OK.", this);
232 }
233
234 private boolean hasAsyncLoggers() {
235 if (root instanceof AsyncLoggerConfig) {
236 return true;
237 }
238 for (final LoggerConfig logger : loggerConfigs.values()) {
239 if (logger instanceof AsyncLoggerConfig) {
240 return true;
241 }
242 }
243 return false;
244 }
245
246
247
248
249 @Override
250 public void stop() {
251 this.setStopping();
252 LOGGER.trace("Stopping {}...", this);
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 for (final LoggerConfig loggerConfig : loggerConfigs.values()) {
268 loggerConfig.getReliabilityStrategy().beforeStopConfiguration(this);
269 }
270 root.getReliabilityStrategy().beforeStopConfiguration(this);
271
272 final String cls = getClass().getSimpleName();
273 LOGGER.trace("{} notified {} ReliabilityStrategies that config will be stopped.", cls, loggerConfigs.size()
274 + 1);
275
276 if (!loggerConfigs.isEmpty()) {
277 LOGGER.trace("{} stopping {} LoggerConfigs.", cls, loggerConfigs.size());
278 for (final LoggerConfig logger : loggerConfigs.values()) {
279 logger.stop();
280 }
281 }
282 LOGGER.trace("{} stopping root LoggerConfig.", cls);
283 if (!root.isStopped()) {
284 root.stop();
285 }
286
287 if (hasAsyncLoggers()) {
288 LOGGER.trace("{} stopping AsyncLoggerConfigDisruptor.", cls);
289 asyncLoggerConfigDisruptor.stop();
290 }
291
292
293 final Appender[] array = appenders.values().toArray(new Appender[appenders.size()]);
294 final List<Appender> async = getAsyncAppenders(array);
295 if (!async.isEmpty()) {
296
297 LOGGER.trace("{} stopping {} AsyncAppenders.", cls, async.size());
298 for (Appender appender : async) {
299 appender.stop();
300 }
301 }
302
303 LOGGER.trace("{} notifying ReliabilityStrategies that appenders will be stopped.", cls);
304 for (final LoggerConfig loggerConfig : loggerConfigs.values()) {
305 loggerConfig.getReliabilityStrategy().beforeStopAppenders();
306 }
307 root.getReliabilityStrategy().beforeStopAppenders();
308
309 LOGGER.trace("{} stopping remaining Appenders.", cls);
310 int appenderCount = 0;
311 for (int i = array.length - 1; i >= 0; --i) {
312 if (array[i].isStarted()) {
313 array[i].stop();
314 appenderCount++;
315 }
316 }
317 LOGGER.trace("{} stopped {} remaining Appenders.", cls, appenderCount);
318
319 LOGGER.trace("{} cleaning Appenders from {} LoggerConfigs.", cls, loggerConfigs.size() + 1);
320 for (final LoggerConfig loggerConfig : loggerConfigs.values()) {
321
322
323
324
325
326
327 loggerConfig.clearAppenders();
328 }
329 root.clearAppenders();
330
331 if (watchManager.isStarted()) {
332 watchManager.stop();
333 }
334 configurationScheduler.stop();
335
336 super.stop();
337 if (advertiser != null && advertisement != null) {
338 advertiser.unadvertise(advertisement);
339 }
340 LOGGER.debug("Stopped {} OK", this);
341 }
342
343 private List<Appender> getAsyncAppenders(final Appender[] all) {
344 final List<Appender> result = new ArrayList<Appender>();
345 for (int i = all.length - 1; i >= 0; --i) {
346 if (all[i] instanceof AsyncAppender) {
347 result.add(all[i]);
348 }
349 }
350 return result;
351 }
352
353 @Override
354 public boolean isShutdownHookEnabled() {
355 return isShutdownHookEnabled;
356 }
357
358 protected void setup() {
359 }
360
361 protected Level getDefaultStatus() {
362 final String statusLevel = PropertiesUtil.getProperties().getStringProperty(
363 Constants.LOG4J_DEFAULT_STATUS_LEVEL, Level.ERROR.name());
364 try {
365 return Level.toLevel(statusLevel);
366 } catch (final Exception ex) {
367 return Level.ERROR;
368 }
369 }
370
371 protected void createAdvertiser(final String advertiserString, final ConfigurationSource configSource,
372 final byte[] buffer, final String contentType) {
373 if (advertiserString != null) {
374 final Node node = new Node(null, advertiserString, null);
375 final Map<String, String> attributes = node.getAttributes();
376 attributes.put("content", new String(buffer));
377 attributes.put("contentType", contentType);
378 attributes.put("name", "configuration");
379 if (configSource.getLocation() != null) {
380 attributes.put("location", configSource.getLocation());
381 }
382 advertiserNode = node;
383 }
384 }
385
386 private void setupAdvertisement() {
387 if (advertiserNode != null) {
388 final String nodeName = advertiserNode.getName();
389 final PluginType<?> type = pluginManager.getPluginType(nodeName);
390 if (type != null) {
391 final Class<? extends Advertiser> clazz = type.getPluginClass().asSubclass(Advertiser.class);
392 try {
393 advertiser = clazz.newInstance();
394 advertisement = advertiser.advertise(advertiserNode.getAttributes());
395 } catch (final InstantiationException e) {
396 LOGGER.error("InstantiationException attempting to instantiate advertiser: {}", nodeName, e);
397 } catch (final IllegalAccessException e) {
398 LOGGER.error("IllegalAccessException attempting to instantiate advertiser: {}", nodeName, e);
399 }
400 }
401 }
402 }
403
404 @SuppressWarnings("unchecked")
405 @Override
406 public <T> T getComponent(final String componentName) {
407 return (T) componentMap.get(componentName);
408 }
409
410 @Override
411 public void addComponent(final String componentName, final Object obj) {
412 componentMap.putIfAbsent(componentName, obj);
413 }
414
415 protected void preConfigure(Node node) {
416 for (final Node child : node.getChildren()) {
417 Class<?> clazz = child.getType().getPluginClass();
418 if (clazz.isAnnotationPresent(Scheduled.class)) {
419 configurationScheduler.incrementScheduledItems();
420 }
421 preConfigure(child);
422 }
423 }
424
425 protected void doConfigure() {
426 preConfigure(rootNode);
427 configurationScheduler.start();
428 if (rootNode.hasChildren() && rootNode.getChildren().get(0).getName().equalsIgnoreCase("Properties")) {
429 final Node first = rootNode.getChildren().get(0);
430 createConfiguration(first, null);
431 if (first.getObject() != null) {
432 subst.setVariableResolver((StrLookup) first.getObject());
433 }
434 } else {
435 final Map<String, String> map = this.getComponent(CONTEXT_PROPERTIES);
436 final StrLookup lookup = map == null ? null : new MapLookup(map);
437 subst.setVariableResolver(new Interpolator(lookup, pluginPackages));
438 }
439
440 boolean setLoggers = false;
441 boolean setRoot = false;
442 for (final Node child : rootNode.getChildren()) {
443 if (child.getName().equalsIgnoreCase("Properties")) {
444 if (tempLookup == subst.getVariableResolver()) {
445 LOGGER.error("Properties declaration must be the first element in the configuration");
446 }
447 continue;
448 }
449 createConfiguration(child, null);
450 if (child.getObject() == null) {
451 continue;
452 }
453 if (child.getName().equalsIgnoreCase("Scripts")) {
454 for (AbstractScript script : child.getObject(AbstractScript[].class)) {
455 if (script instanceof ScriptRef) {
456 LOGGER.error("Script reference to {} not added. Scripts definition cannot contain script references",
457 script.getName());
458 } else {
459 scriptManager.addScript(script);
460 }
461 }
462 } else if (child.getName().equalsIgnoreCase("Appenders")) {
463 appenders = child.getObject();
464 } else if (child.isInstanceOf(Filter.class)) {
465 addFilter(child.getObject(Filter.class));
466 } else if (child.getName().equalsIgnoreCase("Loggers")) {
467 final Loggers l = child.getObject();
468 loggerConfigs = l.getMap();
469 setLoggers = true;
470 if (l.getRoot() != null) {
471 root = l.getRoot();
472 setRoot = true;
473 }
474 } else if (child.getName().equalsIgnoreCase("CustomLevels")) {
475 customLevels = child.getObject(CustomLevels.class).getCustomLevels();
476 } else if (child.isInstanceOf(CustomLevelConfig.class)) {
477 final List<CustomLevelConfig> copy = new ArrayList<>(customLevels);
478 copy.add(child.getObject(CustomLevelConfig.class));
479 customLevels = copy;
480 } else {
481 final List<String> expected = Arrays.asList("\"Appenders\"", "\"Loggers\"", "\"Properties\"",
482 "\"Scripts\"", "\"CustomLevels\"");
483 LOGGER.error("Unknown object \"{}\" of type {} is ignored: try nesting it inside one of: {}.",
484 child.getName(), child.getObject().getClass().getName(), expected);
485 }
486 }
487
488 if (!setLoggers) {
489 LOGGER.warn("No Loggers were configured, using default. Is the Loggers element missing?");
490 setToDefault();
491 return;
492 } else if (!setRoot) {
493 LOGGER.warn("No Root logger was configured, creating default ERROR-level Root logger with Console appender");
494 setToDefault();
495
496 }
497
498 for (final Map.Entry<String, LoggerConfig> entry : loggerConfigs.entrySet()) {
499 final LoggerConfig loggerConfig = entry.getValue();
500 for (final AppenderRef ref : loggerConfig.getAppenderRefs()) {
501 final Appender app = appenders.get(ref.getRef());
502 if (app != null) {
503 loggerConfig.addAppender(app, ref.getLevel(), ref.getFilter());
504 } else {
505 LOGGER.error("Unable to locate appender \"{}\" for logger config \"{}\"", ref.getRef(),
506 loggerConfig);
507 }
508 }
509
510 }
511
512 setParents();
513 }
514
515 protected void setToDefault() {
516
517 setName(DefaultConfiguration.DEFAULT_NAME + "@" + Integer.toHexString(hashCode()));
518 final Layout<? extends Serializable> layout = PatternLayout.newBuilder()
519 .withPattern(DefaultConfiguration.DEFAULT_PATTERN)
520 .withConfiguration(this)
521 .build();
522 final Appender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
523 appender.start();
524 addAppender(appender);
525 final LoggerConfig rootLoggerConfig = getRootLogger();
526 rootLoggerConfig.addAppender(appender, null, null);
527
528 final Level defaultLevel = Level.ERROR;
529 final String levelName = PropertiesUtil.getProperties().getStringProperty(DefaultConfiguration.DEFAULT_LEVEL,
530 defaultLevel.name());
531 final Level level = Level.valueOf(levelName);
532 rootLoggerConfig.setLevel(level != null ? level : defaultLevel);
533 }
534
535
536
537
538
539
540 public void setName(final String name) {
541 this.name = name;
542 }
543
544
545
546
547
548
549 @Override
550 public String getName() {
551 return name;
552 }
553
554
555
556
557
558
559 @Override
560 public void addListener(final ConfigurationListener listener) {
561 listeners.add(listener);
562 }
563
564
565
566
567
568
569 @Override
570 public void removeListener(final ConfigurationListener listener) {
571 listeners.remove(listener);
572 }
573
574
575
576
577
578
579
580 @Override
581 @SuppressWarnings("unchecked")
582 public <T extends Appender> T getAppender(final String appenderName) {
583 return (T) appenders.get(appenderName);
584 }
585
586
587
588
589
590
591 @Override
592 public Map<String, Appender> getAppenders() {
593 return appenders;
594 }
595
596
597
598
599
600
601 @Override
602 public void addAppender(final Appender appender) {
603 appenders.putIfAbsent(appender.getName(), appender);
604 }
605
606 @Override
607 public StrSubstitutor getStrSubstitutor() {
608 return subst;
609 }
610
611 @Override
612 public void setAdvertiser(final Advertiser advertiser) {
613 this.advertiser = advertiser;
614 }
615
616 @Override
617 public Advertiser getAdvertiser() {
618 return advertiser;
619 }
620
621
622
623
624
625
626
627 @Override
628 public ReliabilityStrategy getReliabilityStrategy(LoggerConfig loggerConfig) {
629 return ReliabilityStrategyFactory.getReliabilityStrategy(loggerConfig);
630 }
631
632
633
634
635
636
637
638
639
640
641 @Override
642 public synchronized void addLoggerAppender(final org.apache.logging.log4j.core.Logger logger,
643 final Appender appender) {
644 final String loggerName = logger.getName();
645 appenders.putIfAbsent(appender.getName(), appender);
646 final LoggerConfig lc = getLoggerConfig(loggerName);
647 if (lc.getName().equals(loggerName)) {
648 lc.addAppender(appender, null, null);
649 } else {
650 final LoggerConfig nlc = new LoggerConfig(loggerName, lc.getLevel(), lc.isAdditive());
651 nlc.addAppender(appender, null, null);
652 nlc.setParent(lc);
653 loggerConfigs.putIfAbsent(loggerName, nlc);
654 setParents();
655 logger.getContext().updateLoggers();
656 }
657 }
658
659
660
661
662
663
664
665
666
667
668 @Override
669 public synchronized void addLoggerFilter(final org.apache.logging.log4j.core.Logger logger, final Filter filter) {
670 final String loggerName = logger.getName();
671 final LoggerConfig lc = getLoggerConfig(loggerName);
672 if (lc.getName().equals(loggerName)) {
673 lc.addFilter(filter);
674 } else {
675 final LoggerConfig nlc = new LoggerConfig(loggerName, lc.getLevel(), lc.isAdditive());
676 nlc.addFilter(filter);
677 nlc.setParent(lc);
678 loggerConfigs.putIfAbsent(loggerName, nlc);
679 setParents();
680 logger.getContext().updateLoggers();
681 }
682 }
683
684
685
686
687
688
689
690
691
692
693 @Override
694 public synchronized void setLoggerAdditive(final org.apache.logging.log4j.core.Logger logger, final boolean additive) {
695 final String loggerName = logger.getName();
696 final LoggerConfig lc = getLoggerConfig(loggerName);
697 if (lc.getName().equals(loggerName)) {
698 lc.setAdditive(additive);
699 } else {
700 final LoggerConfig nlc = new LoggerConfig(loggerName, lc.getLevel(), additive);
701 nlc.setParent(lc);
702 loggerConfigs.putIfAbsent(loggerName, nlc);
703 setParents();
704 logger.getContext().updateLoggers();
705 }
706 }
707
708
709
710
711
712
713
714
715 public synchronized void removeAppender(final String appenderName) {
716 for (final LoggerConfig logger : loggerConfigs.values()) {
717 logger.removeAppender(appenderName);
718 }
719 final Appender app = appenders.remove(appenderName);
720
721 if (app != null) {
722 app.stop();
723 }
724 }
725
726
727
728
729
730
731 @Override
732 public List<CustomLevelConfig> getCustomLevels() {
733 return Collections.unmodifiableList(customLevels);
734 }
735
736
737
738
739
740
741
742
743 @Override
744 public LoggerConfig getLoggerConfig(final String loggerName) {
745 LoggerConfig loggerConfig = loggerConfigs.get(loggerName);
746 if (loggerConfig != null) {
747 return loggerConfig;
748 }
749 String substr = loggerName;
750 while ((substr = NameUtil.getSubName(substr)) != null) {
751 loggerConfig = loggerConfigs.get(substr);
752 if (loggerConfig != null) {
753 return loggerConfig;
754 }
755 }
756 return root;
757 }
758
759
760
761
762
763
764 @Override
765 public LoggerConfig getRootLogger() {
766 return root;
767 }
768
769
770
771
772
773
774 @Override
775 public Map<String, LoggerConfig> getLoggers() {
776 return Collections.unmodifiableMap(loggerConfigs);
777 }
778
779
780
781
782
783
784
785 public LoggerConfig getLogger(final String loggerName) {
786 return loggerConfigs.get(loggerName);
787 }
788
789
790
791
792
793
794
795
796 @Override
797 public synchronized void addLogger(final String loggerName, final LoggerConfig loggerConfig) {
798 loggerConfigs.putIfAbsent(loggerName, loggerConfig);
799 setParents();
800 }
801
802
803
804
805
806
807 @Override
808 public synchronized void removeLogger(final String loggerName) {
809 loggerConfigs.remove(loggerName);
810 setParents();
811 }
812
813 @Override
814 public void createConfiguration(final Node node, final LogEvent event) {
815 final PluginType<?> type = node.getType();
816 if (type != null && type.isDeferChildren()) {
817 node.setObject(createPluginObject(type, node, event));
818 } else {
819 for (final Node child : node.getChildren()) {
820 createConfiguration(child, event);
821 }
822
823 if (type == null) {
824 if (node.getParent() != null) {
825 LOGGER.error("Unable to locate plugin for {}", node.getName());
826 }
827 } else {
828 node.setObject(createPluginObject(type, node, event));
829 }
830 }
831 }
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869 private Object createPluginObject(final PluginType<?> type, final Node node, final LogEvent event) {
870 final Class<?> clazz = type.getPluginClass();
871
872 if (Map.class.isAssignableFrom(clazz)) {
873 try {
874 return createPluginMap(node);
875 } catch (final Exception e) {
876 LOGGER.warn("Unable to create Map for {} of class {}", type.getElementName(), clazz, e);
877 }
878 }
879
880 if (Collection.class.isAssignableFrom(clazz)) {
881 try {
882 return createPluginCollection(node);
883 } catch (final Exception e) {
884 LOGGER.warn("Unable to create List for {} of class {}", type.getElementName(), clazz, e);
885 }
886 }
887
888 return new PluginBuilder(type).withConfiguration(this).withConfigurationNode(node).forLogEvent(event).build();
889 }
890
891 private static Map<String, ?> createPluginMap(final Node node) {
892 final Map<String, Object> map = new LinkedHashMap<>();
893 for (final Node child : node.getChildren()) {
894 final Object object = child.getObject();
895 map.put(child.getName(), object);
896 }
897 return map;
898 }
899
900 private static Collection<?> createPluginCollection(final Node node) {
901 final List<Node> children = node.getChildren();
902 final Collection<Object> list = new ArrayList<>(children.size());
903 for (final Node child : children) {
904 final Object object = child.getObject();
905 list.add(object);
906 }
907 return list;
908 }
909
910 private void setParents() {
911 for (final Map.Entry<String, LoggerConfig> entry : loggerConfigs.entrySet()) {
912 final LoggerConfig logger = entry.getValue();
913 String key = entry.getKey();
914 if (!key.isEmpty()) {
915 final int i = key.lastIndexOf('.');
916 if (i > 0) {
917 key = key.substring(0, i);
918 LoggerConfig parent = getLoggerConfig(key);
919 if (parent == null) {
920 parent = root;
921 }
922 logger.setParent(parent);
923 } else {
924 logger.setParent(root);
925 }
926 }
927 }
928 }
929
930
931
932
933
934
935
936
937
938 protected static byte[] toByteArray(final InputStream is) throws IOException {
939 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
940
941 int nRead;
942 final byte[] data = new byte[BUF_SIZE];
943
944 while ((nRead = is.read(data, 0, data.length)) != -1) {
945 buffer.write(data, 0, nRead);
946 }
947
948 return buffer.toByteArray();
949 }
950
951 }