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.layout;
    18
    19  import java.nio.charset.Charset;
    20  import java.util.HashMap;
    21  import java.util.Map;
    22
    23  import org.apache.logging.log4j.core.Layout;
    24  import org.apache.logging.log4j.core.config.Node;
    25  import org.apache.logging.log4j.core.config.plugins.Plugin;
    26  import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
    27  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
    28  import org.apache.logging.log4j.core.jackson.XmlConstants;
    29  import org.apache.logging.log4j.core.util.Constants;
    30
    31  /**
    32   * Appends a series of {@code event} elements as defined in the <a href="log4j.dtd">log4j.dtd</a>.
    33   *
    34   * <h3>Complete well-formed XML vs. fragment XML</h3>
    35   * <p>
    36   * If you configure {@code complete="true"}, the appender outputs a well-formed XML document where the default namespace is the log4j
    37   * namespace {@value XmlConstants#XML_NAMESPACE}. By default, with {@code complete="false"}, you should include the output as an
    38   * <em>external entity</em> in a separate file to form a well-formed XML document.
    39   * </p>
    40   * <p>
    41   * A well-formed XML document follows this pattern:
    42   * </p>
    43   * <pre>
    44  &lt;Event xmlns=&quot;http://logging.apache.org/log4j/2.0/events&quot; timeMillis=&quot;1&quot; thread=&quot;MyThreadName&quot; level=&quot;DEBUG&quot; loggerName=&quot;a.B&quot; loggerFQCN=&quot;f.q.c.n&quot; endOfBatch=&quot;false&quot;&gt;
    45      &lt;Marker name=&quot;Marker1&quot;&gt;
    46          &lt;Parents&gt;
    47              &lt;Parents name=&quot;ParentMarker1&quot;&gt;
    48                  &lt;Parents&gt;
    49                      &lt;Parents name=&quot;GrandMotherMarker&quot;/&gt;
    50                      &lt;Parents name=&quot;GrandFatherMarker&quot;/&gt;
    51                  &lt;/Parents&gt;
    52              &lt;/Parents&gt;
    53              &lt;Parents name=&quot;GrandFatherMarker&quot;/&gt;
    54          &lt;/Parents&gt;
    55      &lt;/Marker&gt;
    56      &lt;Message&gt;Msg&lt;/Message&gt;
    57      &lt;ContextMap&gt;
    58          &lt;item key=&quot;MDC.B&quot; value=&quot;B_Value&quot;/&gt;
    59          &lt;item key=&quot;MDC.A&quot; value=&quot;A_Value&quot;/&gt;
    60      &lt;/ContextMap&gt;
    61      &lt;ContextStack&gt;
    62          &lt;ContextStack&gt;stack_msg1&lt;/ContextStack&gt;
    63          &lt;ContextStack&gt;stack_msg2&lt;/ContextStack&gt;
    64      &lt;/ContextStack&gt;
    65      &lt;Source class=&quot;org.apache.logging.log4j.core.layout.LogEventFixtures&quot; method=&quot;createLogEvent&quot; file=&quot;LogEventFixtures.java&quot; line=&quot;54&quot;/&gt;
    66      &lt;Thrown commonElementCount=&quot;0&quot; localizedMessage=&quot;testIOEx&quot; message=&quot;testIOEx&quot; name=&quot;java.io.IOException&quot;&gt;
    67          &lt;Cause commonElementCount=&quot;27&quot; localizedMessage=&quot;testNPEx&quot; message=&quot;testNPEx&quot; name=&quot;java.lang.NullPointerException&quot;&gt;
    68              &lt;ExtendedStackTrace&gt;
    69                  &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.LogEventFixtures&quot; method=&quot;createLogEvent&quot; file=&quot;LogEventFixtures.java&quot; line=&quot;53&quot; exact=&quot;false&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    70              &lt;/ExtendedStackTrace&gt;
    71          &lt;/Cause&gt;
    72          &lt;ExtendedStackTrace&gt;
    73              &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.LogEventFixtures&quot; method=&quot;createLogEvent&quot; file=&quot;LogEventFixtures.java&quot; line=&quot;56&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    74              &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.XmlLayoutTest&quot; method=&quot;testAllFeatures&quot; file=&quot;XmlLayoutTest.java&quot; line=&quot;122&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    75              &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.XmlLayoutTest&quot; method=&quot;testLocationOnCompactOnMdcOn&quot; file=&quot;XmlLayoutTest.java&quot; line=&quot;270&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    76              &lt;ExtendedStackTrace class=&quot;sun.reflect.NativeMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    77              &lt;ExtendedStackTrace class=&quot;sun.reflect.NativeMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    78              &lt;ExtendedStackTrace class=&quot;sun.reflect.DelegatingMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    79              &lt;ExtendedStackTrace class=&quot;java.lang.reflect.Method&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    80              &lt;ExtendedStackTrace class=&quot;org.junit.runners.model.FrameworkMethod$1&quot; method=&quot;runReflectiveCall&quot; file=&quot;FrameworkMethod.java&quot; line=&quot;47&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    81              &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.model.ReflectiveCallable&quot; method=&quot;run&quot; file=&quot;ReflectiveCallable.java&quot; line=&quot;12&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    82              &lt;ExtendedStackTrace class=&quot;org.junit.runners.model.FrameworkMethod&quot; method=&quot;invokeExplosively&quot; file=&quot;FrameworkMethod.java&quot; line=&quot;44&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    83              &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.InvokeMethod&quot; method=&quot;evaluate&quot; file=&quot;InvokeMethod.java&quot; line=&quot;17&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    84              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;runLeaf&quot; file=&quot;ParentRunner.java&quot; line=&quot;271&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    85              &lt;ExtendedStackTrace class=&quot;org.junit.runners.BlockJUnit4ClassRunner&quot; method=&quot;runChild&quot; file=&quot;BlockJUnit4ClassRunner.java&quot; line=&quot;70&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    86              &lt;ExtendedStackTrace class=&quot;org.junit.runners.BlockJUnit4ClassRunner&quot; method=&quot;runChild&quot; file=&quot;BlockJUnit4ClassRunner.java&quot; line=&quot;50&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    87              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$3&quot; method=&quot;run&quot; file=&quot;ParentRunner.java&quot; line=&quot;238&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    88              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$1&quot; method=&quot;schedule&quot; file=&quot;ParentRunner.java&quot; line=&quot;63&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    89              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;runChildren&quot; file=&quot;ParentRunner.java&quot; line=&quot;236&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    90              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;access$000&quot; file=&quot;ParentRunner.java&quot; line=&quot;53&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    91              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$2&quot; method=&quot;evaluate&quot; file=&quot;ParentRunner.java&quot; line=&quot;229&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    92              &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.RunBefores&quot; method=&quot;evaluate&quot; file=&quot;RunBefores.java&quot; line=&quot;26&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    93              &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.RunAfters&quot; method=&quot;evaluate&quot; file=&quot;RunAfters.java&quot; line=&quot;27&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    94              &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;run&quot; file=&quot;ParentRunner.java&quot; line=&quot;309&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    95              &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference&quot; method=&quot;run&quot; file=&quot;JUnit4TestReference.java&quot; line=&quot;50&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    96              &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.TestExecution&quot; method=&quot;run&quot; file=&quot;TestExecution.java&quot; line=&quot;38&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    97              &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;runTests&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;467&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    98              &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;runTests&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;683&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    99              &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;run&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;390&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    100             &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;main&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;197&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    101         &lt;/ExtendedStackTrace&gt;
    102         &lt;Suppressed&gt;
    103             &lt;Suppressed commonElementCount=&quot;0&quot; localizedMessage=&quot;I am suppressed exception 1&quot; message=&quot;I am suppressed exception 1&quot; name=&quot;java.lang.IndexOutOfBoundsException&quot;&gt;
    104                 &lt;ExtendedStackTrace&gt;
    105                     &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.LogEventFixtures&quot; method=&quot;createLogEvent&quot; file=&quot;LogEventFixtures.java&quot; line=&quot;57&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    106                     &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.XmlLayoutTest&quot; method=&quot;testAllFeatures&quot; file=&quot;XmlLayoutTest.java&quot; line=&quot;122&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    107                     &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.XmlLayoutTest&quot; method=&quot;testLocationOnCompactOnMdcOn&quot; file=&quot;XmlLayoutTest.java&quot; line=&quot;270&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    108                     &lt;ExtendedStackTrace class=&quot;sun.reflect.NativeMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    109                     &lt;ExtendedStackTrace class=&quot;sun.reflect.NativeMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    110                     &lt;ExtendedStackTrace class=&quot;sun.reflect.DelegatingMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    111                     &lt;ExtendedStackTrace class=&quot;java.lang.reflect.Method&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    112                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.model.FrameworkMethod$1&quot; method=&quot;runReflectiveCall&quot; file=&quot;FrameworkMethod.java&quot; line=&quot;47&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    113                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.model.ReflectiveCallable&quot; method=&quot;run&quot; file=&quot;ReflectiveCallable.java&quot; line=&quot;12&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    114                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.model.FrameworkMethod&quot; method=&quot;invokeExplosively&quot; file=&quot;FrameworkMethod.java&quot; line=&quot;44&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    115                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.InvokeMethod&quot; method=&quot;evaluate&quot; file=&quot;InvokeMethod.java&quot; line=&quot;17&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    116                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;runLeaf&quot; file=&quot;ParentRunner.java&quot; line=&quot;271&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    117                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.BlockJUnit4ClassRunner&quot; method=&quot;runChild&quot; file=&quot;BlockJUnit4ClassRunner.java&quot; line=&quot;70&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    118                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.BlockJUnit4ClassRunner&quot; method=&quot;runChild&quot; file=&quot;BlockJUnit4ClassRunner.java&quot; line=&quot;50&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    119                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$3&quot; method=&quot;run&quot; file=&quot;ParentRunner.java&quot; line=&quot;238&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    120                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$1&quot; method=&quot;schedule&quot; file=&quot;ParentRunner.java&quot; line=&quot;63&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    121                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;runChildren&quot; file=&quot;ParentRunner.java&quot; line=&quot;236&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    122                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;access$000&quot; file=&quot;ParentRunner.java&quot; line=&quot;53&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    123                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$2&quot; method=&quot;evaluate&quot; file=&quot;ParentRunner.java&quot; line=&quot;229&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    124                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.RunBefores&quot; method=&quot;evaluate&quot; file=&quot;RunBefores.java&quot; line=&quot;26&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    125                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.RunAfters&quot; method=&quot;evaluate&quot; file=&quot;RunAfters.java&quot; line=&quot;27&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    126                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;run&quot; file=&quot;ParentRunner.java&quot; line=&quot;309&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    127                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference&quot; method=&quot;run&quot; file=&quot;JUnit4TestReference.java&quot; line=&quot;50&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    128                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.TestExecution&quot; method=&quot;run&quot; file=&quot;TestExecution.java&quot; line=&quot;38&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    129                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;runTests&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;467&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    130                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;runTests&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;683&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    131                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;run&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;390&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    132                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;main&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;197&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    133                 &lt;/ExtendedStackTrace&gt;
    134             &lt;/Suppressed&gt;
    135             &lt;Suppressed commonElementCount=&quot;0&quot; localizedMessage=&quot;I am suppressed exception 2&quot; message=&quot;I am suppressed exception 2&quot; name=&quot;java.lang.IndexOutOfBoundsException&quot;&gt;
    136                 &lt;ExtendedStackTrace&gt;
    137                     &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.LogEventFixtures&quot; method=&quot;createLogEvent&quot; file=&quot;LogEventFixtures.java&quot; line=&quot;58&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    138                     &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.XmlLayoutTest&quot; method=&quot;testAllFeatures&quot; file=&quot;XmlLayoutTest.java&quot; line=&quot;122&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    139                     &lt;ExtendedStackTrace class=&quot;org.apache.logging.log4j.core.layout.XmlLayoutTest&quot; method=&quot;testLocationOnCompactOnMdcOn&quot; file=&quot;XmlLayoutTest.java&quot; line=&quot;270&quot; exact=&quot;true&quot; location=&quot;test-classes/&quot; version=&quot;?&quot;/&gt;
    140                     &lt;ExtendedStackTrace class=&quot;sun.reflect.NativeMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    141                     &lt;ExtendedStackTrace class=&quot;sun.reflect.NativeMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    142                     &lt;ExtendedStackTrace class=&quot;sun.reflect.DelegatingMethodAccessorImpl&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    143                     &lt;ExtendedStackTrace class=&quot;java.lang.reflect.Method&quot; method=&quot;invoke&quot; line=&quot;-1&quot; exact=&quot;false&quot; location=&quot;?&quot; version=&quot;1.7.0_55&quot;/&gt;
    144                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.model.FrameworkMethod$1&quot; method=&quot;runReflectiveCall&quot; file=&quot;FrameworkMethod.java&quot; line=&quot;47&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    145                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.model.ReflectiveCallable&quot; method=&quot;run&quot; file=&quot;ReflectiveCallable.java&quot; line=&quot;12&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    146                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.model.FrameworkMethod&quot; method=&quot;invokeExplosively&quot; file=&quot;FrameworkMethod.java&quot; line=&quot;44&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    147                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.InvokeMethod&quot; method=&quot;evaluate&quot; file=&quot;InvokeMethod.java&quot; line=&quot;17&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    148                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;runLeaf&quot; file=&quot;ParentRunner.java&quot; line=&quot;271&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    149                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.BlockJUnit4ClassRunner&quot; method=&quot;runChild&quot; file=&quot;BlockJUnit4ClassRunner.java&quot; line=&quot;70&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    150                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.BlockJUnit4ClassRunner&quot; method=&quot;runChild&quot; file=&quot;BlockJUnit4ClassRunner.java&quot; line=&quot;50&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    151                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$3&quot; method=&quot;run&quot; file=&quot;ParentRunner.java&quot; line=&quot;238&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    152                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$1&quot; method=&quot;schedule&quot; file=&quot;ParentRunner.java&quot; line=&quot;63&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    153                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;runChildren&quot; file=&quot;ParentRunner.java&quot; line=&quot;236&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    154                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;access$000&quot; file=&quot;ParentRunner.java&quot; line=&quot;53&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    155                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner$2&quot; method=&quot;evaluate&quot; file=&quot;ParentRunner.java&quot; line=&quot;229&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    156                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.RunBefores&quot; method=&quot;evaluate&quot; file=&quot;RunBefores.java&quot; line=&quot;26&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    157                     &lt;ExtendedStackTrace class=&quot;org.junit.internal.runners.statements.RunAfters&quot; method=&quot;evaluate&quot; file=&quot;RunAfters.java&quot; line=&quot;27&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    158                     &lt;ExtendedStackTrace class=&quot;org.junit.runners.ParentRunner&quot; method=&quot;run&quot; file=&quot;ParentRunner.java&quot; line=&quot;309&quot; exact=&quot;true&quot; location=&quot;junit-4.11.jar&quot; version=&quot;?&quot;/&gt;
    159                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference&quot; method=&quot;run&quot; file=&quot;JUnit4TestReference.java&quot; line=&quot;50&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    160                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.TestExecution&quot; method=&quot;run&quot; file=&quot;TestExecution.java&quot; line=&quot;38&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    161                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;runTests&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;467&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    162                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;runTests&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;683&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    163                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;run&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;390&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    164                     &lt;ExtendedStackTrace class=&quot;org.eclipse.jdt.internal.junit.runner.RemoteTestRunner&quot; method=&quot;main&quot; file=&quot;RemoteTestRunner.java&quot; line=&quot;197&quot; exact=&quot;true&quot; location=&quot;.cp/&quot; version=&quot;?&quot;/&gt;
    165                 &lt;/ExtendedStackTrace&gt;
    166             &lt;/Suppressed&gt;
    167         &lt;/Suppressed&gt;
    168     &lt;/Thrown&gt;
    169 &lt;/Event&gt;
    170 </pre>
    171  * <p>
    172  * If {@code complete="false"}, the appender does not write the XML processing instruction and the root element.
    173  * </p>
    174  * <p>
    175  * This approach enforces the independence of the XmlLayout and the appender where you embed it.
    176  * </p>
    177  * <h3>Encoding</h3>
    178  * <p>
    179  * Appenders using this layout should have their {@code charset} set to {@code UTF-8} or {@code UTF-16}, otherwise events containing non
    180  * ASCII characters could result in corrupted log files.
    181  * </p>
    182  * <h3>Pretty vs. compact XML</h3>
    183  * <p>
    184  * By default, the XML layout is not compact (compact = not "pretty") with {@code compact="false"}, which means the appender uses
    185  * end-of-line characters and indents lines to format the XML. If {@code compact="true"}, then no end-of-line or indentation is used.
    186  * Message content may contain, of course, end-of-lines.
    187  * </p>
    188  */
    189 @Plugin(name = "XmlLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
    190 public final class XmlLayout extends AbstractJacksonLayout {
    191
    192     private static final long serialVersionUID = 1L;
    193
    194     private static final String ROOT_TAG = "Events";
    195
    196     protected XmlLayout(final boolean locationInfo, final boolean properties, final boolean complete, final boolean compact, final Charset charset) {
    197         super(new JacksonFactory.XML().newWriter(locationInfo, properties, compact), charset, compact, complete, false);
    198     }
    199
    200     /**
    201      * Returns appropriate XML headers.
    202      * <ol>
    203      * <li>XML processing instruction</li>
    204      * <li>XML root element</li>
    205      * </ol>
    206      *
    207      * @return a byte array containing the header.
    208      */
    209     @Override
    210     public byte[] getHeader() {
    211         if (!complete) {
    212             return null;
    213         }
    214         final StringBuilder buf = new StringBuilder();
    215         buf.append("<?xml version=\"1.0\" encoding=\"");
    216         buf.append(this.getCharset().name());
    217         buf.append("\"?>");
    218         buf.append(this.eol);
    219         // Make the log4j namespace the default namespace, no need to use more space with a namespace prefix.
    220         buf.append('<');
    221         buf.append(ROOT_TAG);
    222         buf.append(" xmlns=\"" + XmlConstants.XML_NAMESPACE + "\">");
    223         buf.append(this.eol);
    224         return buf.toString().getBytes(this.getCharset());
    225     }
    226
    227     /**
    228      * Returns appropriate XML footer.
    229      *
    230      * @return a byte array containing the footer, closing the XML root element.
    231      */
    232     @Override
    233     public byte[] getFooter() {
    234         if (!complete) {
    235             return null;
    236         }
    237         return getBytes("</" + ROOT_TAG + '>' + this.eol);
    238     }
    239
    240     /**
    241      * Gets this XmlLayout's content format. Specified by:
    242      * <ul>
    243      * <li>Key: "dtd" Value: "log4j-events.dtd"</li>
    244      * <li>Key: "version" Value: "2.0"</li>
    245      * </ul>
    246      *
    247      * @return Map of content format keys supporting XmlLayout
    248      */
    249     @Override
    250     public Map<String, String> getContentFormat() {
    251         final Map<String, String> result = new HashMap<String, String>();
    252         // result.put("dtd", "log4j-events.dtd");
    253         result.put("xsd", "log4j-events.xsd");
    254         result.put("version", "2.0");
    255         return result;
    256     }
    257
    258     @Override
    259     /**
    260      * @return The content type.
    261      */
    262     public String getContentType() {
    263         return "text/xml; charset=" + this.getCharset();
    264     }
    265
    266     /**
    267      * Creates an XML Layout.
    268      *
    269      * @param locationInfo If "true", includes the location information in the generated XML.
    270      * @param properties If "true", includes the thread context in the generated XML.
    271      * @param complete If "true", includes the XML header and footer, defaults to "false".
    272      * @param compact If "true", does not use end-of-lines and indentation, defaults to "false".
    273      * @param charset The character set to use, if {@code null}, uses "UTF-8".
    274      * @return An XML Layout.
    275      */
    276     @PluginFactory
    277     public static XmlLayout createLayout(
    278             // @formatter:off
    279             @PluginAttribute(value = "locationInfo", defaultBoolean = false) final boolean locationInfo,
    280             @PluginAttribute(value = "properties", defaultBoolean = false) final boolean properties,
    281             @PluginAttribute(value = "complete", defaultBoolean = false) final boolean complete,
    282             @PluginAttribute(value = "compact", defaultBoolean = false) final boolean compact,
    283             @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset)
    284             // @formatter:on
    285     {
    286         return new XmlLayout(locationInfo, properties, complete, compact, charset);
    287     }
    288
    289     /**
    290      * Creates an XML Layout using the default settings.
    291      *
    292      * @return an XML Layout.
    293      */
    294     public static XmlLayout createDefaultLayout() {
    295         return new XmlLayout(false, false, false, false, Constants.UTF_8);
    296     }
    297 }