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 static org.apache.log4j.builders.BuilderManager.CATEGORY;
20  import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
21  import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
22  import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
23  import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
24  
25  import java.util.Properties;
26  import java.util.concurrent.atomic.AtomicBoolean;
27  import java.util.concurrent.atomic.AtomicReference;
28  
29  import org.apache.log4j.Layout;
30  import org.apache.log4j.bridge.LayoutWrapper;
31  import org.apache.log4j.builders.AbstractBuilder;
32  import org.apache.log4j.config.Log4j1Configuration;
33  import org.apache.log4j.config.PropertiesConfiguration;
34  import org.apache.log4j.xml.XmlConfiguration;
35  import org.apache.logging.log4j.Logger;
36  import org.apache.logging.log4j.core.config.plugins.Plugin;
37  import org.apache.logging.log4j.core.layout.PatternLayout;
38  import org.apache.logging.log4j.status.StatusLogger;
39  import org.w3c.dom.Element;
40  
41  /**
42   * Build a Pattern Layout
43   */
44  @Plugin(name = "org.apache.log4j.TTCCLayout", category = CATEGORY)
45  public class TTCCLayoutBuilder extends AbstractBuilder implements LayoutBuilder {
46  
47      private static final Logger LOGGER = StatusLogger.getLogger();
48  
49      private static final String THREAD_PRINTING_PARAM = "ThreadPrinting";
50      private static final String CATEGORY_PREFIXING_PARAM = "CategoryPrefixing";
51      private static final String CONTEXT_PRINTING_PARAM = "ContextPrinting";
52      private static final String DATE_FORMAT_PARAM = "DateFormat";
53      private static final String TIMEZONE_FORMAT = "TimeZone";
54  
55      public TTCCLayoutBuilder() {
56      }
57  
58      public TTCCLayoutBuilder(String prefix, Properties props) {
59          super(prefix, props);
60      }
61  
62      @Override
63      public Layout parseLayout(Element layoutElement, XmlConfiguration config) {
64          final AtomicBoolean threadPrinting = new AtomicBoolean();
65          final AtomicBoolean categoryPrefixing = new AtomicBoolean();
66          final AtomicBoolean contextPrinting = new AtomicBoolean();
67          final AtomicReference<String> dateFormat = new AtomicReference<>();
68          final AtomicReference<String> timezone = new AtomicReference<>();
69          forEachElement(layoutElement.getElementsByTagName("param"), currentElement -> {
70              if (currentElement.getTagName().equals(PARAM_TAG)) {
71                  switch (currentElement.getAttribute(NAME_ATTR)) {
72                      case THREAD_PRINTING_PARAM:
73                          threadPrinting.set(Boolean.parseBoolean(currentElement.getAttribute(VALUE_ATTR)));
74                          break;
75                      case CATEGORY_PREFIXING_PARAM:
76                          categoryPrefixing.set(Boolean.parseBoolean(currentElement.getAttribute(VALUE_ATTR)));
77                          break;
78                      case CONTEXT_PRINTING_PARAM:
79                          contextPrinting.set(Boolean.parseBoolean(currentElement.getAttribute(VALUE_ATTR)));
80                          break;
81                      case DATE_FORMAT_PARAM:
82                          dateFormat.set(currentElement.getAttribute(VALUE_ATTR));
83                          break;
84                      case TIMEZONE_FORMAT:
85                          timezone.set(currentElement.getAttribute(VALUE_ATTR));
86                          break;
87                  }
88              }
89          });
90          return createLayout(threadPrinting.get(), categoryPrefixing.get(), contextPrinting.get(),
91                  dateFormat.get(), timezone.get(), config);
92      }
93  
94      @Override
95      public Layout parseLayout(PropertiesConfiguration config) {
96          boolean threadPrinting = getBooleanProperty(THREAD_PRINTING_PARAM);
97          boolean categoryPrefixing = getBooleanProperty(CATEGORY_PREFIXING_PARAM);
98          boolean contextPrinting = getBooleanProperty(CONTEXT_PRINTING_PARAM);
99          String dateFormat = getProperty(DATE_FORMAT_PARAM);
100         String timezone = getProperty(TIMEZONE_FORMAT);
101 
102         return createLayout(threadPrinting, categoryPrefixing, contextPrinting,
103                 dateFormat, timezone, config);
104     }
105 
106     private Layout createLayout(boolean threadPrinting, boolean categoryPrefixing, boolean contextPrinting,
107             String dateFormat, String timezone, Log4j1Configuration config) {
108         StringBuilder sb = new StringBuilder();
109         if (dateFormat != null) {
110             if (RELATIVE.equalsIgnoreCase(dateFormat)) {
111                 sb.append("%r ");
112             } else {
113                 sb.append("%d{").append(dateFormat).append("}");
114                 if (timezone != null) {
115                     sb.append("{").append(timezone).append("}");
116                 }
117                 sb.append(" ");
118             }
119         }
120         if (threadPrinting) {
121             sb.append("[%t] ");
122         }
123         sb.append("%p ");
124         if (categoryPrefixing) {
125             sb.append("%c ");
126         }
127         if (contextPrinting) {
128             sb.append("%notEmpty{%ndc }");
129         }
130         sb.append("- %m%n");
131         return new LayoutWrapper(PatternLayout.newBuilder()
132                 .withPattern(sb.toString())
133                 .withConfiguration(config)
134                 .build());
135     }
136 }