/* * Copyright 1999,2004-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.log4j.xml; import org.apache.log4j.Layout; import org.apache.log4j.helpers.Transform; import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.LocationInfo; import java.io.IOException; import java.io.Writer; import java.util.Iterator; import java.util.Set; /** * The output of the XMLLayout consists of a series of log4j:event elements as * defined in the log4j.dtd . It does not * output a complete well-formed XML file. The output is designed to be included * as an external entity in a separate file to form a correct XML * file. * *

* For example, if abc is the name of the file where the * XMLLayout ouput goes, then a well-formed XML file would be: * *

 * 
 *  <?xml version="1.0" ?>
 * 
 *  <!DOCTYPE log4j:eventSet SYSTEM "log4j.dtd" [<!ENTITY data SYSTEM "abc">]>
 * 
 *  <log4j:eventSet version="1.2" xmlns:log4j="http://jakarta.apache.org/log4j/">
 *    &data
 *  </log4j:eventSet>
 *  
 * 
* *

* This approach enforces the independence of the XMLLayout and the appender * where it is embedded. * *

* The version attribute helps components to correctly intrepret * output generated by XMLLayout. The value of this attribute should be "1.1" * for output generated by log4j versions prior to log4j 1.2 (final release) and * "1.2" for relase 1.2 and later. * * Contributors: Mathias Bogaert * * @author Ceki Gülcü * @since 0.9.0 */ public class XMLLayout extends Layout { private boolean locationInfo = false; /** * Default constructor. * * @since 1.3 */ public XMLLayout() { super(); // The XMLLayout prints and does not ignore exceptions. Hence the // return value false. ignoresThrowable = false; } /** * The LocationInfo option takes a boolean value. By default, it is * set to false which means there will be no location information output by * this layout. If the the option is set to true, then the file name and line * number of the statement at the origin of the log statement will be output. * *

* If you are embedding this layout within an {@link * org.apache.log4j.net.SMTPAppender} then make sure to set the * LocationInfo option of that appender as well. */ public void setLocationInfo(boolean flag) { locationInfo = flag; } /** * Returns the current value of the LocationInfo option. */ public boolean getLocationInfo() { return locationInfo; } /** No options to activate. */ public void activateOptions() { } /** * Formats a {@link LoggingEvent}in conformance with the log4j.dtd. */ public String format(LoggingEvent event) { StringBuffer buf = new StringBuffer(); // We yield to the \r\n heresy. buf.append("\r\n"); buf.append("\r\n"); String ndc = event.getNDC(); if (ndc != null) { buf.append("\r\n"); } // Set mdcKeySet = event.getMDCKeySet(); // // if ((mdcKeySet != null) && (mdcKeySet.size() > 0)) { // /** // * Normally a sort isn't required, but for Test Case purposes // * we need to guarantee a particular order. // * // * Besides which, from a human readable point of view, the sorting // * of the keys is kinda nice.. // */ // List sortedList = new ArrayList(mdcKeySet); // Collections.sort(sortedList); // // buf.append("\r\n"); // // Iterator iter = sortedList.iterator(); // // while (iter.hasNext()) { // String propName = iter.next().toString(); // output.write(" \r\n"); // } // // output.write("\r\n"); // } if (!ignoresThrowable) { String[] s = event.getThrowableStrRep(); if (s != null) { buf.append("\r\n"); } } if (locationInfo) { LocationInfo locationInfo = event.getLocationInformation(); buf.append("\r\n"); } Set propertySet = event.getPropertyKeySet(); if ((propertySet != null) && (propertySet.size() > 0)) { buf.append("\r\n"); Iterator propIter = propertySet.iterator(); while (propIter.hasNext()) { String propName = propIter.next().toString(); buf.append(" \r\n"); } buf.append("\r\n"); } buf.append("\r\n\r\n"); return buf.toString(); } }