/Dependencies/log4net/Layout/XMLLayoutBase.cs
C# | 259 lines | 71 code | 29 blank | 159 comment | 2 complexity | e749336f89662d5cf29a20e3c1e00168 MD5 | raw file
1#region Apache License 2// 3// Licensed to the Apache Software Foundation (ASF) under one or more 4// contributor license agreements. See the NOTICE file distributed with 5// this work for additional information regarding copyright ownership. 6// The ASF licenses this file to you under the Apache License, Version 2.0 7// (the "License"); you may not use this file except in compliance with 8// the License. You may obtain a copy of the License at 9// 10// http://www.apache.org/licenses/LICENSE-2.0 11// 12// Unless required by applicable law or agreed to in writing, software 13// distributed under the License is distributed on an "AS IS" BASIS, 14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15// See the License for the specific language governing permissions and 16// limitations under the License. 17// 18#endregion 19 20using System; 21using System.IO; 22using System.Text; 23using System.Xml; 24 25using log4net.Util; 26using log4net.Core; 27 28namespace log4net.Layout 29{ 30 /// <summary> 31 /// Layout that formats the log events as XML elements. 32 /// </summary> 33 /// <remarks> 34 /// <para> 35 /// This is an abstract class that must be subclassed by an implementation 36 /// to conform to a specific schema. 37 /// </para> 38 /// <para> 39 /// Deriving classes must implement the <see cref="FormatXml"/> method. 40 /// </para> 41 /// </remarks> 42 /// <author>Nicko Cadell</author> 43 /// <author>Gert Driesen</author> 44 abstract public class XmlLayoutBase : LayoutSkeleton 45 { 46 #region Protected Instance Constructors 47 48 /// <summary> 49 /// Protected constructor to support subclasses 50 /// </summary> 51 /// <remarks> 52 /// <para> 53 /// Initializes a new instance of the <see cref="XmlLayoutBase" /> class 54 /// with no location info. 55 /// </para> 56 /// </remarks> 57 protected XmlLayoutBase() : this(false) 58 { 59 IgnoresException = false; 60 } 61 62 /// <summary> 63 /// Protected constructor to support subclasses 64 /// </summary> 65 /// <remarks> 66 /// <para> 67 /// The <paramref name="locationInfo" /> parameter determines whether 68 /// location information will be output by the layout. If 69 /// <paramref name="locationInfo" /> is set to <c>true</c>, then the 70 /// file name and line number of the statement at the origin of the log 71 /// statement will be output. 72 /// </para> 73 /// <para> 74 /// If you are embedding this layout within an SMTPAppender 75 /// then make sure to set the <b>LocationInfo</b> option of that 76 /// appender as well. 77 /// </para> 78 /// </remarks> 79 protected XmlLayoutBase(bool locationInfo) 80 { 81 IgnoresException = false; 82 m_locationInfo = locationInfo; 83 } 84 85 #endregion Protected Instance Constructors 86 87 #region Public Instance Properties 88 89 /// <summary> 90 /// Gets a value indicating whether to include location information in 91 /// the XML events. 92 /// </summary> 93 /// <value> 94 /// <c>true</c> if location information should be included in the XML 95 /// events; otherwise, <c>false</c>. 96 /// </value> 97 /// <remarks> 98 /// <para> 99 /// If <see cref="LocationInfo" /> is set to <c>true</c>, then the file 100 /// name and line number of the statement at the origin of the log 101 /// statement will be output. 102 /// </para> 103 /// <para> 104 /// If you are embedding this layout within an <c>SMTPAppender</c> 105 /// then make sure to set the <b>LocationInfo</b> option of that 106 /// appender as well. 107 /// </para> 108 /// </remarks> 109 public bool LocationInfo 110 { 111 get { return m_locationInfo; } 112 set { m_locationInfo = value; } 113 } 114 /// <summary> 115 /// The string to replace characters that can not be expressed in XML with. 116 /// <remarks> 117 /// <para> 118 /// Not all characters may be expressed in XML. This property contains the 119 /// string to replace those that can not with. This defaults to a ?. Set it 120 /// to the empty string to simply remove offending characters. For more 121 /// details on the allowed character ranges see http://www.w3.org/TR/REC-xml/#charsets 122 /// Character replacement will occur in the log message, the property names 123 /// and the property values. 124 /// </para> 125 /// </remarks> 126 /// </summary> 127 public string InvalidCharReplacement 128 { 129 get {return m_invalidCharReplacement;} 130 set {m_invalidCharReplacement=value;} 131 } 132 #endregion 133 134 #region Implementation of IOptionHandler 135 136 /// <summary> 137 /// Initialize layout options 138 /// </summary> 139 /// <remarks> 140 /// <para> 141 /// This is part of the <see cref="IOptionHandler"/> delayed object 142 /// activation scheme. The <see cref="ActivateOptions"/> method must 143 /// be called on this object after the configuration properties have 144 /// been set. Until <see cref="ActivateOptions"/> is called this 145 /// object is in an undefined state and must not be used. 146 /// </para> 147 /// <para> 148 /// If any of the configuration properties are modified then 149 /// <see cref="ActivateOptions"/> must be called again. 150 /// </para> 151 /// </remarks> 152 override public void ActivateOptions() 153 { 154 // nothing to do 155 } 156 157 #endregion Implementation of IOptionHandler 158 159 #region Override implementation of LayoutSkeleton 160 161 /// <summary> 162 /// Gets the content type output by this layout. 163 /// </summary> 164 /// <value> 165 /// As this is the XML layout, the value is always <c>"text/xml"</c>. 166 /// </value> 167 /// <remarks> 168 /// <para> 169 /// As this is the XML layout, the value is always <c>"text/xml"</c>. 170 /// </para> 171 /// </remarks> 172 override public string ContentType 173 { 174 get { return "text/xml"; } 175 } 176 177 /// <summary> 178 /// Produces a formatted string. 179 /// </summary> 180 /// <param name="loggingEvent">The event being logged.</param> 181 /// <param name="writer">The TextWriter to write the formatted event to</param> 182 /// <remarks> 183 /// <para> 184 /// Format the <see cref="LoggingEvent"/> and write it to the <see cref="TextWriter"/>. 185 /// </para> 186 /// <para> 187 /// This method creates an <see cref="XmlTextWriter"/> that writes to the 188 /// <paramref name="writer"/>. The <see cref="XmlTextWriter"/> is passed 189 /// to the <see cref="FormatXml"/> method. Subclasses should override the 190 /// <see cref="FormatXml"/> method rather than this method. 191 /// </para> 192 /// </remarks> 193 override public void Format(TextWriter writer, LoggingEvent loggingEvent) 194 { 195 if (loggingEvent == null) 196 { 197 throw new ArgumentNullException("loggingEvent"); 198 } 199 200 // Attach the protected writer to the TextWriter passed in 201 m_protectCloseTextWriter.Attach(writer); 202 203 XmlTextWriter xmlWriter = new XmlTextWriter(m_protectCloseTextWriter); 204 xmlWriter.Formatting = Formatting.None; 205 xmlWriter.Namespaces = false; 206 207 // Write the event to the writer 208 FormatXml(xmlWriter, loggingEvent); 209 210 xmlWriter.WriteWhitespace(SystemInfo.NewLine); 211 212 // Close on xmlWriter will ensure xml is flushed 213 // the protected writer will ignore the actual close 214 xmlWriter.Close(); 215 216 // detach from the writer 217 m_protectCloseTextWriter.Attach(null); 218 } 219 220 #endregion Override implementation of LayoutSkeleton 221 222 #region Protected Instance Methods 223 224 /// <summary> 225 /// Does the actual writing of the XML. 226 /// </summary> 227 /// <param name="writer">The writer to use to output the event to.</param> 228 /// <param name="loggingEvent">The event to write.</param> 229 /// <remarks> 230 /// <para> 231 /// Subclasses should override this method to format 232 /// the <see cref="LoggingEvent"/> as XML. 233 /// </para> 234 /// </remarks> 235 abstract protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent); 236 237 #endregion Protected Instance Methods 238 239 #region Private Instance Fields 240 241 /// <summary> 242 /// Flag to indicate if location information should be included in 243 /// the XML events. 244 /// </summary> 245 private bool m_locationInfo = false; 246 247 /// <summary> 248 /// Writer adapter that ignores Close 249 /// </summary> 250 private readonly ProtectCloseTextWriter m_protectCloseTextWriter = new ProtectCloseTextWriter(null); 251 252 /// <summary> 253 /// The string to replace invalid chars with 254 /// </summary> 255 private string m_invalidCharReplacement="?"; 256 257 #endregion Private Instance Fields 258 } 259}