001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache license, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License. You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the license for the specific language governing permissions and
015     * limitations under the license.
016     */
017    package org.apache.logging.log4j.core.layout;
018    
019    import java.nio.charset.Charset;
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import org.apache.logging.log4j.core.config.plugins.Plugin;
024    import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
025    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
026    import org.apache.logging.log4j.core.jackson.XmlConstants;
027    import org.apache.logging.log4j.core.util.Charsets;
028    
029    /**
030     * Appends a series of {@code event} elements as defined in the <a href="log4j.dtd">log4j.dtd</a>.
031     *
032     * <h4>Complete well-formed XML vs. fragment XML</h4>
033     * <p>
034     * If you configure {@code complete="true"}, the appender outputs a well-formed XML document where the default namespace is the log4j
035     * namespace {@value XmlConstants#XML_NAMESPACE}. By default, with {@code complete="false"}, you should include the output as an
036     * <em>external entity</em> in a separate file to form a well-formed XML document.
037     * </p>
038     * <p>
039     * A well-formed XML document follows this pattern:
040     * </p>
041     * <pre>
042    &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;
043        &lt;Marker name=&quot;Marker1&quot;&gt;
044            &lt;Parents&gt;
045                &lt;Parents name=&quot;ParentMarker1&quot;&gt;
046                    &lt;Parents&gt;
047                        &lt;Parents name=&quot;GrandMotherMarker&quot;/&gt;
048                        &lt;Parents name=&quot;GrandFatherMarker&quot;/&gt;
049                    &lt;/Parents&gt;
050                &lt;/Parents&gt;
051                &lt;Parents name=&quot;GrandFatherMarker&quot;/&gt;
052            &lt;/Parents&gt;
053        &lt;/Marker&gt;
054        &lt;Message&gt;Msg&lt;/Message&gt;
055        &lt;ContextMap&gt;
056            &lt;item key=&quot;MDC.B&quot; value=&quot;B_Value&quot;/&gt;
057            &lt;item key=&quot;MDC.A&quot; value=&quot;A_Value&quot;/&gt;
058        &lt;/ContextMap&gt;
059        &lt;ContextStack&gt;
060            &lt;ContextStack&gt;stack_msg1&lt;/ContextStack&gt;
061            &lt;ContextStack&gt;stack_msg2&lt;/ContextStack&gt;
062        &lt;/ContextStack&gt;
063        &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;
064        &lt;Thrown commonElementCount=&quot;0&quot; localizedMessage=&quot;testIOEx&quot; message=&quot;testIOEx&quot; name=&quot;java.io.IOException&quot;&gt;
065            &lt;Cause commonElementCount=&quot;27&quot; localizedMessage=&quot;testNPEx&quot; message=&quot;testNPEx&quot; name=&quot;java.lang.NullPointerException&quot;&gt;
066                &lt;ExtendedStackTrace&gt;
067                    &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;
068                &lt;/ExtendedStackTrace&gt;
069            &lt;/Cause&gt;
070            &lt;ExtendedStackTrace&gt;
071                &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;
072                &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;
073                &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;
074                &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;
075                &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;
076                &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;
077                &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;
078                &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;
079                &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;
080                &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;
081                &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;
082                &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;
083                &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;
084                &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;
085                &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;
086                &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;
087                &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;
088                &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;
089                &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;
090                &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;
091                &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;
092                &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;
093                &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;
094                &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;
095                &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;
096                &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;
097                &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;
098                &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;
099            &lt;/ExtendedStackTrace&gt;
100            &lt;Suppressed&gt;
101                &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;
102                    &lt;ExtendedStackTrace&gt;
103                        &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;
104                        &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;
105                        &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;
106                        &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;
107                        &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;
108                        &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;
109                        &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;
110                        &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;
111                        &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;
112                        &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;
113                        &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;
114                        &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;
115                        &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;
116                        &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;
117                        &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;
118                        &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;
119                        &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;
120                        &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;
121                        &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;
122                        &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;
123                        &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;
124                        &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;
125                        &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;
126                        &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;
127                        &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;
128                        &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;
129                        &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;
130                        &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;
131                    &lt;/ExtendedStackTrace&gt;
132                &lt;/Suppressed&gt;
133                &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;
134                    &lt;ExtendedStackTrace&gt;
135                        &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;
136                        &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;
137                        &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;
138                        &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;
139                        &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;
140                        &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;
141                        &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;
142                        &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;
143                        &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;
144                        &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;
145                        &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;
146                        &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;
147                        &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;
148                        &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;
149                        &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;
150                        &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;
151                        &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;
152                        &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;
153                        &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;
154                        &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;
155                        &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;
156                        &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;
157                        &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;
158                        &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;
159                        &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;
160                        &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;
161                        &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;
162                        &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;
163                    &lt;/ExtendedStackTrace&gt;
164                &lt;/Suppressed&gt;
165            &lt;/Suppressed&gt;
166        &lt;/Thrown&gt;
167    &lt;/Event&gt;
168    </pre>
169     * <p>
170     * If {@code complete="false"}, the appender does not write the XML processing instruction and the root element.
171     * </p>
172     * <p>
173     * This approach enforces the independence of the XmlLayout and the appender where you embed it.
174     * </p>
175     * <h4>Encoding</h4>
176     * <p>
177     * Appenders using this layout should have their {@code charset} set to {@code UTF-8} or {@code UTF-16}, otherwise events containing non
178     * ASCII characters could result in corrupted log files.
179     * </p>
180     * <h4>Pretty vs. compact XML</h4>
181     * <p>
182     * By default, the XML layout is not compact (compact = not "pretty") with {@code compact="false"}, which means the appender uses
183     * end-of-line characters and indents lines to format the XML. If {@code compact="true"}, then no end-of-line or indentation is used.
184     * Message content may contain, of course, end-of-lines.
185     * </p>
186     */
187    @Plugin(name = "XmlLayout", category = "Core", elementType = "layout", printObject = true)
188    public final class XmlLayout extends AbstractJacksonLayout {
189    
190        private static final String ROOT_TAG = "Events";
191    
192        protected XmlLayout(final boolean locationInfo, final boolean properties, final boolean complete, final boolean compact, final Charset charset) {
193            super(new JacksonFactory.XML().newWriter(locationInfo, properties, compact), charset, compact, complete);
194        }
195    
196        /**
197         * Returns appropriate XML headers.
198         * <ol>
199         * <li>XML processing instruction</li>
200         * <li>XML root element</li>
201         * </ol>
202         *
203         * @return a byte array containing the header.
204         */
205        @Override
206        public byte[] getHeader() {
207            if (!complete) {
208                return null;
209            }
210            final StringBuilder buf = new StringBuilder();
211            buf.append("<?xml version=\"1.0\" encoding=\"");
212            buf.append(this.getCharset().name());
213            buf.append("\"?>");
214            buf.append(this.eol);
215            // Make the log4j namespace the default namespace, no need to use more space with a namespace prefix.
216            buf.append('<');
217            buf.append(ROOT_TAG);
218            buf.append(" xmlns=\"" + XmlConstants.XML_NAMESPACE + "\">");
219            buf.append(this.eol);
220            return buf.toString().getBytes(this.getCharset());
221        }
222    
223        /**
224         * Returns appropriate XML footer.
225         *
226         * @return a byte array containing the footer, closing the XML root element.
227         */
228        @Override
229        public byte[] getFooter() {
230            if (!complete) {
231                return null;
232            }
233            return ("</" + ROOT_TAG + '>' + this.eol).getBytes(getCharset());
234        }
235    
236        /**
237         * XmlLayout's content format is specified by:
238         * <p/>
239         * Key: "dtd" Value: "log4j-events.dtd"
240         * <p/>
241         * Key: "version" Value: "2.0"
242         *
243         * @return Map of content format keys supporting XmlLayout
244         */
245        @Override
246        public Map<String, String> getContentFormat() {
247            final Map<String, String> result = new HashMap<String, String>();
248            // result.put("dtd", "log4j-events.dtd");
249            result.put("xsd", "log4j-events.xsd");
250            result.put("version", "2.0");
251            return result;
252        }
253    
254        @Override
255        /**
256         * @return The content type.
257         */
258        public String getContentType() {
259            return "text/xml; charset=" + this.getCharset();
260        }
261    
262        /**
263         * Creates an XML Layout.
264         *
265         * @param locationInfo If "true", includes the location information in the generated XML.
266         * @param properties If "true", includes the thread context in the generated XML.
267         * @param complete If "true", includes the XML header and footer, defaults to "false".
268         * @param compact If "true", does not use end-of-lines and indentation, defaults to "false".
269         * @param charset The character set to use, if {@code null}, uses "UTF-8".
270         * @return An XML Layout.
271         */
272        @PluginFactory
273        public static XmlLayout createLayout(
274                // @formatter:off
275                @PluginAttribute(value = "locationInfo", defaultBoolean = false) final boolean locationInfo,
276                @PluginAttribute(value = "properties", defaultBoolean = false) final boolean properties,
277                @PluginAttribute(value = "complete", defaultBoolean = false) final boolean complete,
278                @PluginAttribute(value = "compact", defaultBoolean = false) final boolean compact,
279                @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset)
280                // @formatter:on
281        {
282            return new XmlLayout(locationInfo, properties, complete, compact, charset);
283        }
284    
285        /**
286         * Creates an XML Layout using the default settings.
287         *
288         * @return an XML Layout.
289         */
290        public static XmlLayout createDefaultLayout() {
291            return new XmlLayout(false, false, false, false, Charsets.UTF_8);
292        }
293    }