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.log4j.builders.layout;
18  
19  import org.apache.log4j.Layout;
20  import org.apache.log4j.bridge.LayoutWrapper;
21  import org.apache.log4j.builders.AbstractBuilder;
22  import org.apache.log4j.config.Log4j1Configuration;
23  import org.apache.log4j.config.PropertiesConfiguration;
24  import org.apache.log4j.xml.XmlConfiguration;
25  import org.apache.logging.log4j.Logger;
26  import org.apache.logging.log4j.core.config.plugins.Plugin;
27  import org.apache.logging.log4j.core.config.plugins.PluginAliases;
28  import org.apache.logging.log4j.core.layout.PatternLayout;
29  import org.apache.logging.log4j.status.StatusLogger;
30  import org.w3c.dom.Element;
31  import org.w3c.dom.Node;
32  import org.w3c.dom.NodeList;
33  
34  import java.util.Properties;
35  
36  import static org.apache.log4j.builders.BuilderManager.CATEGORY;
37  import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
38  
39  /**
40   * Build a Pattern Layout
41   */
42  @Plugin(name = "org.apache.log4j.PatternLayout", category = CATEGORY)
43  @PluginAliases("org.apache.log4j.EnhancedPatternLayout")
44  public class PatternLayoutBuilder extends AbstractBuilder implements LayoutBuilder {
45  
46      private static final Logger LOGGER = StatusLogger.getLogger();
47      private static final String PATTERN = "ConversionPattern";
48  
49      public PatternLayoutBuilder() {
50      }
51  
52      public PatternLayoutBuilder(String prefix, Properties props) {
53          super(prefix, props);
54      }
55  
56      @Override
57      public Layout parseLayout(final Element layoutElement, final XmlConfiguration config) {
58          NodeList params = layoutElement.getElementsByTagName("param");
59          final int length = params.getLength();
60          String pattern = null;
61          for (int index = 0; index < length; ++ index) {
62              Node currentNode = params.item(index);
63              if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
64                  Element currentElement = (Element) currentNode;
65                  if (currentElement.getTagName().equals(PARAM_TAG)) {
66                      if (PATTERN.equalsIgnoreCase(currentElement.getAttribute("name"))) {
67                          pattern = currentElement.getAttribute("value");
68                          break;
69                      }
70                  }
71              }
72          }
73          return createLayout(pattern, config);
74      }
75  
76      @Override
77      public Layout parseLayout(final PropertiesConfiguration config) {
78          String pattern = getProperty(PATTERN);
79          return createLayout(pattern, config);
80      }
81  
82      private Layout createLayout(String pattern, final Log4j1Configuration config) {
83          if (pattern == null) {
84              LOGGER.info("No pattern provided for pattern layout, using default pattern");
85              pattern = PatternLayout.DEFAULT_CONVERSION_PATTERN;
86          }
87          return new LayoutWrapper(PatternLayout.newBuilder()
88                  .withPattern(pattern
89                          // Log4j 2's %x (NDC) is not compatible with Log4j 1's
90                          // %x
91                          // Log4j 1: "foo bar baz"
92                          // Log4j 2: "[foo, bar, baz]"
93                          // Use %ndc to get the Log4j 1 format
94                          .replace("%x", "%ndc")
95  
96                          // Log4j 2's %X (MDC) is not compatible with Log4j 1's
97                          // %X
98                          // Log4j 1: "{{foo,bar}{hoo,boo}}"
99                          // Log4j 2: "{foo=bar,hoo=boo}"
100                         // Use %properties to get the Log4j 1 format
101                         .replace("%X", "%properties"))
102                 .withConfiguration(config)
103                 .build());
104     }
105 }