LOG4NET-586 add a base class for namespace aware XmlLayouts

Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/07190341
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/07190341
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/07190341

Branch: refs/heads/feature/LOG4NET-586
Commit: 07190341950355b49b958740c59b7a673c5e07f1
Parents: c5b4747
Author: Stefan Bodewig <[email protected]>
Authored: Tue May 29 20:22:57 2018 +0200
Committer: Stefan Bodewig <[email protected]>
Committed: Wed May 30 21:44:36 2018 +0200

----------------------------------------------------------------------
 src/Layout/XmlLayoutBaseNS.cs | 281 +++++++++++++++++++++++++++++++++++++
 src/log4net.csproj            |   3 +
 2 files changed, 284 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/07190341/src/Layout/XmlLayoutBaseNS.cs
----------------------------------------------------------------------
diff --git a/src/Layout/XmlLayoutBaseNS.cs b/src/Layout/XmlLayoutBaseNS.cs
new file mode 100644
index 0000000..c4fe537
--- /dev/null
+++ b/src/Layout/XmlLayoutBaseNS.cs
@@ -0,0 +1,281 @@
+#region Apache License
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you 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.
+//
+#endregion
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+using log4net.Util;
+using log4net.Core;
+
+namespace log4net.Layout
+{
+       /// <summary>
+       /// Layout that formats the log events as XML elements using a 
namespace aware writer.
+       /// </summary>
+       /// <remarks>
+       /// <para>
+       /// This is an abstract class that must be subclassed by an 
implementation
+       /// to conform to a specific schema.
+       /// </para>
+       /// <para>
+       /// Deriving classes must implement the <see cref="FormatXml"/> method.
+       /// </para>
+       /// </remarks>
+       abstract public class XmlLayoutBaseNS : LayoutSkeleton
+       {
+               #region Protected Instance Constructors
+
+               /// <summary>
+               /// Protected constructor to support subclasses
+               /// </summary>
+               /// <remarks>
+               /// <para>
+               /// Initializes a new instance of the <see 
cref="XmlLayoutBaseNS" /> class
+               /// with no location info.
+               /// </para>
+               /// </remarks>
+               protected XmlLayoutBaseNS() : this(false)
+               {
+                       IgnoresException = false;
+               }
+
+               /// <summary>
+               /// Protected constructor to support subclasses
+               /// </summary>
+               /// <remarks>
+               /// <para>
+               /// The <paramref name="locationInfo" /> parameter determines 
whether
+               /// location information will be output by the layout. If
+               /// <paramref name="locationInfo" /> is set to <c>true</c>, 
then the
+               /// file name and line number of the statement at the origin of 
the log
+               /// statement will be output.
+               /// </para>
+               /// <para>
+               /// If you are embedding this layout within an SMTPAppender
+               /// then make sure to set the <b>LocationInfo</b> option of that
+               /// appender as well.
+               /// </para>
+               /// </remarks>
+               protected XmlLayoutBaseNS(bool locationInfo)
+               {
+                       IgnoresException = false;
+                       m_locationInfo = locationInfo;
+               }
+
+               #endregion Protected Instance Constructors
+
+               #region Public Instance Properties
+
+               /// <summary>
+               /// Gets a value indicating whether to include location 
information in
+               /// the XML events.
+               /// </summary>
+               /// <value>
+               /// <c>true</c> if location information should be included in 
the XML
+               /// events; otherwise, <c>false</c>.
+               /// </value>
+               /// <remarks>
+               /// <para>
+               /// If <see cref="LocationInfo" /> is set to <c>true</c>, then 
the file
+               /// name and line number of the statement at the origin of the 
log
+               /// statement will be output.
+               /// </para>
+               /// <para>
+               /// If you are embedding this layout within an 
<c>SMTPAppender</c>
+               /// then make sure to set the <b>LocationInfo</b> option of that
+               /// appender as well.
+               /// </para>
+               /// </remarks>
+               public bool LocationInfo
+               {
+                       get { return m_locationInfo; }
+                       set { m_locationInfo = value; }
+               }
+               /// <summary>
+               /// The string to replace characters that can not be expressed 
in XML with.
+               /// <remarks>
+               /// <para>
+               /// Not all characters may be expressed in XML. This property 
contains the
+               /// string to replace those that can not with. This defaults to 
a ?. Set it
+               /// to the empty string to simply remove offending characters. 
For more
+               /// details on the allowed character ranges see 
http://www.w3.org/TR/REC-xml/#charsets
+               /// Character replacement will occur in  the log message, the 
property names
+               /// and the property values.
+               /// </para>
+               /// </remarks>
+               /// </summary>
+               public string InvalidCharReplacement
+               {
+                       get {return m_invalidCharReplacement;}
+                       set {m_invalidCharReplacement=value;}
+               }
+
+               /// <summary>
+               /// The namespace URI to use for the elements and attributes 
written by this layout.
+               /// </summary>
+               public string NamespaceUri
+               {
+                       get { return m_namespaceUri; }
+                       set { m_namespaceUri = value; }
+               }
+
+               /// <summary>
+               /// The prefix to use for the elements and attributes written 
by this layout.
+               /// </summary>
+               /// <remarks>
+               /// <para>
+               /// If the prefix is not set, then the XML subsystem may
+               /// select the prefix or use no prefix at all.
+               /// </para>
+               /// </remarks>
+               public string Prefix
+               {
+                       get { return m_prefix; }
+                       set { m_prefix = value; }
+               }
+               #endregion
+
+               #region Implementation of IOptionHandler
+
+               /// <summary>
+               /// Initialize layout options
+               /// </summary>
+               /// <remarks>
+               /// <para>
+               /// This is part of the <see cref="IOptionHandler"/> delayed 
object
+               /// activation scheme. The <see cref="ActivateOptions"/> method 
must
+               /// be called on this object after the configuration properties 
have
+               /// been set. Until <see cref="ActivateOptions"/> is called this
+               /// object is in an undefined state and must not be used.
+               /// </para>
+               /// <para>
+               /// If any of the configuration properties are modified then
+               /// <see cref="ActivateOptions"/> must be called again.
+               /// </para>
+               /// </remarks>
+               override public void ActivateOptions()
+               {
+                       if (NamespaceUri == null || NamespaceUri.Length == 0)
+                       {
+                               throw new ArgumentException("NamespaceUri must 
not be empty");
+                       }
+               }
+
+               #endregion Implementation of IOptionHandler
+
+               #region Override implementation of LayoutSkeleton
+
+               /// <summary>
+               /// Gets the content type output by this layout.
+               /// </summary>
+               /// <value>
+               /// As this is the XML layout, the value is always 
<c>"text/xml"</c>.
+               /// </value>
+               /// <remarks>
+               /// <para>
+               /// As this is the XML layout, the value is always 
<c>"text/xml"</c>.
+               /// </para>
+               /// </remarks>
+               override public string ContentType
+               {
+                       get { return "text/xml"; }
+               }
+
+               /// <summary>
+               /// Produces a formatted string.
+               /// </summary>
+               /// <param name="loggingEvent">The event being logged.</param>
+               /// <param name="writer">The TextWriter to write the formatted 
event to</param>
+               /// <remarks>
+               /// <para>
+               /// Format the <see cref="LoggingEvent"/> and write it to the 
<see cref="TextWriter"/>.
+               /// </para>
+               /// <para>
+               /// This method creates an <see cref="XmlTextWriter"/> that 
writes to the
+               /// <paramref name="writer"/>. The <see cref="XmlTextWriter"/> 
is passed
+               /// to the <see cref="FormatXml"/> method. Subclasses should 
override the
+               /// <see cref="FormatXml"/> method rather than this method.
+               /// </para>
+               /// </remarks>
+               override public void Format(TextWriter writer, LoggingEvent 
loggingEvent)
+               {
+                       if (loggingEvent == null)
+                       {
+                               throw new ArgumentNullException("loggingEvent");
+                       }
+                       XmlWriterSettings settings = new XmlWriterSettings();
+                       settings.Indent = false;
+                       settings.OmitXmlDeclaration = true;
+                       XmlWriter xmlWriter = XmlWriter.Create(new 
ProtectCloseTextWriter(writer), settings);
+                       // Write the event to the writer
+                       FormatXml(xmlWriter, loggingEvent);
+
+                       xmlWriter.WriteWhitespace(SystemInfo.NewLine);
+
+                       // Close on xmlWriter will ensure xml is flushed
+                       // the protected writer will ignore the actual close
+                       xmlWriter.Close();
+               }
+
+               #endregion Override implementation of LayoutSkeleton
+
+               #region Protected Instance Methods
+
+               /// <summary>
+               /// Does the actual writing of the XML.
+               /// </summary>
+               /// <param name="writer">The writer to use to output the event 
to.</param>
+               /// <param name="loggingEvent">The event to write.</param>
+               /// <remarks>
+               /// <para>
+               /// Subclasses should override this method to format
+               /// the <see cref="LoggingEvent"/> as XML.
+               /// </para>
+               /// </remarks>
+               abstract protected void FormatXml(XmlWriter writer, 
LoggingEvent loggingEvent);
+
+               #endregion Protected Instance Methods
+
+               #region Private Instance Fields
+
+               /// <summary>
+               /// Flag to indicate if location information should be included 
in
+               /// the XML events.
+               /// </summary>
+               private bool m_locationInfo = false;
+
+               /// <summary>
+               /// The string to replace invalid chars with
+               /// </summary>
+               private string m_invalidCharReplacement="?";
+
+               /// <summary>
+               /// The namespace URI to use for the elements and attributes 
written by this layout.
+               /// </summary>
+               private string m_namespaceUri;
+
+               /// <summary>
+               /// The prefix to use for the elements and attributes written 
by this layout.
+               /// </summary>
+               private string m_prefix;
+               #endregion Private Instance Fields
+       }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/07190341/src/log4net.csproj
----------------------------------------------------------------------
diff --git a/src/log4net.csproj b/src/log4net.csproj
index 05a7062..b638481 100644
--- a/src/log4net.csproj
+++ b/src/log4net.csproj
@@ -509,6 +509,9 @@
     <Compile Include="Layout\XmlLayoutBase.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Layout\XmlLayoutBaseNS.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="Layout\XmlLayoutSchemaLog4j.cs">
       <SubType>Code</SubType>
     </Compile>

Reply via email to