View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.appender;
18  
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.logging.log4j.core.Appender;
24  import org.apache.logging.log4j.core.config.Configuration;
25  import org.apache.logging.log4j.core.config.Node;
26  import org.apache.logging.log4j.core.config.plugins.Plugin;
27  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
28  import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
29  import org.apache.logging.log4j.core.config.plugins.PluginNode;
30  import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
31  import org.apache.logging.log4j.status.StatusLogger;
32  
33  /**
34   * A deferred plugin for appenders.
35   */
36  @Plugin(name = "AppenderSet", category = "Core", printObject = true, deferChildren = true)
37  public class AppenderSet {
38  
39      public static class Builder implements org.apache.logging.log4j.core.util.Builder<AppenderSet> {
40  
41          @PluginNode
42          private Node node;
43  
44          @PluginConfiguration
45          @Required
46          private Configuration configuration;
47  
48          @Override
49          public AppenderSet build() {
50              if (configuration == null) {
51                  LOGGER.error("Configuration is missing from AppenderSet {}", this);
52                  return null;                
53              }
54              if (node == null) {
55                  LOGGER.error("No node in AppenderSet {}", this);
56                  return null;
57              }
58              final List<Node> children = node.getChildren();
59              if (children == null) {
60                  LOGGER.error("No children node in AppenderSet {}", this);
61                  return null;
62              }
63              final Map<String, Node> map = new HashMap<>(children.size());
64              for (final Node childNode : children) {
65                  final String key = childNode.getAttributes().get("name");
66                  if (key == null) {
67                      LOGGER.error("The attribute 'name' is missing from from the node {} in AppenderSet {}",
68                              childNode, children);
69                  } else {
70                      map.put(key, childNode);
71                  }
72              }
73              return new AppenderSet(configuration, map);
74          }
75  
76          public Node getNode() {
77              return node;
78          }
79  
80          public Configuration getConfiguration() {
81              return configuration;
82          }
83  
84          public Builder withNode(@SuppressWarnings("hiding") final Node node) {
85              this.node = node;
86              return this;
87          }
88  
89          public Builder withConfiguration(@SuppressWarnings("hiding") final Configuration configuration) {
90              this.configuration = configuration;
91              return this;
92          }
93  
94          @Override
95          public String toString() {
96              return getClass().getName() + " [node=" + node + ", configuration=" + configuration + "]";
97          }
98  
99      }
100 
101     private static final StatusLogger LOGGER = StatusLogger.getLogger();
102 
103     private final Configuration configuration;
104     private final Map<String, Node> nodeMap;
105 
106     @PluginBuilderFactory
107     public static Builder newBuilder() {
108         return new Builder();
109     }
110 
111     private AppenderSet(final Configuration configuration, final Map<String, Node> appenders) {
112         this.configuration = configuration;
113         this.nodeMap = appenders;
114     }
115 
116     public Appender createAppender(final String appenderName, final String actualName) {
117         final Node node = nodeMap.get(appenderName);
118         if (node == null) {
119             LOGGER.error("No node named {} in {}", appenderName, this);
120             return null;
121         }
122         node.getAttributes().put("name", actualName);
123         if (node.getType().getElementName().equals(Appender.ELEMENT_TYPE)) {
124             final Node appNode = new Node(node);
125             configuration.createConfiguration(appNode, null);
126             if (appNode.getObject() instanceof Appender) {
127                 final Appender app = appNode.getObject();
128                 app.start();
129                 return app;
130             }
131             LOGGER.error("Unable to create Appender of type " + node.getName());
132             return null;
133         }
134         LOGGER.error("No Appender was configured for name {} " + appenderName);
135         return null;
136     }
137 }