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 <Event xmlns="http://logging.apache.org/log4j/2.0/events" timeMillis="1" thread="MyThreadName" level="DEBUG" loggerName="a.B" loggerFQCN="f.q.c.n" endOfBatch="false"> 45 <Marker name="Marker1"> 46 <Parents> 47 <Parents name="ParentMarker1"> 48 <Parents> 49 <Parents name="GrandMotherMarker"/> 50 <Parents name="GrandFatherMarker"/> 51 </Parents> 52 </Parents> 53 <Parents name="GrandFatherMarker"/> 54 </Parents> 55 </Marker> 56 <Message>Msg</Message> 57 <ContextMap> 58 <item key="MDC.B" value="B_Value"/> 59 <item key="MDC.A" value="A_Value"/> 60 </ContextMap> 61 <ContextStack> 62 <ContextStack>stack_msg1</ContextStack> 63 <ContextStack>stack_msg2</ContextStack> 64 </ContextStack> 65 <Source class="org.apache.logging.log4j.core.layout.LogEventFixtures" method="createLogEvent" file="LogEventFixtures.java" line="54"/> 66 <Thrown commonElementCount="0" localizedMessage="testIOEx" message="testIOEx" name="java.io.IOException"> 67 <Cause commonElementCount="27" localizedMessage="testNPEx" message="testNPEx" name="java.lang.NullPointerException"> 68 <ExtendedStackTrace> 69 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.LogEventFixtures" method="createLogEvent" file="LogEventFixtures.java" line="53" exact="false" location="test-classes/" version="?"/> 70 </ExtendedStackTrace> 71 </Cause> 72 <ExtendedStackTrace> 73 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.LogEventFixtures" method="createLogEvent" file="LogEventFixtures.java" line="56" exact="true" location="test-classes/" version="?"/> 74 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.XmlLayoutTest" method="testAllFeatures" file="XmlLayoutTest.java" line="122" exact="true" location="test-classes/" version="?"/> 75 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.XmlLayoutTest" method="testLocationOnCompactOnMdcOn" file="XmlLayoutTest.java" line="270" exact="true" location="test-classes/" version="?"/> 76 <ExtendedStackTrace class="sun.reflect.NativeMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 77 <ExtendedStackTrace class="sun.reflect.NativeMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 78 <ExtendedStackTrace class="sun.reflect.DelegatingMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 79 <ExtendedStackTrace class="java.lang.reflect.Method" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 80 <ExtendedStackTrace class="org.junit.runners.model.FrameworkMethod$1" method="runReflectiveCall" file="FrameworkMethod.java" line="47" exact="true" location="junit-4.11.jar" version="?"/> 81 <ExtendedStackTrace class="org.junit.internal.runners.model.ReflectiveCallable" method="run" file="ReflectiveCallable.java" line="12" exact="true" location="junit-4.11.jar" version="?"/> 82 <ExtendedStackTrace class="org.junit.runners.model.FrameworkMethod" method="invokeExplosively" file="FrameworkMethod.java" line="44" exact="true" location="junit-4.11.jar" version="?"/> 83 <ExtendedStackTrace class="org.junit.internal.runners.statements.InvokeMethod" method="evaluate" file="InvokeMethod.java" line="17" exact="true" location="junit-4.11.jar" version="?"/> 84 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="runLeaf" file="ParentRunner.java" line="271" exact="true" location="junit-4.11.jar" version="?"/> 85 <ExtendedStackTrace class="org.junit.runners.BlockJUnit4ClassRunner" method="runChild" file="BlockJUnit4ClassRunner.java" line="70" exact="true" location="junit-4.11.jar" version="?"/> 86 <ExtendedStackTrace class="org.junit.runners.BlockJUnit4ClassRunner" method="runChild" file="BlockJUnit4ClassRunner.java" line="50" exact="true" location="junit-4.11.jar" version="?"/> 87 <ExtendedStackTrace class="org.junit.runners.ParentRunner$3" method="run" file="ParentRunner.java" line="238" exact="true" location="junit-4.11.jar" version="?"/> 88 <ExtendedStackTrace class="org.junit.runners.ParentRunner$1" method="schedule" file="ParentRunner.java" line="63" exact="true" location="junit-4.11.jar" version="?"/> 89 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="runChildren" file="ParentRunner.java" line="236" exact="true" location="junit-4.11.jar" version="?"/> 90 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="access$000" file="ParentRunner.java" line="53" exact="true" location="junit-4.11.jar" version="?"/> 91 <ExtendedStackTrace class="org.junit.runners.ParentRunner$2" method="evaluate" file="ParentRunner.java" line="229" exact="true" location="junit-4.11.jar" version="?"/> 92 <ExtendedStackTrace class="org.junit.internal.runners.statements.RunBefores" method="evaluate" file="RunBefores.java" line="26" exact="true" location="junit-4.11.jar" version="?"/> 93 <ExtendedStackTrace class="org.junit.internal.runners.statements.RunAfters" method="evaluate" file="RunAfters.java" line="27" exact="true" location="junit-4.11.jar" version="?"/> 94 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="run" file="ParentRunner.java" line="309" exact="true" location="junit-4.11.jar" version="?"/> 95 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference" method="run" file="JUnit4TestReference.java" line="50" exact="true" location=".cp/" version="?"/> 96 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.TestExecution" method="run" file="TestExecution.java" line="38" exact="true" location=".cp/" version="?"/> 97 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="runTests" file="RemoteTestRunner.java" line="467" exact="true" location=".cp/" version="?"/> 98 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="runTests" file="RemoteTestRunner.java" line="683" exact="true" location=".cp/" version="?"/> 99 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="run" file="RemoteTestRunner.java" line="390" exact="true" location=".cp/" version="?"/> 100 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="main" file="RemoteTestRunner.java" line="197" exact="true" location=".cp/" version="?"/> 101 </ExtendedStackTrace> 102 <Suppressed> 103 <Suppressed commonElementCount="0" localizedMessage="I am suppressed exception 1" message="I am suppressed exception 1" name="java.lang.IndexOutOfBoundsException"> 104 <ExtendedStackTrace> 105 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.LogEventFixtures" method="createLogEvent" file="LogEventFixtures.java" line="57" exact="true" location="test-classes/" version="?"/> 106 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.XmlLayoutTest" method="testAllFeatures" file="XmlLayoutTest.java" line="122" exact="true" location="test-classes/" version="?"/> 107 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.XmlLayoutTest" method="testLocationOnCompactOnMdcOn" file="XmlLayoutTest.java" line="270" exact="true" location="test-classes/" version="?"/> 108 <ExtendedStackTrace class="sun.reflect.NativeMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 109 <ExtendedStackTrace class="sun.reflect.NativeMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 110 <ExtendedStackTrace class="sun.reflect.DelegatingMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 111 <ExtendedStackTrace class="java.lang.reflect.Method" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 112 <ExtendedStackTrace class="org.junit.runners.model.FrameworkMethod$1" method="runReflectiveCall" file="FrameworkMethod.java" line="47" exact="true" location="junit-4.11.jar" version="?"/> 113 <ExtendedStackTrace class="org.junit.internal.runners.model.ReflectiveCallable" method="run" file="ReflectiveCallable.java" line="12" exact="true" location="junit-4.11.jar" version="?"/> 114 <ExtendedStackTrace class="org.junit.runners.model.FrameworkMethod" method="invokeExplosively" file="FrameworkMethod.java" line="44" exact="true" location="junit-4.11.jar" version="?"/> 115 <ExtendedStackTrace class="org.junit.internal.runners.statements.InvokeMethod" method="evaluate" file="InvokeMethod.java" line="17" exact="true" location="junit-4.11.jar" version="?"/> 116 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="runLeaf" file="ParentRunner.java" line="271" exact="true" location="junit-4.11.jar" version="?"/> 117 <ExtendedStackTrace class="org.junit.runners.BlockJUnit4ClassRunner" method="runChild" file="BlockJUnit4ClassRunner.java" line="70" exact="true" location="junit-4.11.jar" version="?"/> 118 <ExtendedStackTrace class="org.junit.runners.BlockJUnit4ClassRunner" method="runChild" file="BlockJUnit4ClassRunner.java" line="50" exact="true" location="junit-4.11.jar" version="?"/> 119 <ExtendedStackTrace class="org.junit.runners.ParentRunner$3" method="run" file="ParentRunner.java" line="238" exact="true" location="junit-4.11.jar" version="?"/> 120 <ExtendedStackTrace class="org.junit.runners.ParentRunner$1" method="schedule" file="ParentRunner.java" line="63" exact="true" location="junit-4.11.jar" version="?"/> 121 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="runChildren" file="ParentRunner.java" line="236" exact="true" location="junit-4.11.jar" version="?"/> 122 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="access$000" file="ParentRunner.java" line="53" exact="true" location="junit-4.11.jar" version="?"/> 123 <ExtendedStackTrace class="org.junit.runners.ParentRunner$2" method="evaluate" file="ParentRunner.java" line="229" exact="true" location="junit-4.11.jar" version="?"/> 124 <ExtendedStackTrace class="org.junit.internal.runners.statements.RunBefores" method="evaluate" file="RunBefores.java" line="26" exact="true" location="junit-4.11.jar" version="?"/> 125 <ExtendedStackTrace class="org.junit.internal.runners.statements.RunAfters" method="evaluate" file="RunAfters.java" line="27" exact="true" location="junit-4.11.jar" version="?"/> 126 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="run" file="ParentRunner.java" line="309" exact="true" location="junit-4.11.jar" version="?"/> 127 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference" method="run" file="JUnit4TestReference.java" line="50" exact="true" location=".cp/" version="?"/> 128 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.TestExecution" method="run" file="TestExecution.java" line="38" exact="true" location=".cp/" version="?"/> 129 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="runTests" file="RemoteTestRunner.java" line="467" exact="true" location=".cp/" version="?"/> 130 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="runTests" file="RemoteTestRunner.java" line="683" exact="true" location=".cp/" version="?"/> 131 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="run" file="RemoteTestRunner.java" line="390" exact="true" location=".cp/" version="?"/> 132 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="main" file="RemoteTestRunner.java" line="197" exact="true" location=".cp/" version="?"/> 133 </ExtendedStackTrace> 134 </Suppressed> 135 <Suppressed commonElementCount="0" localizedMessage="I am suppressed exception 2" message="I am suppressed exception 2" name="java.lang.IndexOutOfBoundsException"> 136 <ExtendedStackTrace> 137 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.LogEventFixtures" method="createLogEvent" file="LogEventFixtures.java" line="58" exact="true" location="test-classes/" version="?"/> 138 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.XmlLayoutTest" method="testAllFeatures" file="XmlLayoutTest.java" line="122" exact="true" location="test-classes/" version="?"/> 139 <ExtendedStackTrace class="org.apache.logging.log4j.core.layout.XmlLayoutTest" method="testLocationOnCompactOnMdcOn" file="XmlLayoutTest.java" line="270" exact="true" location="test-classes/" version="?"/> 140 <ExtendedStackTrace class="sun.reflect.NativeMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 141 <ExtendedStackTrace class="sun.reflect.NativeMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 142 <ExtendedStackTrace class="sun.reflect.DelegatingMethodAccessorImpl" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 143 <ExtendedStackTrace class="java.lang.reflect.Method" method="invoke" line="-1" exact="false" location="?" version="1.7.0_55"/> 144 <ExtendedStackTrace class="org.junit.runners.model.FrameworkMethod$1" method="runReflectiveCall" file="FrameworkMethod.java" line="47" exact="true" location="junit-4.11.jar" version="?"/> 145 <ExtendedStackTrace class="org.junit.internal.runners.model.ReflectiveCallable" method="run" file="ReflectiveCallable.java" line="12" exact="true" location="junit-4.11.jar" version="?"/> 146 <ExtendedStackTrace class="org.junit.runners.model.FrameworkMethod" method="invokeExplosively" file="FrameworkMethod.java" line="44" exact="true" location="junit-4.11.jar" version="?"/> 147 <ExtendedStackTrace class="org.junit.internal.runners.statements.InvokeMethod" method="evaluate" file="InvokeMethod.java" line="17" exact="true" location="junit-4.11.jar" version="?"/> 148 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="runLeaf" file="ParentRunner.java" line="271" exact="true" location="junit-4.11.jar" version="?"/> 149 <ExtendedStackTrace class="org.junit.runners.BlockJUnit4ClassRunner" method="runChild" file="BlockJUnit4ClassRunner.java" line="70" exact="true" location="junit-4.11.jar" version="?"/> 150 <ExtendedStackTrace class="org.junit.runners.BlockJUnit4ClassRunner" method="runChild" file="BlockJUnit4ClassRunner.java" line="50" exact="true" location="junit-4.11.jar" version="?"/> 151 <ExtendedStackTrace class="org.junit.runners.ParentRunner$3" method="run" file="ParentRunner.java" line="238" exact="true" location="junit-4.11.jar" version="?"/> 152 <ExtendedStackTrace class="org.junit.runners.ParentRunner$1" method="schedule" file="ParentRunner.java" line="63" exact="true" location="junit-4.11.jar" version="?"/> 153 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="runChildren" file="ParentRunner.java" line="236" exact="true" location="junit-4.11.jar" version="?"/> 154 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="access$000" file="ParentRunner.java" line="53" exact="true" location="junit-4.11.jar" version="?"/> 155 <ExtendedStackTrace class="org.junit.runners.ParentRunner$2" method="evaluate" file="ParentRunner.java" line="229" exact="true" location="junit-4.11.jar" version="?"/> 156 <ExtendedStackTrace class="org.junit.internal.runners.statements.RunBefores" method="evaluate" file="RunBefores.java" line="26" exact="true" location="junit-4.11.jar" version="?"/> 157 <ExtendedStackTrace class="org.junit.internal.runners.statements.RunAfters" method="evaluate" file="RunAfters.java" line="27" exact="true" location="junit-4.11.jar" version="?"/> 158 <ExtendedStackTrace class="org.junit.runners.ParentRunner" method="run" file="ParentRunner.java" line="309" exact="true" location="junit-4.11.jar" version="?"/> 159 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference" method="run" file="JUnit4TestReference.java" line="50" exact="true" location=".cp/" version="?"/> 160 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.TestExecution" method="run" file="TestExecution.java" line="38" exact="true" location=".cp/" version="?"/> 161 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="runTests" file="RemoteTestRunner.java" line="467" exact="true" location=".cp/" version="?"/> 162 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="runTests" file="RemoteTestRunner.java" line="683" exact="true" location=".cp/" version="?"/> 163 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="run" file="RemoteTestRunner.java" line="390" exact="true" location=".cp/" version="?"/> 164 <ExtendedStackTrace class="org.eclipse.jdt.internal.junit.runner.RemoteTestRunner" method="main" file="RemoteTestRunner.java" line="197" exact="true" location=".cp/" version="?"/> 165 </ExtendedStackTrace> 166 </Suppressed> 167 </Suppressed> 168 </Thrown> 169 </Event> 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 }