diff options
212 files changed, 54646 insertions, 0 deletions
diff --git a/dotnet/LICENCE.txt b/dotnet/LICENCE.txt new file mode 100644 index 0000000000..6b0b1270ff --- /dev/null +++ b/dotnet/LICENCE.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/dotnet/NOTICE.txt b/dotnet/NOTICE.txt new file mode 100644 index 0000000000..ec97abcb86 --- /dev/null +++ b/dotnet/NOTICE.txt @@ -0,0 +1,22 @@ +========================================================================= +== NOTICE file corresponding to the section 4 d of == +== the Apache License, Version 2.0, == +== in this case for the Apache Ant distribution. == +========================================================================= + +Apache Qpid.NET +Copyright 2006 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + +This product also includes software developed by: + + - The SAXON XSLT Processor from Michael Kay distributed under the Mozilla + Public License v1.0, which is available for download at + http://saxon.sourceforge.net/ + + - The nunit library, Copyright © 2002 James W. Newkirk, Michael C. Two, + Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig. Available + under terms based on the zlib/libpng licence. Available from + http://www.nunit.org/ diff --git a/dotnet/Qpid.Buffer/BufferOverflowException.cs b/dotnet/Qpid.Buffer/BufferOverflowException.cs new file mode 100644 index 0000000000..b5896262da --- /dev/null +++ b/dotnet/Qpid.Buffer/BufferOverflowException.cs @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Buffer +{ + public class BufferOverflowException : Exception + { + public BufferOverflowException(string message) : base(message) + { + } + } +} + diff --git a/dotnet/Qpid.Buffer/BufferUnderflowException.cs b/dotnet/Qpid.Buffer/BufferUnderflowException.cs new file mode 100644 index 0000000000..9de6b6558f --- /dev/null +++ b/dotnet/Qpid.Buffer/BufferUnderflowException.cs @@ -0,0 +1,33 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Buffer +{ + public class BufferUnderflowException : Exception + { + public BufferUnderflowException(string message) + : base(message) + { + } + } +} + diff --git a/dotnet/Qpid.Buffer/ByteBuffer.cs b/dotnet/Qpid.Buffer/ByteBuffer.cs new file mode 100644 index 0000000000..70022407a5 --- /dev/null +++ b/dotnet/Qpid.Buffer/ByteBuffer.cs @@ -0,0 +1,450 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Text; + +namespace Qpid.Buffer +{ + /// <summary> + /// A buffer that manages an underlying byte oriented stream, and writes and reads to and from it in + /// BIG ENDIAN order. + /// </summary> + public abstract class ByteBuffer + { + protected const int MINIMUM_CAPACITY = 1; + + protected static Stack _containerStack = new Stack(); + + protected static Stack[] _heapBufferStacks = new Stack[] + { + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack(), + new Stack(), new Stack(), new Stack(), new Stack() + }; + + /// <summary> + /// Returns the direct or heap buffer which is capable of the specified size. + /// Currently does not support direct buffers but this will be an option in future. + /// </summary> + /// <param name="capacity">The capacity.</param> + /// <returns></returns> + public static ByteBuffer Allocate(int capacity) + { + // for now, just allocate a heap buffer but in future could do an optimised "direct" buffer + // that is implemented natively + return Allocate(capacity, false); + } + + public static ByteBuffer Allocate(int capacity, bool direct) + { + ByteBuffer buffer = Allocate0(capacity, direct); + RefCountingByteBuffer buf = AllocateContainer(); + buf.Init(buffer); + return buf; + } + + private static RefCountingByteBuffer AllocateContainer() + { + RefCountingByteBuffer buf = null; + lock (_containerStack) + { + if (_containerStack.Count > 0) + { + buf = (RefCountingByteBuffer) _containerStack.Pop(); + } + } + + if (buf == null) + { + buf = new RefCountingByteBuffer(); + } + return buf; + } + + protected static ByteBuffer Allocate0(int capacity, bool direct) + { + if (direct) + { + throw new NotSupportedException("Direct buffers not currently implemented"); + } + int idx = GetBufferStackIndex(_heapBufferStacks, capacity); + Stack stack = _heapBufferStacks[idx]; + ByteBuffer buf = null; + lock (stack) + { + if (stack.Count > 0) + { + buf = (ByteBuffer) stack.Pop(); + } + } + + if (buf == null) + { + buf = new HeapByteBuffer(MINIMUM_CAPACITY << idx); + } + + return buf; + } + + protected static void Release0(ByteBuffer buf) + { + Stack stack = _heapBufferStacks[GetBufferStackIndex(_heapBufferStacks, buf.Capacity)]; + lock (stack) + { + stack.Push(buf); + } + } + + private static int GetBufferStackIndex(Stack[] bufferStacks, int size) + { + int targetSize = MINIMUM_CAPACITY; + int stackIdx = 0; + // each bucket contains buffers that are double the size of the previous bucket + while (size > targetSize) + { + targetSize <<= 1; + stackIdx++; + if (stackIdx >= bufferStacks.Length) + { + throw new ArgumentOutOfRangeException("size", "Buffer size is too big: " + size); + } + } + return stackIdx; + } + + /// <summary> + /// Increases the internal reference count of this buffer to defer automatic release. You have + /// to invoke release() as many times as you invoked this method to release this buffer. + /// </summary> + public abstract void Acquire(); + + /// <summary> + /// Releases the specified buffer to the buffer pool. + /// </summary> + public abstract void Release(); + + public abstract int Capacity + { + get; + } + + public abstract bool IsAutoExpand + { + get; + set; + } + + /// <summary> + /// Changes the capacity and limit of this buffer sot his buffer gets the specified + /// expectedRemaining room from the current position. This method works even if you didn't set + /// autoExpand to true. + /// </summary> + /// <param name="expectedRemaining">Room you want from the current position</param> + public abstract void Expand(int expectedRemaining); + + /// <summary> + /// Changes the capacity and limit of this buffer sot his buffer gets the specified + /// expectedRemaining room from the specified position. + /// </summary> + /// <param name="pos">The pos you want the room to be available from.</param> + /// <param name="expectedRemaining">The expected room you want available.</param> + public abstract void Expand(int pos, int expectedRemaining); + + /// <summary> + /// Returns true if and only if this buffer is returned back to the buffer pool when released. + /// </summary> + /// <value><c>true</c> if pooled; otherwise, <c>false</c>.</value> + public abstract bool Pooled + { + get; + set; + } + + public abstract int Position + { + get; + set; + } + + public abstract int Limit + { + get; + set; + } + + //public abstract void Mark(); + + //public abstract void Reset(); + + public abstract void Clear(); + + /// <summary> + /// Clears this buffer and fills its content with NULL. The position is set to zero, the limit is set to + /// capacity and the mark is discarded. + /// </summary> + public void Sweep() + { + Clear(); + FillAndReset(Remaining); + } + + public void Sweep(byte value) + { + Clear(); + FillAndReset(value, Remaining); + } + + public abstract void Flip(); + + public abstract void Rewind(); + + public abstract int Remaining + { + get; + } + + public bool HasRemaining() + { + return Remaining > 0; + } + + public abstract byte Get(); + + public abstract byte Get(int index); + + public abstract void Get(byte[] destination); + + public abstract ushort GetUnsignedShort(); + + public abstract uint GetUnsignedInt(); + + public abstract ulong GetUnsignedLong(); + + public abstract string GetString(uint length, Encoding encoder); + + public abstract void Put(byte data); + + public abstract void Put(byte[] data); + public abstract void Put(byte[] data, int offset, int size); + + public abstract void Put(ushort data); + + public abstract void Put(uint data); + + public abstract void Put(ulong data); + + public abstract void Put(ByteBuffer buf); + + public abstract void Compact(); + + public abstract byte[] ToByteArray(); + + public override string ToString() + { + StringBuilder buf = new StringBuilder(); + buf.Append("HeapBuffer"); + buf.AppendFormat("[pos={0} lim={1} cap={2} : {3}]", Position, Limit, Capacity, HexDump); + return buf.ToString(); + } + + public override int GetHashCode() + { + int h = 1; + int p = Position; + for (int i = Limit - 1; i >= p; i--) + { + h = 31 * h + Get(i); + } + + return h; + } + + public override bool Equals(object obj) + { + if (!(obj is ByteBuffer)) + { + return false; + } + ByteBuffer that = (ByteBuffer) obj; + + if (Remaining != that.Remaining) + { + return false; + } + int p = Position; + for (int i = Limit - 1, j = that.Limit - 1; i >= p; i--, j--) + { + byte v1 = this.Get(i); + byte v2 = that.Get(j); + if (v1 != v2) + { + return false; + } + } + return true; + } + + public string HexDump + { + get + { + return ByteBufferHexDumper.GetHexDump(this); + } + } + + /// <summary> + /// Fills the buffer with the specified specified value. This method moves the buffer position forward. + /// </summary> + /// <param name="value">The value.</param> + /// <param name="size">The size.</param> + public void Fill(byte value, int size) + { + AutoExpand(size); + int q = size >> 3; + int r = size & 7; + + if (q > 0) + { + int intValue = value | (value << 8) | (value << 16) | (value << 24); + long longValue = intValue; + longValue <<= 32; + longValue |= (ushort)intValue; + + for (int i = q; i > 0; i--) + { + Put((ulong)longValue); + } + } + + q = r >> 2; + r = r & 3; + + if (q > 0) + { + int intValue = value | (value << 8) | (value << 16) | (value << 24); + Put((uint)intValue); + } + + q = r >> 1; + r = r & 1; + + if (q > 0) + { + short shortValue = (short) (value | (value << 8)); + Put((ushort) shortValue); + } + if (r > 0) + { + Put(value); + } + } + + public void FillAndReset(byte value, int size) + { + AutoExpand(size); + int pos = Position; + try + { + Fill(value, size); + } + finally + { + Position = pos; + } + } + + public void Fill(int size) + { + AutoExpand(size); + int q = size >> 3; + int r = size & 7; + + for (int i = q; i > 0; i--) + { + Put(0L); + } + + q = r >> 2; + r = r & 3; + + if (q > 0) + { + Put(0); + } + + q = r >> 1; + r = r & 1; + + if(q > 0) + { + Put((ushort) 0); + } + + if (r > 0) + { + Put((byte) 0); + } + } + + public void FillAndReset(int size) + { + AutoExpand(size); + int pos = Position; + try + { + Fill(size); + } + finally + { + Position = pos; + } + } + + public void Skip(int size) + { + AutoExpand(size); + Position = Position + size; + } + + protected void AutoExpand(int expectedRemaining) + { + if (IsAutoExpand) + { + Expand(expectedRemaining); + } + } + + protected void AutoExpand(int pos, int expectedRemaining) + { + if (IsAutoExpand) + { + Expand(pos, expectedRemaining); + } + } + } +} + diff --git a/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs b/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs new file mode 100644 index 0000000000..a43331ff1a --- /dev/null +++ b/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs @@ -0,0 +1,77 @@ +/* + * + * 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. + * + */ +using System.Text; + +namespace Qpid.Buffer +{ + public class ByteBufferHexDumper + { + private static byte[] highDigits; + + private static byte[] lowDigits; + + static ByteBufferHexDumper() + { + byte[] digits = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', + (byte)'E', (byte)'F' }; + int i; + byte[] high = new byte[256]; + byte[] low = new byte[256]; + + for (i = 0; i < 256; i++) + { + high[i] = digits[i >> 4]; + low[i] = digits[i & 0x0F]; + } + + highDigits = high; + lowDigits = low; + } + + public static string GetHexDump(ByteBuffer input) + { + int size = input.Limit - input.Position; + if (size == 0) + { + return "empty"; + } + + StringBuilder output = new StringBuilder(size * 3 - 1); + + byte[] data = input.ToByteArray(); + int byteValue = data[0] & 0xFF; + output.Append((char) highDigits[byteValue]); + output.Append((char) lowDigits[byteValue]); + + for (int i = 1 ; i < size; i++) + { + output.Append(' '); + byteValue = data[i] & 0xFF; + output.Append((char) highDigits[byteValue]); + output.Append((char) lowDigits[byteValue]); + } + + return output.ToString(); + } + } +} + diff --git a/dotnet/Qpid.Buffer/ByteBufferProxy.cs b/dotnet/Qpid.Buffer/ByteBufferProxy.cs new file mode 100644 index 0000000000..2dd4e73aa6 --- /dev/null +++ b/dotnet/Qpid.Buffer/ByteBufferProxy.cs @@ -0,0 +1,190 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; + +namespace Qpid.Buffer +{ + public class ByteBufferProxy : ByteBuffer + { + protected ByteBuffer _buf; + + protected ByteBufferProxy(ByteBuffer buf) + { + if (buf == null) + { + throw new ArgumentNullException("buf"); + } + _buf = buf; + } + + + public override void Acquire() + { + _buf.Acquire(); + } + + public override void Release() + { + _buf.Release(); + } + + public override int Capacity + { + get { return _buf.Capacity; } + } + + public override bool IsAutoExpand + { + get { return _buf.IsAutoExpand; } + set { _buf.IsAutoExpand = value; } + } + + public override void Expand(int expectedRemaining) + { + _buf.Expand(expectedRemaining); + } + + public override void Expand(int pos, int expectedRemaining) + { + _buf.Expand(pos, expectedRemaining); + } + + public override bool Pooled + { + get { return _buf.Pooled; } + set { _buf.Pooled = value; } + } + + public override int Position + { + get { return _buf.Position; } + set { _buf.Position = value; } + } + + public override int Limit + { + get { return _buf.Limit; } + set { _buf.Limit = value; } + } + + public override void Clear() + { + _buf.Clear(); + } + + public override void Flip() + { + _buf.Flip(); + } + + public override void Rewind() + { + _buf.Rewind(); + } + + public override int Remaining + { + get { return _buf.Remaining; } + } + + public override byte Get() + { + return _buf.Get(); + } + + public override byte Get(int index) + { + return _buf.Get(index); + } + + public override void Get(byte[] destination) + { + _buf.Get(destination); + } + + public override ushort GetUnsignedShort() + { + return _buf.GetUnsignedShort(); + } + + public override uint GetUnsignedInt() + { + return _buf.GetUnsignedInt(); + } + + public override ulong GetUnsignedLong() + { + return _buf.GetUnsignedLong(); + } + + public override string GetString(uint length, Encoding encoder) + { + return _buf.GetString(length, encoder); + } + + public override void Put(byte data) + { + _buf.Put(data); + } + + public override void Put(byte[] data, int offset, int size) + { + _buf.Put(data, offset, size); + } + + public override void Put(byte[] data) + { + _buf.Put(data); + } + + public override void Put(ushort data) + { + _buf.Put(data); + } + + public override void Put(uint data) + { + _buf.Put(data); + } + + public override void Put(ulong data) + { + _buf.Put(data); + } + + public override void Put(ByteBuffer buf) + { + _buf.Put(buf); + } + + public override void Compact() + { + _buf.Compact(); + } + + public override byte[] ToByteArray() + { + return _buf.ToByteArray(); + } + } +} + diff --git a/dotnet/Qpid.Buffer/HeapByteBuffer.cs b/dotnet/Qpid.Buffer/HeapByteBuffer.cs new file mode 100644 index 0000000000..03dbd58bff --- /dev/null +++ b/dotnet/Qpid.Buffer/HeapByteBuffer.cs @@ -0,0 +1,390 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; + +namespace Qpid.Buffer +{ + public class HeapByteBuffer : ByteBuffer + { + private byte[] _underlyingData; + + /// <summary> + /// The position of the next value to be read or written + /// </summary> + private int _position; + + /// <summary> + /// The index of the first element that should not be read or written + /// </summary> + private int _limit; + + public HeapByteBuffer(int size) : this(new byte[size], 0) + { + } + + private HeapByteBuffer(byte[] bytes, int length) + { + _underlyingData = bytes; + _limit = bytes.Length; + _position = length; + } + + public override int Capacity + { + get + { + return _underlyingData.Length; + } + } + + public override int Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + /// <summary> + /// Sets this buffer's limit. If the position is larger than the new limit then it is set to the new limit. + /// </summary> + /// <value>The new limit value; must be non-negative and no larger than this buffer's capacity</value> + public override int Limit + { + get + { + return _limit; + } + set + { + if (value < 0) + { + throw new ArgumentException("Limit must not be negative"); + } + if (value > Capacity) + { + throw new ArgumentException("Limit must not be greater than Capacity"); + } + _limit = value; + if (_position > value) + { + _position = value; + } + } + } + + /// <summary> + /// Returns the number of elements between the current position and the limit + /// </summary> + /// <value>The number of elements remaining in this buffer</value> + public override int Remaining + { + get + { + return (_limit - _position); + } + } + + public override void Clear() + { + _position = 0; + _limit = Capacity; + } + + public override void Flip() + { + _limit = _position; + _position = 0; + } + + public override void Rewind() + { + _position = 0; + } + + public override byte[] ToByteArray() + { + return _underlyingData; + } + + private void CheckSpace(int size) + { + if (_position + size > _limit) + { + throw new BufferOverflowException("Attempt to write " + size + " byte(s) to buffer where position is " + _position + + " and limit is " + _limit); + } + } + + private void CheckSpaceForReading(int size) + { + if (_position + size > _limit) + { + throw new BufferUnderflowException("Attempt to read " + size + " byte(s) to buffer where position is " + _position + + " and limit is " + _limit); + } + } + + /// <summary> + /// Writes the given byte into this buffer at the current position, and then increments the position. + /// </summary> + /// <param name="data">The byte to be written</param> + /// <exception cref="BufferOverflowException">If this buffer's current position is not smaller than its limit</exception> + public override void Put(byte data) + { + CheckSpace(1); + _underlyingData[_position++] = data; + } + + /// <summary> + /// Writes all the data in the given byte array into this buffer at the current + /// position and then increments the position. + /// </summary> + /// <param name="data">The data to copy.</param> + /// <exception cref="BufferOverflowException">If this buffer's current position plus the array length is not smaller than its limit</exception> + public override void Put(byte[] data) + { + Put(data, 0, data.Length); + } + + public override void Put(byte[] data, int offset, int size) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + CheckSpace(size); + Array.Copy(data, offset, _underlyingData, _position, size); + _position += size; + } + + /// <summary> + /// Writes the given ushort into this buffer at the current position, and then increments the position. + /// </summary> + /// <param name="data">The ushort to be written</param> + public override void Put(ushort data) + { + CheckSpace(2); + _underlyingData[_position++] = (byte) (data >> 8); + _underlyingData[_position++] = (byte) data; + } + + public override void Put(uint data) + { + CheckSpace(4); + _underlyingData[_position++] = (byte) (data >> 24); + _underlyingData[_position++] = (byte) (data >> 16); + _underlyingData[_position++] = (byte) (data >> 8); + _underlyingData[_position++] = (byte) data; + } + + public override void Put(ulong data) + { + CheckSpace(8); + _underlyingData[_position++] = (byte) (data >> 56); + _underlyingData[_position++] = (byte) (data >> 48); + _underlyingData[_position++] = (byte) (data >> 40); + _underlyingData[_position++] = (byte) (data >> 32); + _underlyingData[_position++] = (byte) (data >> 24); + _underlyingData[_position++] = (byte) (data >> 16); + _underlyingData[_position++] = (byte) (data >> 8); + _underlyingData[_position++] = (byte) data; + } + + /// <summary> + /// Read the byte at the current position and increment the position + /// </summary> + /// <returns>a byte</returns> + /// <exception cref="BufferUnderflowException">if there are no bytes left to read</exception> + public override byte Get() + { + CheckSpaceForReading(1); + return _underlyingData[_position++]; + } + + /// <summary> + /// Reads bytes from the buffer into the supplied array + /// </summary> + /// <param name="destination">The destination array. The array must not + /// be bigger than the remaining space in the buffer, nor can it be null.</param> + public override void Get(byte[] destination) + { + if (destination == null) + { + throw new ArgumentNullException("destination"); + } + int len = destination.Length; + CheckSpaceForReading(len); + Array.Copy(_underlyingData, _position, destination, 0, len); + _position += len; + } + + /// <summary> + /// Reads and returns an unsigned short (two bytes, big endian) from this buffer + /// </summary> + /// <returns>an unsigned short</returns> + /// <exception cref="BufferUnderflowException">If there are fewer than two bytes remaining in this buffer</exception> + public override ushort GetUnsignedShort() + { + CheckSpaceForReading(2); + byte upper = _underlyingData[_position++]; + byte lower = _underlyingData[_position++]; + return (ushort) ((upper << 8) + lower); + } + + /// <summary> + /// Reads and returns an unsigned int (four bytes, big endian) from this buffer + /// </summary> + /// <returns>an unsigned integer</returns> + /// <exception cref="BufferUnderflowException">If there are fewer than four bytes remaining in this buffer</exception> + public override uint GetUnsignedInt() + { + CheckSpaceForReading(4); + byte b1 = _underlyingData[_position++]; + byte b2 = _underlyingData[_position++]; + byte b3 = _underlyingData[_position++]; + byte b4 = _underlyingData[_position++]; + return (uint) ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4); + } + + public override ulong GetUnsignedLong() + { + CheckSpaceForReading(8); + byte b1 = _underlyingData[_position++]; + byte b2 = _underlyingData[_position++]; + byte b3 = _underlyingData[_position++]; + byte b4 = _underlyingData[_position++]; + byte b5 = _underlyingData[_position++]; + byte b6 = _underlyingData[_position++]; + byte b7 = _underlyingData[_position++]; + byte b8 = _underlyingData[_position++]; + return (ulong)((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32) + (b5 << 24) + + (b6 << 16) + (b7 << 8) + b8); + } + + public override string GetString(uint length, Encoding encoder) + { + CheckSpaceForReading((int)length); + string result = encoder.GetString(_underlyingData, _position, (int)length); + _position += (int)length; + return result; + } + + public override void Acquire() + { + } + + public override void Release() + { + } + + public override bool IsAutoExpand + { + get { return false; } + set { } + } + + public override void Expand(int expectedRemaining) + { + throw new NotImplementedException(); + } + + public override void Expand(int pos, int expectedRemaining) + { + throw new NotImplementedException(); + } + + public override bool Pooled + { + get { return false; } + set { } + } + + public void Mark() + { + throw new NotImplementedException(); + } + + public void Reset() + { + throw new NotImplementedException(); + } + + public override byte Get(int index) + { + throw new NotImplementedException(); + } + + public override void Put(ByteBuffer src) + { + if (src == this) + { + throw new ArgumentException("Cannot copy self into self!"); + } + + HeapByteBuffer sb; + if (src is HeapByteBuffer) + { + sb = (HeapByteBuffer) src; + } + else + { + sb = (HeapByteBuffer)((RefCountingByteBuffer) src).Buf; + } + int n = sb.Remaining; + if (n > Remaining) + { + throw new BufferOverflowException("Not enought capacity in this buffer for " + n + " elements - only " + Remaining + " remaining"); + } + Array.Copy(sb._underlyingData, sb._position, _underlyingData, _position, n); + sb._position += n; + _position += n; + } + + public override void Compact() + { + if (Remaining > 0) + { + if (_position > 0) + { + Array.Copy(_underlyingData, _position, _underlyingData, 0, Remaining); + } + _position = Remaining; + } + else + { + _position = 0; + } + _limit = Capacity; + } + + public static HeapByteBuffer wrap(byte[] bytes, int length) + { + return new HeapByteBuffer(bytes, length); + } + } +} + diff --git a/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs b/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..971d78b27c --- /dev/null +++ b/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.ByteBuffer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("Qpid.ByteBuffer")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2b3333e5-03b5-4f00-9215-66009f8a5c47")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/Qpid.Buffer/Qpid.Buffer.csproj b/dotnet/Qpid.Buffer/Qpid.Buffer.csproj new file mode 100644 index 0000000000..dbc12856bf --- /dev/null +++ b/dotnet/Qpid.Buffer/Qpid.Buffer.csproj @@ -0,0 +1,56 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Buffer</RootNamespace>
+ <AssemblyName>Qpid.Buffer</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BufferOverflowException.cs" />
+ <Compile Include="BufferUnderflowException.cs" />
+ <Compile Include="ByteBuffer.cs" />
+ <Compile Include="ByteBufferHexDumper.cs" />
+ <Compile Include="ByteBufferProxy.cs" />
+ <Compile Include="HeapByteBuffer.cs" />
+ <Compile Include="RefCountingByteBuffer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Buffer/RefCountingByteBuffer.cs b/dotnet/Qpid.Buffer/RefCountingByteBuffer.cs new file mode 100644 index 0000000000..0d3fc4b77b --- /dev/null +++ b/dotnet/Qpid.Buffer/RefCountingByteBuffer.cs @@ -0,0 +1,336 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; + +namespace Qpid.Buffer +{ + public class RefCountingByteBuffer : ByteBuffer + { + private ByteBuffer _buf; + + private int _refCount = 1; + private bool _autoExpand; + private bool _pooled; + + public void Init(ByteBuffer buf) + { + lock (this) + { + _buf = buf; + buf.Clear(); + _autoExpand = false; + _pooled = true; + _refCount = 1; + } + } + + public override void Acquire() + { + lock (this) + { + if (_refCount <= 0) + { + throw new Exception("Already released buffer"); + } + _refCount++; + } + } + + public override void Release() + { + lock (this) + { + if (_refCount <= 0) + { + _refCount = 0; + throw new Exception("Already released buffer. Release called too many times"); + } + + _refCount--; + if (_refCount > 0) + { + return; + } + } + + if (_pooled) + { + Release0(_buf); + } + + lock (_containerStack) + { + _containerStack.Push(this); + } + } + + public ByteBuffer Buf + { + get + { + return _buf; + } + } + + public override bool IsAutoExpand + { + get + { + return _autoExpand; + } + + set + { + _autoExpand = value; + } + } + + public override bool Pooled + { + get + { + return _pooled; + } + + set + { + _pooled = value; + } + } + + public override int Capacity + { + get + { + return _buf.Capacity; + } + } + + public override int Position + { + get + { + return _buf.Position; + } + set + { + AutoExpand(value, 0); + _buf.Position = value; + } + } + + public override int Limit + { + get + { + return _buf.Limit; + } + set + { + AutoExpand(value, 0); + _buf.Limit = value; + } + } + + /*public override void Mark() + { + _buf.Mark(); + } + + public override void Reset() + { + _buf.Reset(); + }*/ + + public override void Clear() + { + _buf.Clear(); + } + + public override void Flip() + { + _buf.Flip(); + } + + public override void Rewind() + { + _buf.Rewind(); + } + + public override int Remaining + { + get + { + return _buf.Remaining; + } + } + + public override byte Get() + { + return _buf.Get(); + } + + public override void Put(byte data) + { + AutoExpand(1); + _buf.Put(data); + } + + public override byte Get(int index) + { + return _buf.Get(index); + } + + public override void Compact() + { + _buf.Compact(); + } + + + public override void Get(byte[] destination) + { + _buf.Get(destination); + } + + public override ushort GetUnsignedShort() + { + return _buf.GetUnsignedShort(); + } + + public override uint GetUnsignedInt() + { + return _buf.GetUnsignedInt(); + } + + public override ulong GetUnsignedLong() + { + return _buf.GetUnsignedLong(); + } + + public override string GetString(uint length, Encoding encoder) + { + return _buf.GetString(length, encoder); + } + + public override void Put(byte[] data) + { + AutoExpand(data.Length); + _buf.Put(data); + } + + public override void Put(byte[] data, int offset, int size) + { + AutoExpand(size); + _buf.Put(data, offset, size); + } + + public override void Put(ushort data) + { + AutoExpand(2); + _buf.Put(data); + } + + public override void Put(uint data) + { + AutoExpand(4); + _buf.Put(data); + } + + public override void Put(ulong data) + { + AutoExpand(8); + _buf.Put(data); + } + + public override void Put(ByteBuffer buf) + { + AutoExpand(buf.Remaining); + _buf.Put(buf); + } + + public override void Expand(int expectedRemaining) + { + if (_autoExpand) + { + int pos = _buf.Position; + int limit = _buf.Limit; + int end = pos + expectedRemaining; + if (end > limit) + { + EnsureCapacity(end); + _buf.Limit = end; + } + } + } + + public override void Expand(int pos, int expectedRemaining) + { + if (_autoExpand) + { + int limit = _buf.Limit; + int end = pos + expectedRemaining; + if (end > limit) + { + EnsureCapacity(end); + _buf.Limit = end; + } + } + } + + private void EnsureCapacity(int requestedCapacity) + { + if (requestedCapacity <= _buf.Capacity) + { + return; + } + + int newCapacity = MINIMUM_CAPACITY; + while (newCapacity < requestedCapacity) + { + newCapacity <<= 1; + } + + ByteBuffer oldBuf = _buf; + ByteBuffer newBuf = Allocate0(newCapacity, false); + newBuf.Clear(); + int pos = oldBuf.Position; + int limit = oldBuf.Limit; + oldBuf.Clear(); + newBuf.Put(oldBuf); + newBuf.Position = pos; + newBuf.Limit = limit; + _buf = newBuf; + Release0(oldBuf); + } + + public override byte[] ToByteArray() + { + return _buf.ToByteArray(); + } + + public override string ToString() + { + return "RefCountingByteBuffer: refs= " + _refCount + "buf=" + base.ToString(); + } + } +} + diff --git a/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs b/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs new file mode 100644 index 0000000000..4e69e07f45 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/Common/BaseMessagingTestFixture.cs @@ -0,0 +1,74 @@ +/* + * + * 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. + * + */ +using System; +using log4net; +using NUnit.Framework; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + public class BaseMessagingTestFixture + { + private static ILog _logger = LogManager.GetLogger(typeof(BaseMessagingTestFixture)); + + protected IConnection _connection; + + protected IChannel _channel; + + [SetUp] + public virtual void Init() + { + try + { + QpidConnectionInfo connectionInfo = new QpidConnectionInfo(); + + bool local = true; + + if (local) + { + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); + } + else + { + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "eqd-lxamq01.uk.jpmorgan.com", 8099, false)); + } + _connection = new AMQConnection(connectionInfo); + _channel = _connection.CreateChannel(false, AcknowledgeMode.NoAcknowledge, 1); + } + catch (QpidException e) + { + _logger.Error("Error initialisng test fixture: " + e, e); + throw e; + } + } + + [TearDown] + public void Shutdown() + { + Console.WriteLine("Shutdown"); + if (_connection != null) + { + Console.WriteLine("Disposing connection"); + _connection.Dispose(); + } + } + } +} diff --git a/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs new file mode 100644 index 0000000000..cf26b42c6a --- /dev/null +++ b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingConsumer.cs @@ -0,0 +1,104 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + [TestFixture] + public class HeadersMatchingConsumer : BaseMessagingTestFixture + { + private static ILog _logger = LogManager.GetLogger(typeof(HeadersMatchingConsumer)); + + private string _serviceName = "ServiceQ1"; + + private AutoResetEvent _evt = new AutoResetEvent(false); + + [SetUp] + public override void Init() + { + base.Init(); + + _logger.Info("Starting..."); + + _logger.Info("Service (queue) name is '" + _serviceName + "'..."); + + _connection.ExceptionListener = new ExceptionListenerDelegate(OnException); + + // Declare a new HeadersExchange with the name of the service. + _channel.DeclareExchange(_serviceName, ExchangeClassConstants.HEADERS); + + // Create non-durable, temporary (aka auto-delete), exclusive queue. + string queueName = _channel.GenerateUniqueName(); + _channel.DeclareQueue(queueName, false, true, true); + + // Bind our queue to the new HeadersExchange. + _channel.Bind(queueName, _serviceName, null, CreatePatternAsFieldTable()); + + IMessageConsumer consumer = _channel.CreateConsumerBuilder(queueName) + .withPrefetch(100) + .withNoLocal(true) + .Create(); + + consumer.OnMessage = new MessageReceivedDelegate(OnMessage); + } + + [Test] + public void Test() + { + _connection.Start(); + _logger.Info("Waiting..."); + _evt.WaitOne(); + } + + public void OnMessage(IMessage message) + { + _logger.Info(string.Format("message.Type = {0}", message.GetType())); + _logger.Info("Got message '" + message + "'"); + } + + private FieldTable CreatePatternAsFieldTable() + { + FieldTable matchTable = new FieldTable(); + // Currently all String matching must be prefixed by an "S" ("S" for string because of a failing of the FieldType definition). + matchTable["Smatch1"] = "foo"; + matchTable["Smatch2"] = ""; + return matchTable; + } + + public void OnException(Exception e) + { + if (e is QpidException && e.InnerException is AMQDisconnectedException) + { + _logger.Error("Broker closed connection"); + } + else + { + _logger.Error("Connection exception occurred: " + e); + } + _evt.Set(); + } + } +} diff --git a/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs new file mode 100644 index 0000000000..35f6017f48 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/HeadersExchange/HeadersMatchingProducer.cs @@ -0,0 +1,113 @@ +/* + * + * 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. + * + */ +using log4net; +using NUnit.Framework; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + [TestFixture] + public class HeadersMatchingProducer : BaseMessagingTestFixture + { + private static ILog _logger = LogManager.GetLogger(typeof(HeadersMatchingProducer)); + + private string _commandExchangeName = "ServiceQ1"; + + private int _messageCount = 12; + + private IMessagePublisher _publisher; + + [SetUp] + public override void Init() + { + base.Init(); + + try + { + _publisher = _channel.CreatePublisherBuilder() + .withExchangeName(_commandExchangeName) + .withMandatory(true) + .Create(); + + // Disabling timestamps - a performance optimisation where timestamps and TTL/expiration + // are not required. + _publisher.DisableMessageTimestamp = true; + + _publisher.DeliveryMode = DeliveryMode.NonPersistent; + } + catch (QpidException e) + { + _logger.Error("Error: " + e, e); + } + } + + [Test] + public void SendMessages() + { + _connection.Start(); + for (int i = 0; i < _messageCount; i++) + { + int rem = i % 6; + IMessage msg = null; + switch (rem) + { + case 0: + msg = _channel.CreateTextMessage("matches match2='bar'"); + msg.Headers["match1"] = "foo"; + msg.Headers["match2"] = "bar"; + break; + + case 1: + msg = _channel.CreateTextMessage("not match - only match1"); + msg.Headers["match1"] = "foo"; + break; + + case 2: + msg = _channel.CreateTextMessage("not match - only match2"); + msg.Headers["match2"] = "bar"; + break; + + case 3: + msg = _channel.CreateTextMessage("matches match2=''"); + msg.Headers["match1"] = "foo"; + msg.Headers["match2"] = ""; + break; + + case 4: + msg = _channel.CreateTextMessage("matches - extra headers"); + msg.Headers["match1"] = "foo"; + msg.Headers["match2"] = "bar"; + msg.Headers["match3"] = "not required"; + break; + + case 5: + msg = _channel.CreateTextMessage("5: no match"); + msg.Headers["match1"] = "foo1"; + msg.Headers["match2"] = "bar"; + msg.Headers["match3"] = "not required"; + break; + } + _publisher.Send(msg); + } + _logger.Info("Finished sending " + _messageCount + " messages"); + } + } +} diff --git a/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs b/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs new file mode 100644 index 0000000000..6b6fca20b2 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/MultiConsumer/ProducerMultiConsumer.cs @@ -0,0 +1,125 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + [TestFixture] + public class ProducerMultiConsumer : BaseMessagingTestFixture + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(ProducerMultiConsumer)); + + private string _commandQueueName = "ServiceQ1"; + + private const int CONSUMER_COUNT = 5; + + private const int MESSAGE_COUNT = 1000; + + private const string MESSAGE_DATA_BYTES = "jfd ghljgl hjvhlj cvhvjf ldhfsj lhfdsjf hldsjfk hdslkfj hsdflk "; + + AutoResetEvent _finishedEvent = new AutoResetEvent(false); + + private static String GetData(int size) + { + StringBuilder buf = new StringBuilder(size); + int count = 0; + while (count < size + MESSAGE_DATA_BYTES.Length) + { + buf.Append(MESSAGE_DATA_BYTES); + count += MESSAGE_DATA_BYTES.Length; + } + if (count < size) + { + buf.Append(MESSAGE_DATA_BYTES, 0, size - count); + } + + return buf.ToString(); + } + + private IMessagePublisher _publisher; + + private IMessageConsumer[] _consumers = new IMessageConsumer[CONSUMER_COUNT]; + + private int _messageReceivedCount = 0; + + [SetUp] + public override void Init() + { + base.Init(); + _publisher = _channel.CreatePublisherBuilder() + .withRoutingKey(_commandQueueName) + .withExchangeName(ExchangeNameDefaults.TOPIC) + .Create(); + + _publisher.DisableMessageTimestamp = true; + _publisher.DeliveryMode = DeliveryMode.NonPersistent; + + for (int i = 0; i < CONSUMER_COUNT; i++) + { + string queueName = _channel.GenerateUniqueName(); + _channel.DeclareQueue(queueName, false, true, true); + + _channel.Bind(queueName, ExchangeNameDefaults.TOPIC, _commandQueueName); + + _consumers[i] = _channel.CreateConsumerBuilder(queueName) + .withPrefetch(100).Create(); + _consumers[i].OnMessage = new MessageReceivedDelegate(OnMessage); + } + _connection.Start(); + } + + public void OnMessage(IMessage m) + { + int newCount = Interlocked.Increment(ref _messageReceivedCount); + if (newCount % 1000 == 0) _logger.Info("Received count=" + newCount); + if (newCount == (MESSAGE_COUNT * CONSUMER_COUNT)) + { + _logger.Info("All messages received"); + _finishedEvent.Set(); + } + } + + [Test] + public void RunTest() + { + for (int i = 0; i < MESSAGE_COUNT; i++) + { + ITextMessage msg; + try + { + msg = _channel.CreateTextMessage(GetData(512 + 8*i)); + } + catch (Exception e) + { + _logger.Error("Error creating message: " + e, e); + break; + } + _publisher.Send(msg); + } + _finishedEvent.WaitOne(); + } + } +} diff --git a/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs b/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3a2842c210 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using System.Reflection; +using System.Runtime.InteropServices; +using log4net.Config; +[assembly: XmlConfigurator(ConfigFile="log4net.config")] + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.Client.Tests")] +[assembly: AssemblyDescription("Test Suite for Qpid Clients")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("Qpid.Client.Tests")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7ebdea21-1352-4673-b66e-fdc0beff461f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.5.*")] diff --git a/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj b/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj new file mode 100644 index 0000000000..c3e957ae09 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj @@ -0,0 +1,95 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Client.Tests</RootNamespace>
+ <AssemblyName>Qpid.Client.Tests</AssemblyName>
+ <StartupObject>
+ </StartupObject>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework, Version=2.2.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="bio\BlockingIo.cs" />
+ <Compile Include="connection\ConnectionTest.cs" />
+ <Compile Include="failover\FailoverTest.cs" />
+ <Compile Include="failover\FailoverTxTest.cs" />
+ <Compile Include="HeadersExchange\HeadersMatchingConsumer.cs" />
+ <Compile Include="HeadersExchange\HeadersMatchingProducer.cs" />
+ <Compile Include="MultiConsumer\ProducerMultiConsumer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Common\BaseMessagingTestFixture.cs" />
+ <Compile Include="requestreply1\ServiceProvidingClient.cs" />
+ <Compile Include="requestreply1\ServiceRequestingClient.cs" />
+ <Compile Include="undeliverable\UndeliverableTest.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Client.Transport.Socket.Blocking\Qpid.Client.Transport.Socket.Blocking.csproj">
+ <Project>{52AC4940-2077-4104-A753-29A9C8C16957}</Project>
+ <Name>Qpid.Client.Transport.Socket.Blocking</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="log4net.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Qpid.Common.DLL.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Client.Tests/Qpid.Common.DLL.config b/dotnet/Qpid.Client.Tests/Qpid.Common.DLL.config new file mode 100644 index 0000000000..e1300549d7 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/Qpid.Common.DLL.config @@ -0,0 +1,5 @@ +<configuration> + <assemblySettings> + <add key="OpenAMQ1d4Compatibility" value="false"/> + </assemblySettings> +</configuration>
\ No newline at end of file diff --git a/dotnet/Qpid.Client.Tests/bio/BlockingIo.cs b/dotnet/Qpid.Client.Tests/bio/BlockingIo.cs new file mode 100644 index 0000000000..24f3299dae --- /dev/null +++ b/dotnet/Qpid.Client.Tests/bio/BlockingIo.cs @@ -0,0 +1,73 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using NUnit.Framework; +using Qpid.Client.Protocol; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client.Transport +{ + [TestFixture] + public class BlockingIo + { + [Test] + public void connectFromOutside() + { + QpidConnectionInfo connectionInfo = new QpidConnectionInfo(); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); + AMQConnection connection = new AMQConnection(connectionInfo); + ProtocolWriter protocolWriter = connection.ConvenientProtocolWriter; + + // TODO: Open channels and handle them simultaneously. + // Need more thread here? + // Send ChannelOpen. + ushort channelId = 1; + protocolWriter.SyncWrite(ChannelOpenBody.CreateAMQFrame(channelId, null), typeof (ChannelOpenOkBody)); + + connection.Close(); + } + + [Test] + public void regularConnection() + { + QpidConnectionInfo connectionInfo = new QpidConnectionInfo(); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); + using (IConnection connection = new AMQConnection(connectionInfo)) { + Console.WriteLine("connection = {0}", connection); + Thread.Sleep(2000); + } + } + + [Test] + public void connectionAndSleepForHeartbeats() + { + QpidConnectionInfo connectionInfo = new QpidConnectionInfo(); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); + using (IConnection connection = new AMQConnection(connectionInfo)) + { + Console.WriteLine("connection = {0}", connection); + Thread.Sleep(60000); + } + } + } +} diff --git a/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs b/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs new file mode 100644 index 0000000000..d6d7639c21 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/connection/ConnectionTest.cs @@ -0,0 +1,99 @@ +/* + * + * 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. + * + */ +using System; +using NUnit.Framework; +using Qpid.Client.qms; +using Qpid.Messaging; + +namespace Qpid.Client.Tests.connection +{ + [TestFixture] + public class ConnectionTest + { + [Test] + public void simpleConnection() + { + ConnectionInfo connectionInfo = new QpidConnectionInfo(); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); + using (IConnection connection = new AMQConnection(connectionInfo)) + { + Console.WriteLine("connection = " + connection); + } + } + + [Test] + public void passwordFailureConnection() + { + ConnectionInfo connectionInfo = new QpidConnectionInfo(); + connectionInfo.setPassword("rubbish"); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo()); + try + { + using (IConnection connection = new AMQConnection(connectionInfo)) + { + Console.WriteLine("connection = " + connection); + } + } + catch (AMQException) + { + Assert.Fail(); +// if (!(e is AMQAuthenticationException)) +// { +// Assert.Fail("Expected AMQAuthenticationException!"); +// } + } + } +// +// [Test] +// public void connectionFailure() +// { +// try +// { +// new AMQConnection("amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5673?retries='0''"); +// Assert.fail("Connection should not be established"); +// } +// catch (AMQException amqe) +// { +// if (!(amqe instanceof AMQConnectionException)) +// { +// Assert.fail("Correct exception not thrown"); +// } +// } +// } +// +// [Test] +// public void unresolvedHostFailure() +// { +// try +// { +// new AMQConnection("amqp://guest:guest@clientid/testpath?brokerlist='tcp://rubbishhost:5672?retries='0''"); +// Assert.fail("Connection should not be established"); +// } +// catch (AMQException amqe) +// { +// if (!(amqe instanceof AMQUnresolvedAddressException)) +// { +// Assert.fail("Correct exception not thrown"); +// } +// } +// } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client.Tests/default.build b/dotnet/Qpid.Client.Tests/default.build new file mode 100644 index 0000000000..36cdb612b5 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/default.build @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<project name="XMS.AMQ.ClientTests" default="build"> + <property name="nant.settings.currentframework" value="net-1.0" /> + <property name="basename" value="XMSClientTests"/> + <property name="debug" value="true"/> + <property name="MINADir" value="../minadotnet"/> + <property name="XMSCommonDir" value="../xmscommon"/> + <property name="XMSClientDir" value="../xmsclient"/> +<!-- + <property name="NunitDir" value="../build/nunit"/> + <property name="NunitDir" value="C:\Program Files\NUnit-Net-2.0 2.2.8"/> +--> + <property name="NunitDir" value="C:\Program Files\NUnit 2.2.8"/> + + <if test="${debug}"> + <property name="targetdir" value="bin/${nant.settings.currentframework}/Debug"/> + </if> + <ifnot test="${debug}"> + <property name="targetdir" value="bin/${nant.settings.currentframework}/Release"/> + </ifnot> + + <target name="clean"> + <delete> + <fileset> + <include name="${targetdir}/${basename}.dll"/> + <include name="${targetdir}/${basename}.pdb"/> + </fileset> + </delete> + </target> + + <target name="init"> + <mkdir dir="${targetdir}"/> + </target> + + <target name="build" depends="init"> + <csc target="library" output="${targetdir}/${basename}.dll" debug="${debug}"> + <sources> + <include name="**/*.cs"/> + <exclude name="Properties/Settings.Designer.cs" /> + </sources> + <references> + <lib> + <include name="${MINADir}/${targetdir}" /> + <include name="${XMSCommonDir}/${targetdir}" /> + <include name="${XMSClientDir}/${targetdir}" /> + <include name="${XMSCommonDir}/lib/**" /> + <include name="${NunitDir}/bin" /> + </lib> + <include name="log4net.dll" /> + <include name="MINA.dll" /> + <include name="IBM.XMS.dll" /> + <include name="XMSCommon.dll" /> + <include name="XMSClient.dll" /> + <include name="nunit.framework.dll" /> + </references> + </csc> + <copy todir="${targetdir}"> + <fileset> + <include name="*.config" /> + <include name="${MINADir}/${targetdir}/*.dll" /> + <include name="${XMSCommonDir}/${targetdir}/*.dll" /> + <include name="${XMSClientDir}/${targetdir}/*.dll" /> + <include name="${NunitDir}/bin/nunit.framework.dll" /> + <include name="${XMSCommonDir}/lib/xms/*.dll" /> + </fileset> + </copy> + </target> +</project> diff --git a/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs b/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs new file mode 100644 index 0000000000..6b3ab068f5 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/failover/FailoverTest.cs @@ -0,0 +1,258 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Client.qms; +using Qpid.Messaging; + +namespace Qpid.Client.Tests.failover +{ + [TestFixture] + public class FailoverTest : IConnectionListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverTest)); + + private IConnection _connection; + private IChannel _channel; + private IMessagePublisher _publisher; + private int _count; + + private IMessageConsumer _consumerOfResponse; + + void DoFailoverTest(ConnectionInfo info) + { + DoFailoverTest(new AMQConnection(info)); + } + + void DoFailoverTest(IConnection connection) + { + AMQConnection amqConnection = (AMQConnection)connection; + amqConnection.ConnectionListener = this; + //Console.WriteLine("connection.url = " + amqConnection.ToURL()); + _connection = connection; + _connection.ExceptionListener = new ExceptionListenerDelegate(OnConnectionException); + _channel = _connection.CreateChannel(false, AcknowledgeMode.NoAcknowledge); + + string exchangeName = ExchangeNameDefaults.TOPIC; + string routingKey = "topic1"; + + string queueName = DeclareAndBindTemporaryQueue(exchangeName, routingKey); + + new MsgListener(_connection.CreateChannel(false, AcknowledgeMode.NoAcknowledge), queueName); + + IChannel channel = _channel; + + string tempQueueName = channel.GenerateUniqueName(); + channel.DeclareQueue(tempQueueName, false, true, true); + _consumerOfResponse = channel.CreateConsumerBuilder(tempQueueName).Create(); + _consumerOfResponse.OnMessage = new MessageReceivedDelegate(OnMessage); + + _connection.Start(); + + IMessage msg = _channel.CreateTextMessage("Init"); + // FIXME: Leaving ReplyToExchangeName as default (i.e. the default exchange) + // FIXME: but the implementation might not like this as it defaults to null rather than "". + msg.ReplyToRoutingKey = tempQueueName; +// msg.ReplyTo = new ReplyToDestination("" /* i.e. the default exchange */, tempQueueName); + _logger.Info(String.Format("sending msg.Text={0}", ((ITextMessage)msg).Text)); + +// _publisher = _channel.CreatePublisher(exchangeName, exchangeClass, routingKey); + _publisher = _channel.CreatePublisherBuilder() + .withRoutingKey(routingKey) + .withExchangeName(exchangeName) + .Create(); + _publisher.Send(msg); + } + + public string DeclareAndBindTemporaryQueue(string exchangeName, string routingKey) + { + string queueName = _channel.GenerateUniqueName(); + + // Queue.Declare + _channel.DeclareQueue(queueName, false, true, true); + + // Queue.Bind + _channel.Bind(queueName, exchangeName, routingKey); + return queueName; + } + + private void OnConnectionException(Exception e) + { + _logger.Error("Connection exception occurred", e); + } + + public void OnMessage(IMessage message) + { + try + { + _logger.Info("received message on temp queue msg.Text=" + ((ITextMessage)message).Text); + Thread.Sleep(1000); + _publisher.Send(_channel.CreateTextMessage("Message" + (++_count))); + } + catch (QpidException e) + { + error(e); + } + } + + private void error(Exception e) + { + _logger.Error("exception received", e); + stop(); + } + + private void stop() + { + _logger.Info("Stopping..."); + try + { + _connection.Dispose(); + } + catch (QpidException e) + { + _logger.Error("Failed to shutdown", e); + } + } + + public void BytesSent(long count) + { + } + + public void BytesReceived(long count) + { + } + + public bool PreFailover(bool redirect) + { + _logger.Info("preFailover(" + redirect + ") called"); + return true; + } + + public bool PreResubscribe() + { + _logger.Info("preResubscribe() called"); + return true; + } + + public void FailoverComplete() + { + _logger.Info("failoverComplete() called"); + } + + private class MsgListener + { + private IChannel _session; + private IMessagePublisher _publisher; + + internal MsgListener(IChannel session, string queueName) + { + _session = session; + _session.CreateConsumerBuilder(queueName).Create().OnMessage = + new MessageReceivedDelegate(OnMessage); + } + + public void OnMessage(IMessage message) + { + try + { + _logger.Info("Received: msg.Text = " + ((ITextMessage) message).Text); + if(_publisher == null) + { + _publisher = init(message); + } + reply(message); + } + catch (QpidException e) + { +// Error(e); + _logger.Error("yikes", e); // XXX + } + } + + private void reply(IMessage message) + { + string msg = ((ITextMessage) message).Text; + _logger.Info("sending reply - " + msg); + _publisher.Send(_session.CreateTextMessage(msg)); + } + + private IMessagePublisher init(IMessage message) + { + _logger.Info(string.Format("creating reply producer with dest = '{0}:{1}'", + message.ReplyToExchangeName, message.ReplyToRoutingKey)); + + string exchangeName = message.ReplyToExchangeName; + string routingKey = message.ReplyToRoutingKey; + + //return _channel.CreatePublisher(exchangeName, exchangeClass, routingKey); + return _session.CreatePublisherBuilder() + .withExchangeName(exchangeName) + .withRoutingKey(routingKey) + .Create(); + } + } + + [Test] + public void TestWithBasicInfo() + { + Console.WriteLine("TestWithBasicInfo"); + try + { + QpidConnectionInfo connectionInfo = new QpidConnectionInfo(); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); +// connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5673, false)); + + //connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "eqd-lxamq01", 7672, false)); + + + //connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "eqd-lxamq01.uk.jpmorgan.com", 8099, false)); + + + DoFailoverTest(connectionInfo); + while (true) + { + Thread.Sleep(5000); + } + } + catch (Exception e) + { + _logger.Error("Exception caught", e); + } + } + +// [Test] +// public void TestWithUrl() +// { +// String clientId = "failover" + DateTime.Now.Ticks; +// String defaultUrl = "amqp://guest:guest@" + clientId + "/test" + +// "?brokerlist='tcp://localhost:5672;tcp://localhost:5673'&failover='roundrobin'"; +// +// _logger.Info("url = [" + defaultUrl + "]"); +// +// // _logger.Info("connection url = [" + new AMQConnectionURL(defaultUrl) + "]"); +// +// String broker = defaultUrl; +// //new FailoverTest(broker); +// } + } +} diff --git a/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs new file mode 100644 index 0000000000..ad1570ed14 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/failover/FailoverTxTest.cs @@ -0,0 +1,194 @@ +/* + * + * 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. + * + */ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Client.qms; +using Qpid.Messaging; + +namespace Qpid.Client.Tests.failover +{ + [TestFixture] + public class FailoverTxTest : IConnectionListener + { + private static readonly ILog _log = LogManager.GetLogger(typeof(FailoverTxTest)); + + const int NUM_ITERATIONS = 3; + const int NUM_MESSAGES = 10; + const int SLEEP_MILLIS = 500; + + AMQConnection _connection; + + public void onMessage(IMessage message) + { + try + { + _log.Info("Received: " + ((ITextMessage) message).Text); + } + catch (QpidException e) + { + error(e); + } + } + + void DoFailoverTxTest(ConnectionInfo connectionInfo) + { + _connection = new AMQConnection(connectionInfo); + _connection.ConnectionListener = this; + _log.Info("connection = " + _connection); + _log.Info("connectionInfo = " + connectionInfo); + _log.Info("connection.asUrl = " + _connection.toURL()); + + IChannel session = _connection.CreateChannel(false, AcknowledgeMode.NoAcknowledge); + + string queueName = session.GenerateUniqueName(); + + // Queue.Declare + session.DeclareQueue(queueName, false, true, true); + + // No need to call Queue.Bind as automatically bound to default direct exchange. +// channel.Bind(queueName, exchangeName, routingKey); + + session.CreateConsumerBuilder(queueName).Create().OnMessage = new MessageReceivedDelegate(onMessage); + + _connection.Start(); + + sendInTx(queueName); + + _connection.Close(); + _log.Info("FailoverTxText complete"); + } + + private void sendInTx(string routingKey) + { + _log.Info("sendInTx"); + bool transacted = false; + IChannel session = _connection.CreateChannel(transacted, AcknowledgeMode.NoAcknowledge); + IMessagePublisher publisher = session.CreatePublisherBuilder() + .withRoutingKey(routingKey) + .Create(); + + for (int i = 1; i <= NUM_ITERATIONS; ++i) + { + for (int j = 1; j <= NUM_MESSAGES; ++j) + { + ITextMessage msg = session.CreateTextMessage("Tx=" + i + " msg=" + j); + _log.Info("sending message = " + msg.Text); + publisher.Send(msg); + Thread.Sleep(SLEEP_MILLIS); + } + if (transacted) session.Commit(); + } + } + + private void error(Exception e) + { + _log.Fatal("Exception received. About to stop.", e); + stop(); + } + + private void stop() + { + _log.Info("Stopping..."); + try + { + _connection.Close(); + } + catch (QpidException e) + { + _log.Info("Failed to shutdown: ", e); + } + } + + public void BytesSent(long count) + { + } + + public void BytesReceived(long count) + { + } + + public bool PreFailover(bool redirect) + { + _log.Info("preFailover(" + redirect + ") called"); + return true; + } + + public bool PreResubscribe() + { + _log.Info("preResubscribe() called"); + return true; + } + + public void FailoverComplete() + { + _log.Info("failoverComplete() called"); + } + + [Test] + public void TestWithBasicInfo() + { + Console.WriteLine("TestWithBasicInfo"); + Console.WriteLine(".NET Framework version: " + RuntimeEnvironment.GetSystemVersion()); + try + { + QpidConnectionInfo connectionInfo = new QpidConnectionInfo(); + + bool local = true; + if (local) + { + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false)); + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5673, false)); + } + else + { + connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "eqd-lxamq01.uk.jpmorgan.com", 8099, false)); + } + + DoFailoverTxTest(connectionInfo); + } + catch (Exception e) + { + _log.Error("Exception caught", e); + } + } + + //[Test] + //public void runTestWithUrl() + //{ + // try { + // String clientId = "failover" + DateTime.Now.Ticks; + // string defaultUrl = "amqp://guest:guest@" + clientId + "/test" + + // "?brokerlist='tcp://localhost:5672;tcp://localhost:5673'&failover='roundrobin'"; + + // _log.Info("url = [" + defaultUrl + "]"); + + // _log.Info("connection url = [" + new AMQConnectionInfo(defaultUrl) + "]"); + + // DoFailoverTxTest(new AMQConnectionInfo(defaultUrl)); + // } catch (Exception e) { + // _log.Error("test failed", e); + // } + //} + } +} diff --git a/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt b/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt new file mode 100644 index 0000000000..b2316295d3 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt @@ -0,0 +1,23 @@ +Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, + Charlie Poole +Copyright © 2000-2004 Philip A. Craig + +This software is provided 'as-is', without any express or implied warranty. In +no event will the authors be held liable for any damages arising from the use +of this software. + +Permission is granted to anyone to use this software for any purpose, including +commercial applications, and to alter it and redistribute it freely, subject to +the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim + that you wrote the original software. If you use this software in a product, an + acknowledgment (see the following) in the product documentation is required. + + Portions Copyright © 2002 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov + or Copyright © 2000-2002 Philip A. Craig + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dll b/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dll Binary files differnew file mode 100644 index 0000000000..53666e74c9 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dll diff --git a/dotnet/Qpid.Client.Tests/log4net.config b/dotnet/Qpid.Client.Tests/log4net.config new file mode 100644 index 0000000000..e0a43a8b5e --- /dev/null +++ b/dotnet/Qpid.Client.Tests/log4net.config @@ -0,0 +1,38 @@ +<log4net> + <appender name="console" type="log4net.Appender.ConsoleAppender" > + <layout type="log4net.Layout.PatternLayout"> + <conversionPattern value="%d [%t] %-5p %c:%M(%L) - %m%n" /> + </layout> + </appender> + + <appender name="protocolLog" type="log4net.Appender.FileAppender"> + <file value="protocol.log"/> + <appendToFile value="false"/> + <layout type="log4net.Layout.PatternLayout"> + <conversionPattern value="%date - %message%newline"/> + </layout> + </appender> + + <appender name="ioLog" type="log4net.Appender.FileAppender"> + <file value="io.log"/> + <appendToFile value="false"/> + <layout type="log4net.Layout.PatternLayout"> + <conversionPattern value="%date - %message%newline"/> + </layout> + </appender> + + <logger name="Qpid.Client.ProtocolChannel.Tracing" additivity="false"> + <level value="info"/> + <appender-ref ref="protocolLog"/> + </logger> + + <logger name="Qpid.Client.ByteChannel.Tracing" additivity="false"> + <level value="info" /> + <appender-ref ref="ioLog"/> + </logger> + + <root> + <level value="info"/> + <appender-ref ref="console"/> + </root> +</log4net>
\ No newline at end of file diff --git a/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs b/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs new file mode 100644 index 0000000000..bb5758c18c --- /dev/null +++ b/dotnet/Qpid.Client.Tests/requestreply1/ServiceProvidingClient.cs @@ -0,0 +1,147 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + [TestFixture] + public class ServiceProvidingClient : BaseMessagingTestFixture + { + private static ILog _logger = LogManager.GetLogger(typeof(ServiceProvidingClient)); + + private int _messageCount; + + private string _replyToExchangeName; + private string _replyToRoutingKey; + + private IMessagePublisher _destinationPublisher; + + private string _serviceName = "ServiceQ1"; + + private string _selector = null; + + //private EventWaitHandle _event = new ManualResetEvent(false); + private AutoResetEvent _event = new AutoResetEvent(false); + + [SetUp] + public override void Init() + { + base.Init(); + + _logger.Info("Starting..."); + _logger.Info("Service (queue) name is '" + _serviceName + "'..."); + + _connection.ExceptionListener = new ExceptionListenerDelegate(OnConnectionException); + + _logger.Info("Message selector is <" + _selector + ">..."); + + _channel.DeclareQueue(_serviceName, false, false, false); + + IMessageConsumer consumer = _channel.CreateConsumerBuilder(_serviceName) + .withPrefetch(100) + .withNoLocal(true) + .Create(); + consumer.OnMessage = new MessageReceivedDelegate(OnMessage); + } + + private void OnConnectionException(Exception e) + { + _logger.Info("Connection exception occurred", e); + _event.Set(); // Shutdown test on error + // XXX: Test still doesn't shutdown when broker terminates. Is there no heartbeat? + } + + [Test] + public void Test() + { + _connection.Start(); + _logger.Info("Waiting..."); + _event.WaitOne(); + } + + public void OnMessage(IMessage message) + { +// _logger.Info("Got message '" + message + "'"); + + ITextMessage tm = (ITextMessage)message; + + try + { + string replyToExchangeName = tm.ReplyToExchangeName; + string replyToRoutingKey = tm.ReplyToRoutingKey; + + _replyToExchangeName = replyToExchangeName; + _replyToRoutingKey = replyToRoutingKey; + _logger.Debug("About to create a producer"); + +// Console.WriteLine("ReplyTo.ExchangeName = " + _replyToExchangeName); +// Console.WriteLine("ReplyTo.RoutingKey = " + _replyToRoutingKey); + + _destinationPublisher = _channel.CreatePublisherBuilder() + .withExchangeName(_replyToExchangeName) + .withRoutingKey(_replyToRoutingKey) + .Create(); + _destinationPublisher.DisableMessageTimestamp = true; + _destinationPublisher.DeliveryMode = DeliveryMode.NonPersistent; + _logger.Debug("After create a producer"); + } + catch (QpidException e) + { + _logger.Error("Error creating destination", e); + throw e; + } + _messageCount++; + if (_messageCount % 1000 == 0) + { + _logger.Info("Received message total: " + _messageCount); + _logger.Info(string.Format("Sending response to '{0}:{1}'", + _replyToExchangeName, _replyToRoutingKey)); + } + + try + { + String payload = "This is a response: sing together: 'Mahnah mahnah...'" + tm.Text; + ITextMessage msg = _channel.CreateTextMessage(payload); + if (tm.Headers.Contains("timeSent")) + { +// _logger.Info("timeSent property set on message"); +// _logger.Info("timeSent value is: " + tm.Headers["timeSent"]); + msg.Headers["timeSent"] = tm.Headers["timeSent"]; + } + _destinationPublisher.Send(msg); + if (_messageCount % 1000 == 0) + { + _logger.Info(string.Format("Sending response to '{0}:{1}'", + _replyToExchangeName, _replyToRoutingKey)); + } + } + catch (QpidException e) + { + _logger.Error("Error sending message: " + e, e); + throw e; + } + } + } +} diff --git a/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs b/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs new file mode 100644 index 0000000000..582f022719 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/requestreply1/ServiceRequestingClient.cs @@ -0,0 +1,215 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + [TestFixture] + public class ServiceRequestingClient : BaseMessagingTestFixture + { + private const int MESSAGE_SIZE = 1024; + private static string MESSAGE_DATA = new string('x', MESSAGE_SIZE); + + private const int NUM_MESSAGES = 10000; + + private static ILog _log = LogManager.GetLogger(typeof(ServiceRequestingClient)); + + AutoResetEvent _finishedEvent = new AutoResetEvent(false); + + private int _expectedMessageCount = NUM_MESSAGES; + + private long _startTime; + + private string _commandQueueName = "ServiceQ1"; + + private IMessagePublisher _publisher; + + Avergager averager = new Avergager(); + + private void InitialiseProducer() + { + try + { + _publisher = _channel.CreatePublisherBuilder() + .withRoutingKey(_commandQueueName) + .Create(); + _publisher.DisableMessageTimestamp = true; // XXX: need a "with" for this in builder? + _publisher.DeliveryMode = DeliveryMode.NonPersistent; // XXX: need a "with" for this in builder? + } + catch (QpidException e) + { + _log.Error("Error: " + e, e); + } + } + + [Test] + public void SendMessages() + { + InitialiseProducer(); + + string replyQueueName = _channel.GenerateUniqueName(); + + _channel.DeclareQueue(replyQueueName, false, true, true); + + IMessageConsumer messageConsumer = _channel.CreateConsumerBuilder(replyQueueName) + .withPrefetch(100) + .withNoLocal(true) + .withExclusive(true).Create(); + + _startTime = DateTime.Now.Ticks; + + messageConsumer.OnMessage = new MessageReceivedDelegate(OnMessage); + _connection.Start(); + for (int i = 0; i < _expectedMessageCount; i++) + { + ITextMessage msg; + try + { + msg = _channel.CreateTextMessage(MESSAGE_DATA + i); + } + catch (Exception e) + { + _log.Error("Error creating message: " + e, e); + break; + } + msg.ReplyToRoutingKey = replyQueueName; + + // Added timestamp. + long timeNow = DateTime.Now.Ticks; + string timeSentString = String.Format("{0:G}", timeNow); +// _log.Info(String.Format("timeSent={0} timeSentString={1}", timeNow, timeSentString)); + msg.Headers.SetString("timeSent", timeSentString); + //msg.Headers.SetLong("sentAt", timeNow); + + try + { + _publisher.Send(msg); + } + catch (Exception e) + { + _log.Error("Error sending message: " + e, e); + //base._port = 5673; + _log.Info("Reconnecting but on port 5673"); + try + { + base.Init(); + InitialiseProducer(); + // cheesy but a quick test + _log.Info("Calling SendMessages again"); + SendMessages(); + } + catch (Exception ex) + { + _log.Error("Totally busted: failed to reconnect: " + ex, ex); + } + } + } + + // Assert that the test finishes within a reasonable amount of time. + const int waitSeconds = 10; + const int waitMilliseconds = waitSeconds * 1000; + _log.Info("Finished sending " + _expectedMessageCount + " messages"); + _log.Info(String.Format("Waiting {0} seconds to receive last message...", waitSeconds)); + Assert.IsTrue(_finishedEvent.WaitOne(waitMilliseconds, false), + String.Format("Expected to finish in {0} seconds", waitSeconds)); + } + + public void OnMessage(IMessage m) + { + if (_log.IsDebugEnabled) + { + _log.Debug("Message received: " + m); + } + + //if (m.Headers.Contains("sentAt")) + if (!m.Headers.Contains("timeSent")) + { + throw new Exception("Set timeSent!"); + } + //long sentAt = m.Headers.GetLong("sentAt"); + long sentAt = Int64.Parse(m.Headers.GetString("timeSent")); + long now = DateTime.Now.Ticks; + long latencyTicks = now - sentAt; +// _log.Info(String.Format("latency = {0} ticks ", latencyTicks)); + long latencyMilliseconds = latencyTicks / TimeSpan.TicksPerMillisecond; +// _log.Info(String.Format("latency = {0} ms", latencyMilliseconds)); + + averager.Add(latencyMilliseconds); + + // Output average every 1000 messages. + if (averager.Num % 1000 == 0) + { + _log.Info("Ticks per millisecond = " + TimeSpan.TicksPerMillisecond); + _log.Info(String.Format("Average latency (ms) = {0}", averager)); + _log.Info("Received message count: " + averager.Num); + } + + if (averager.Num == _expectedMessageCount) + { + _log.Info(String.Format("Final average latency (ms) = {0}", averager)); + + double timeTakenSeconds = (DateTime.Now.Ticks - _startTime) * 1.0 / (TimeSpan.TicksPerMillisecond * 1000); + _log.Info("Total time taken to receive " + _expectedMessageCount + " messages was " + + timeTakenSeconds + "s, equivalent to " + + (_expectedMessageCount/timeTakenSeconds) + " messages per second"); + + _finishedEvent.Set(); // Notify main thread to quit. + } + } + + public static void Main(String[] args) + { + ServiceRequestingClient c = new ServiceRequestingClient(); + c.Init(); + c.SendMessages(); + } + } + + class Avergager + { + long num = 0; + long sum = 0; + + long min = long.MaxValue; + long max = long.MinValue; + + public void Add(long item) + { + ++num; + sum += item; + if (item < min) min = item; + if (item > max) max = item; + } + + public long Average { get { return sum/num; }} + + public long Num { get { return num; } } + + public override string ToString() + { + return String.Format("average={0} min={1} max={2}", Average, min, max); + } + } +} diff --git a/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs b/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs new file mode 100644 index 0000000000..63c936d667 --- /dev/null +++ b/dotnet/Qpid.Client.Tests/undeliverable/UndeliverableTest.cs @@ -0,0 +1,94 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using NUnit.Framework; +using Qpid.Messaging; + +namespace Qpid.Client.Tests +{ + [TestFixture] + public class UndeliverableTest : BaseMessagingTestFixture + { + private static ILog _logger = LogManager.GetLogger(typeof(UndeliverableTest)); + + [SetUp] + public override void Init() + { + base.Init(); + + try + { + _connection.ExceptionListener = new ExceptionListenerDelegate(OnException); + } + catch (QpidException e) + { + _logger.Error("Could not add ExceptionListener", e); + } + } + + public static void OnException(Exception e) + { + // Here we dig out the AMQUndelivered exception (if present) in order to log the returned message. + + _logger.Error("OnException handler received connection-level exception", e); + if (e is QpidException) + { + QpidException qe = (QpidException)e; + if (qe.InnerException is AMQUndeliveredException) + { + AMQUndeliveredException ue = (AMQUndeliveredException)qe.InnerException; + _logger.Error("inner exception is AMQUndeliveredException", ue); + _logger.Error(string.Format("Returned message = {0}", ue.GetUndeliveredMessage())); + + } + } + } + + [Test] + public void SendUndeliverableMessage() + { + SendOne("default exchange", null); + SendOne("direct exchange", ExchangeNameDefaults.DIRECT); + SendOne("topic exchange", ExchangeNameDefaults.TOPIC); + SendOne("headers exchange", ExchangeNameDefaults.HEADERS); + + Thread.Sleep(1000); // Wait for message returns! + } + + private void SendOne(string exchangeNameFriendly, string exchangeName) + { + _logger.Info("Sending undeliverable message to " + exchangeNameFriendly); + + // Send a test message to a non-existant queue on the default exchange. See if message is returned! + MessagePublisherBuilder builder = _channel.CreatePublisherBuilder() + .withRoutingKey("Non-existant route key!") + .withMandatory(true); + if (exchangeName != null) + { + builder.withExchangeName(exchangeName); + } + IMessagePublisher publisher = builder.Create(); + publisher.Send(_channel.CreateTextMessage("Hiya!")); + } + } +} diff --git a/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs b/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs new file mode 100644 index 0000000000..d165e33467 --- /dev/null +++ b/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs @@ -0,0 +1,115 @@ +/* + * + * 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. + * + */ +using System; +using System.Net; +using System.Net.Sockets; +using log4net; +using Qpid.Buffer; +using Qpid.Client.Protocol; + +namespace Qpid.Client.Transport.Socket.Blocking +{ + class BlockingSocketProcessor : IConnectionCloser + { + private static readonly ILog _log = LogManager.GetLogger(typeof(BlockingSocketProcessor)); + + string _host; + int _port; + System.Net.Sockets.Socket _socket; + private NetworkStream _networkStream; + IByteChannel _byteChannel; + IProtocolListener _protocolListener; + + public BlockingSocketProcessor(string host, int port, IProtocolListener protocolListener) + { + _host = host; + _port = port; + _protocolListener = protocolListener; + _byteChannel = new ByteChannel(this); + } + + /// <summary> + /// Synchronous blocking connect. + /// </summary> + public void Connect() + { + _socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + IPHostEntry ipHostInfo = Dns.Resolve(_host); + IPAddress ipAddress = ipHostInfo.AddressList[0]; + + IPEndPoint ipe = new IPEndPoint(ipAddress, _port); + + _socket.Connect(ipe); + _networkStream = new NetworkStream(_socket, true); + } + + public string getLocalEndPoint() + { + return _socket.LocalEndPoint.ToString(); + } + + public void Write(ByteBuffer byteBuffer) + { + try + { + _networkStream.Write(byteBuffer.ToByteArray(), byteBuffer.Position, byteBuffer.Limit); + } + catch (Exception e) + { + _log.Error("Write caused exception", e); + _protocolListener.OnException(e); + } + } + + public ByteBuffer Read() + { + const int bufferSize = 4 * 1024; // TODO: Prevent constant allocation of buffers. + byte[] bytes = new byte[bufferSize]; + + int numOctets = _networkStream.Read(bytes, 0, bytes.Length); + + ByteBuffer byteBuffer = HeapByteBuffer.wrap(bytes, numOctets); + + byteBuffer.Flip(); + + return byteBuffer; + } + + public void Disconnect() + { + _networkStream.Flush(); + _networkStream.Close(); + _socket.Close(); + } + + public void Close() + { + Disconnect(); + } + + public IByteChannel ByteChannel + { + get { return _byteChannel; } + } + } +} + diff --git a/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs b/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs new file mode 100644 index 0000000000..744a949d08 --- /dev/null +++ b/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs @@ -0,0 +1,120 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Threading; +using log4net; +using Qpid.Client.Protocol; +using Qpid.Framing; + +namespace Qpid.Client.Transport.Socket.Blocking +{ + public class BlockingSocketTransport : ITransport + { + static readonly ILog _log = LogManager.GetLogger(typeof(BlockingSocketTransport)); + + // Configuration variables. + string _host; + int _port; + IProtocolListener _protocolListener; + + // Runtime variables. + private BlockingSocketProcessor _socketProcessor; + private AmqpChannel _amqpChannel; + + private ReaderRunner _readerRunner; + private Thread _readerThread; + + public BlockingSocketTransport(string host, int port, AMQConnection connection) + { + _host = host; + _port = port; + _protocolListener = connection.ProtocolListener; + } + + public void Open() + { + _socketProcessor = new BlockingSocketProcessor(_host, _port, _protocolListener); + _socketProcessor.Connect(); + _amqpChannel = new AmqpChannel(_socketProcessor.ByteChannel); + _readerRunner = new ReaderRunner(this); + _readerThread = new Thread(new ThreadStart(_readerRunner.Run)); + _readerThread.Start(); + } + + public string getLocalEndPoint() + { + return _socketProcessor.getLocalEndPoint(); + } + + public void Close() + { + StopReaderThread(); + _socketProcessor.Disconnect(); + } + + public IProtocolChannel ProtocolChannel { get { return _amqpChannel; } } + public IProtocolWriter ProtocolWriter { get { return _amqpChannel; } } + + public void StopReaderThread() + { + _readerRunner.Stop(); + } + + class ReaderRunner + { + BlockingSocketTransport _transport; + bool _running = true; + + public ReaderRunner(BlockingSocketTransport transport) + { + _transport = transport; + } + + public void Run() + { + try + { + while (_running) + { + Queue frames = _transport.ProtocolChannel.Read(); + + foreach (IDataBlock dataBlock in frames) + { + _transport._protocolListener.OnMessage(dataBlock); + } + } + } + catch (Exception e) + { + _transport._protocolListener.OnException(e); + } + } + + public void Stop() + { + // TODO: Check if this is thread safe. running is not volitile.... + _running = false; + } + } + } +} + diff --git a/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs b/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs new file mode 100644 index 0000000000..07784b750c --- /dev/null +++ b/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ +using System; +using log4net; +using Qpid.Buffer; + +namespace Qpid.Client.Transport.Socket.Blocking +{ + class ByteChannel : IByteChannel + { + // Warning: don't use this log for regular logging. + private static readonly ILog _ioTraceLog = LogManager.GetLogger("Qpid.Client.ByteChannel.Tracing"); + + BlockingSocketProcessor processor; + + public ByteChannel(BlockingSocketProcessor processor) + { + this.processor = processor; + } + + public ByteBuffer Read() + { + ByteBuffer result = processor.Read(); + + // TODO: Move into decorator. + if (_ioTraceLog.IsDebugEnabled) + { + _ioTraceLog.Debug(String.Format("READ {0}", result)); + } + + return result; + } + + public void Write(ByteBuffer buffer) + { + // TODO: Move into decorator. + if (_ioTraceLog.IsDebugEnabled) + { + _ioTraceLog.Debug(String.Format("WRITE {0}", buffer)); + } + + processor.Write(buffer); + } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs b/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..54da92a22a --- /dev/null +++ b/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BlockingTransport")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("BlockingTransport")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ca23e89c-f5b9-4f7a-929a-4fae00ef055b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj b/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj new file mode 100644 index 0000000000..a710ef998e --- /dev/null +++ b/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj @@ -0,0 +1,71 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{52AC4940-2077-4104-A753-29A9C8C16957}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Client.Transport.Socket.Blocking</RootNamespace>
+ <AssemblyName>Qpid.Client.Transport.Socket.Blocking</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.0.30714, Culture=neutral, PublicKeyToken=500ffcafb14f92df">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BlockingSocketProcessor.cs" />
+ <Compile Include="BlockingSocketTransport.cs" />
+ <Compile Include="ByteChannel.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/dotnet/Qpid.Client/Client/AMQConnection.cs b/dotnet/Qpid.Client/Client/AMQConnection.cs new file mode 100644 index 0000000000..12eb9f6a21 --- /dev/null +++ b/dotnet/Qpid.Client/Client/AMQConnection.cs @@ -0,0 +1,845 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.IO; +using System.Reflection; +using System.Threading; +using log4net; +using Qpid.Client.Failover; +using Qpid.Client.Protocol; +using Qpid.Client.qms; +using Qpid.Client.State; +using Qpid.Client.Transport; +using Qpid.Collections; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client +{ + public class AMQConnection : Closeable, IConnection + { + private static readonly ILog _log = LogManager.GetLogger(typeof(AMQConnection)); + + ConnectionInfo _connectionInfo; + private int _nextChannelId = 0; + + // _Connected should be refactored with a suitable wait object. + private bool _connected; + + Thread _heartBeatThread; + HeartBeatThread _heartBeatRunner; + + // The last error code that occured on the connection. Used to return the correct exception to the client + private AMQException _lastAMQException = null; + + /** + * This is the "root" mutex that must be held when doing anything that could be impacted by failover. + * This must be held by any child objects of this connection such as the session, producers and consumers. + */ + private readonly Object _failoverMutex = new Object(); + public object FailoverMutex + { + get { return _failoverMutex; } + } + + /** + * Policy dictating how to failover + */ + private FailoverPolicy _failoverPolicy; + + internal bool IsFailoverAllowed + { + get { return _failoverPolicy.FailoverAllowed(); } + } + + /// <summary> + /// A channel is roughly analogous to a session. The server can negotiate the maximum number of channels + /// per session and we must prevent the client from opening too many. Zero means unlimited. + /// </summary> + private ushort _maximumChannelCount; + + /// <summary> + /// The maximum size of frame supported by the server + /// </summary> + private uint _maximumFrameSize; + + private AMQStateManager _stateManager; + + private AMQProtocolSession _protocolSession; + public AMQProtocolSession ProtocolSession { get { return _protocolSession; } } + + /// <summary> + /// Maps from session id (Integer) to AmqChannel instance + /// </summary> + private readonly LinkedHashtable _sessions = new LinkedHashtable(); + + private ExceptionListenerDelegate _exceptionListener; + + private IConnectionListener _connectionListener; + + private ITransport _transport; + public ITransport Transport { get { return _transport; } } + + /// <summary> + /// Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for + /// message publication. + /// </summary> + private bool _started; + + private AMQProtocolListener _protocolListener; + public AMQProtocolListener ProtocolListener { get { return _protocolListener; } } + + public IProtocolWriter ProtocolWriter + { + get { return _transport.ProtocolWriter; } + } + + ProtocolWriter _protocolWriter; + + public ProtocolWriter ConvenientProtocolWriter + { + get { return _protocolWriter; } + } + + public AMQConnection(ConnectionInfo connectionInfo) + { + if (connectionInfo == null) + { + throw new ArgumentException("ConnectionInfo must be specified"); + } + _log.Info("ConnectionInfo: " + connectionInfo); + _connectionInfo = connectionInfo; + _log.Info("password = " + _connectionInfo.getPassword()); + _failoverPolicy = new FailoverPolicy(connectionInfo); + + // We are not currently connected. + _connected = false; + + Exception lastException = null; + do + { + try + { + BrokerInfo brokerInfo = _failoverPolicy.GetNextBrokerInfo(); + _log.Info("Connecting to " + brokerInfo); + MakeBrokerConnection(brokerInfo); + break; + } + catch (Exception e) + { + lastException = e; + _log.Error("Unable to connect to broker " + _failoverPolicy.GetCurrentBrokerInfo(), e); + // XXX: Should perhaps break out of the do/while here if not a SocketException... + } + } while (_failoverPolicy.FailoverAllowed()); + + _log.Debug("Are we connected:" + _connected); + + if (!_failoverPolicy.FailoverAllowed()) + { + throw new AMQConnectionException("Unable to connect", lastException); + } + + // TODO: this needs to be redone so that we are not spinning. + // A suitable object should be set that is then waited on + // and only notified when a connection is made or when + // the AMQConnection gets closed. + while (!_connected && !Closed) + { + _log.Debug("Sleeping."); + Thread.Sleep(100); + } + if (!_failoverPolicy.FailoverAllowed() || _failoverPolicy.GetCurrentBrokerInfo() == null) + { + if (_lastAMQException != null) + { + throw _lastAMQException; + } + } + } + + private ITransport LoadTransportFromAssembly(string host, int port, String assemblyName, String transportType) + { + Assembly assembly = Assembly.LoadFrom(assemblyName); + foreach (Type type in assembly.GetTypes()) + { + _log.Info(String.Format("type = {0}", type)); + } + Type transport = assembly.GetType(transportType); + if (transport == null) + { + throw new ArgumentException( + String.Format("Type is not found in assembly. Type={0} Assembly={1}", transportType, assemblyName)); + + } + _log.Info("transport = " + transport); + _log.Info("ctors = " + transport.GetConstructors()); + ConstructorInfo info = transport.GetConstructors()[0]; + ITransport result = (ITransport)info.Invoke(new object[] { host, port, this }); + + _log.Info("transport = " + result); + return result; + } + + public void Disconnect() + { + _transport.Close(); + } + + #region IConnection Members + + public string ClientID + { + get + { + CheckNotClosed(); + return _connectionInfo.GetClientName(); + } + set + { + CheckNotClosed(); + _connectionInfo.SetClientName(value); + } + } + + public override void Close() + { + lock (FailoverMutex) + { + // atomically set to closed and check the _previous value was NOT CLOSED + if (Interlocked.Exchange(ref _closed, CLOSED) == NOT_CLOSED) + { + try + { + CloseAllSessions(null); + CloseConnection(); + } + catch (AMQException e) + { + throw new QpidException("Error closing connection: " + e); + } + } + } + } + + private void CloseConnection() + { + _stateManager.ChangeState(AMQState.CONNECTION_CLOSING); + + AMQFrame frame = ConnectionCloseBody.CreateAMQFrame( + 0, 200, "Qpid.NET client is closing the connection.", 0, 0); + + ProtocolWriter.Write(frame); + + _log.Debug("Blocking for connection close ok frame"); + + _stateManager.AttainState(AMQState.CONNECTION_CLOSED); + Disconnect(); + } + + class CreateChannelFailoverSupport : FailoverSupport + { + private static readonly ILog _log = LogManager.GetLogger(typeof(CreateChannelFailoverSupport)); + + private bool _transacted; + private AcknowledgeMode _acknowledgeMode; + int _prefetch; + AMQConnection _connection; + + public CreateChannelFailoverSupport(AMQConnection connection, bool transacted, AcknowledgeMode acknowledgementMode, int prefetch) + { + _connection = connection; + _transacted = transacted; + _acknowledgeMode = acknowledgementMode; + _prefetch = prefetch; + } + + protected override object operation() + { + ushort channelId = _connection.NextChannelId(); + + if (_log.IsDebugEnabled) + { + _log.Debug("Write channel open frame for channel id " + channelId); + } + + // We must create the channel and register it before actually sending the frame to the server to + // open it, so that there is no window where we could receive data on the channel and not be set + // up to handle it appropriately. + AmqChannel channel = new AmqChannel(_connection, + channelId, _transacted, _acknowledgeMode, _prefetch); + _connection.ProtocolSession.AddSessionByChannel(channelId, channel); + _connection.RegisterSession(channelId, channel); + + bool success = false; + try + { + _connection.createChannelOverWire(channelId, (ushort)_prefetch, _transacted); + success = true; + } + catch (AMQException e) + { + throw new QpidException("Error creating channel: " + e, e); + } + finally + { + if (!success) { + _connection.ProtocolSession.RemoveSessionByChannel(channelId); + _connection.DeregisterSession(channelId); + } + } + + if (_connection._started) + { + channel.Start(); + } + return channel; + } + } + + internal ushort NextChannelId() + { + return (ushort) Interlocked.Increment(ref _nextChannelId); + } + + public IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode) + { + return CreateChannel(transacted, acknowledgeMode, AmqChannel.DEFAULT_PREFETCH); + } + + public IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode, int prefetch) + { + CheckNotClosed(); + if (ChannelLimitReached()) + { + throw new ChannelLimitReachedException(_maximumChannelCount); + } + else + { + CreateChannelFailoverSupport operation = + new CreateChannelFailoverSupport(this, transacted, acknowledgeMode, prefetch); + return (IChannel)operation.execute(this); + } + } + + public void CloseSession(AmqChannel channel) + { + _protocolSession.CloseSession(channel); + + AMQFrame frame = ChannelCloseBody.CreateAMQFrame( + channel.ChannelId, 200, "JMS client closing channel", 0, 0); + + _log.Debug("Blocking for channel close frame for channel " + channel.ChannelId); + _protocolWriter.SyncWrite(frame, typeof(ChannelCloseOkBody)); + _log.Debug("Received channel close frame"); + // When control resumes at this point, a reply will have been received that + // indicates the broker has closed the channel successfully + } + + public ExceptionListenerDelegate ExceptionListener + { + get + { + CheckNotClosed(); + return _exceptionListener; + } + set + { + CheckNotClosed(); + _exceptionListener = value; + } + } + + /// <summary> + /// Start the connection, i.e. start flowing messages. Note that this method must be called only from a single thread + /// and is not thread safe (which is legal according to the JMS specification). + /// @throws JMSException + /// </summary> + public void Start() + { + CheckNotClosed(); + if (!_started) + { + foreach (DictionaryEntry lde in _sessions) + { + AmqChannel s = (AmqChannel)lde.Value; + s.Start(); + } + _started = true; + } + } + + public void Stop() + { + CheckNotClosed(); + throw new NotImplementedException(); + } + + public IConnectionListener ConnectionListener + { + get { return _connectionListener; } + set { _connectionListener = value; } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + Close(); + } + + #endregion + + private bool ChannelLimitReached() + { + return _maximumChannelCount != 0 && _sessions.Count == _maximumChannelCount; + } + + /// <summary> + /// Close all the sessions, either due to normal connection closure or due to an error occurring. + /// @param cause if not null, the error that is causing this shutdown + /// </summary> + private void CloseAllSessions(Exception cause) + { + _log.Info("Closing all session in connection " + this); + ICollection sessions = new ArrayList(_sessions.Values); + foreach (AmqChannel channel in sessions) + { + _log.Info("Closing channel " + channel); + if (cause != null) + { + channel.Closed(cause); + } + else + { + try + { + channel.Close(); + } + catch (QpidException e) + { + _log.Error("Error closing channel: " + e); + } + } + } + _log.Info("Done closing all sessions in connection " + this); + } + + public int MaximumChannelCount + { + get + { + CheckNotClosed(); + return _maximumChannelCount; + } + } + + internal void SetMaximumChannelCount(ushort maximumChannelCount) + { + CheckNotClosed(); + _maximumChannelCount = maximumChannelCount; + } + + public uint MaximumFrameSize + { + get + { + return _maximumFrameSize; + } + + set + { + _maximumFrameSize = value; + } + } + + public IDictionary Sessions + { + get + { + return _sessions; + } + } + + public string Host + { + get + { + return _failoverPolicy.GetCurrentBrokerInfo().getHost(); + } + } + + public int Port + { + get + { + return _failoverPolicy.GetCurrentBrokerInfo().getPort(); + } + } + + public string Username + { + get + { + return _connectionInfo.getUsername(); + } + } + + public string Password + { + get + { + return _connectionInfo.getPassword(); + } + } + + public string VirtualHost + { + get + { + return _connectionInfo.getVirtualHost(); + } + } + + /// <summary> + /// Invoked by the AMQProtocolSession when a protocol session exception has occurred. + /// This method sends the exception to a JMS exception listener, if configured, and + /// propagates the exception to sessions, which in turn will propagate to consumers. + /// This allows synchronous consumers to have exceptions thrown to them. + /// </summary> + /// <param name="cause">the exception</param> + public void ExceptionReceived(Exception cause) + { + if (_exceptionListener != null) + { + // Listener expects one of these... + QpidException xe; + + if (cause is QpidException) + { + xe = (QpidException) cause; + } + else + { + xe = new QpidException("Exception thrown against " + ToString() + ": " + cause, cause); + } + // in the case of an IOException, MINA has closed the protocol session so we set _closed to true + // so that any generic client code that tries to close the connection will not mess up this error + // handling sequence + if (cause is IOException) + { + Interlocked.Exchange(ref _closed, CLOSED); + } + _exceptionListener.Invoke(xe); + } + else + { + _log.Error("Connection exception: " + cause); + } + + // An undelivered is not fatal to the connections usability. + if (!(cause is AMQUndeliveredException)) + { + Interlocked.Exchange(ref _closed, CLOSED); + CloseAllSessions(cause); + } + else + { + ; + } + } + + internal void RegisterSession(int channelId, AmqChannel channel) + { + _sessions[channelId] = channel; + } + + internal void DeregisterSession(int channelId) + { + _sessions.Remove(channelId); + } + + /** + * Fire the preFailover event to the registered connection listener (if any) + * + * @param redirect true if this is the result of a redirect request rather than a connection error + * @return true if no listener or listener does not veto change + */ + public bool FirePreFailover(bool redirect) + { + bool proceed = true; + if (_connectionListener != null) + { + proceed = _connectionListener.PreFailover(redirect); + } + return proceed; + } + + /** + * Fire the preResubscribe event to the registered connection listener (if any). If the listener + * vetoes resubscription then all the sessions are closed. + * + * @return true if no listener or listener does not veto resubscription. + * @throws JMSException + */ + public bool FirePreResubscribe() + { + if (_connectionListener != null) + { + bool resubscribe = _connectionListener.PreResubscribe(); + if (!resubscribe) + { + MarkAllSessionsClosed(); + } + return resubscribe; + } + else + { + return true; + } + } + + /** + * Marks all sessions and their children as closed without sending any protocol messages. Useful when + * you need to mark objects "visible" in userland as closed after failover or other significant event that + * impacts the connection. + * <p/> + * The caller must hold the failover mutex before calling this method. + */ + private void MarkAllSessionsClosed() + { + //LinkedList sessionCopy = new LinkedList(_sessions.values()); + ArrayList sessionCopy = new ArrayList(_sessions.Values); + foreach (AmqChannel session in sessionCopy) + { + session.MarkClosed(); + } + _sessions.Clear(); + } + + /** + * Fires a failover complete event to the registered connection listener (if any). + */ + public void FireFailoverComplete() + { + if (_connectionListener != null) + { + _connectionListener.FailoverComplete(); + } + } + + public bool AttemptReconnection(String host, int port, bool useSSL) + { + BrokerInfo bd = new AmqBrokerInfo("amqp", host, port, useSSL); + + _failoverPolicy.setBroker(bd); + + try + { + MakeBrokerConnection(bd); + return true; + } + catch (Exception e) + { + _log.Info("Unable to connect to broker at " + bd, e); + AttemptReconnection(); + } + return false; + } + + private void MakeBrokerConnection(BrokerInfo brokerDetail) + { + try + { + _stateManager = new AMQStateManager(); + _protocolListener = new AMQProtocolListener(this, _stateManager); + _protocolListener.AddFrameListener(_stateManager); + + // Currently there is only one transport option - BlockingSocket. + String assemblyName = "Qpid.Client.Transport.Socket.Blocking.dll"; + String transportType = "Qpid.Client.Transport.Socket.Blocking.BlockingSocketTransport"; + + // Load the transport assembly dynamically. + _transport = LoadTransportFromAssembly(brokerDetail.getHost(), brokerDetail.getPort(), assemblyName, transportType); + + // Connect. + _transport.Open(); + _protocolWriter = new ProtocolWriter(_transport.ProtocolWriter, _protocolListener); + _protocolSession = new AMQProtocolSession(_transport.ProtocolWriter, _transport, this); + _protocolListener.ProtocolSession = _protocolSession; + + // Now start the connection "handshake". + _transport.ProtocolWriter.Write(new ProtocolInitiation()); + + // Blocks until the connection has been opened. + _stateManager.AttainState(AMQState.CONNECTION_OPEN); + + _failoverPolicy.attainedConnection(); + + // XXX: Again this should be changed to a suitable notify. + _connected = true; + } + catch (AMQException e) + { + _lastAMQException = e; + throw e; + } + } + + public bool AttemptReconnection() + { + while (_failoverPolicy.FailoverAllowed()) + { + try + { + MakeBrokerConnection(_failoverPolicy.GetNextBrokerInfo()); + return true; + } + catch (Exception e) + { + if (!(e is AMQException)) + { + _log.Info("Unable to connect to broker at " + _failoverPolicy.GetCurrentBrokerInfo(), e); + } + else + { + _log.Info(e.Message + ":Unable to connect to broker at " + _failoverPolicy.GetCurrentBrokerInfo()); + } + } + } + + // Connection unsuccessful. + return false; + } + + /** + * For all sessions, and for all consumers in those sessions, resubscribe. This is called during failover handling. + * The caller must hold the failover mutex before calling this method. + */ + public void ResubscribeSessions() + { + ArrayList sessions = new ArrayList(_sessions.Values); + _log.Info(String.Format("Resubscribing sessions = {0} sessions.size={1}", sessions, sessions.Count)); + foreach (AmqChannel s in sessions) + { + _protocolSession.AddSessionByChannel(s.ChannelId, s); + ReopenChannel(s.ChannelId, (ushort)s.DefaultPrefetch, s.Transacted); + s.Resubscribe(); + } + } + + private void ReopenChannel(ushort channelId, ushort prefetch, bool transacted) + { + try + { + createChannelOverWire(channelId, prefetch, transacted); + } + catch (AMQException e) + { + _protocolSession.RemoveSessionByChannel(channelId); + DeregisterSession(channelId); + throw new AMQException("Error reopening channel " + channelId + " after failover: " + e); + } + } + + void createChannelOverWire(ushort channelId, ushort prefetch, bool transacted) + { + _protocolWriter.SyncWrite(ChannelOpenBody.CreateAMQFrame(channelId, null), typeof (ChannelOpenOkBody)); + + // Don't use the BasicQos frame if connecting to OpenAMQ (at it is not support). We + // know this when we connection using AMQP 0.7 + if (ProtocolInitiation.CURRENT_PROTOCOL_VERSION_MAJOR != 7) + { + // Basic.Qos frame appears to not be supported by OpenAMQ 1.0d. + _protocolWriter.SyncWrite( + BasicQosBody.CreateAMQFrame(channelId, 0, prefetch, false), + typeof (BasicQosOkBody)); + } + + + if (transacted) + { + if (_log.IsDebugEnabled) + { + _log.Debug("Issuing TxSelect for " + channelId); + } + _protocolWriter.SyncWrite(TxSelectBody.CreateAMQFrame(channelId), typeof(TxSelectOkBody)); + } + } + + public String toURL() + { + return _connectionInfo.asUrl(); + } + + class HeartBeatThread + { + int _heartbeatMillis; + IProtocolWriter _protocolWriter; + bool _run = true; + + public HeartBeatThread(IProtocolWriter protocolWriter, int heartbeatMillis) + { + _protocolWriter = protocolWriter; + _heartbeatMillis = heartbeatMillis; + } + + public void Run() + { + while (_run) + { + Thread.Sleep(_heartbeatMillis); + if (!_run) break; + _log.Debug("Sending heartbeat"); + // TODO: Can we optimise this so that heartbeats are only written when we haven't sent anything recently to the broker? + _protocolWriter.Write(HeartbeatBody.FRAME); + } + _log.Info("Heatbeat thread stopped"); + } + + public void Stop() + { + _run = false; + } + } + + public void StartHeartBeatThread(int heartbeatSeconds) + { + _log.Info("Starting new heartbeat thread"); + _heartBeatRunner = new HeartBeatThread(ProtocolWriter, heartbeatSeconds * 1000); + _heartBeatThread = new Thread(new ThreadStart(_heartBeatRunner.Run)); + _heartBeatThread.Name = "HeartBeat"; + _heartBeatThread.Start(); + } + + public void StopHeartBeatThread() + { + if (_heartBeatRunner != null) + { + _log.Info("Stopping old heartbeat thread"); + _heartBeatRunner.Stop(); + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/AMQConnectionException.cs b/dotnet/Qpid.Client/Client/AMQConnectionException.cs new file mode 100644 index 0000000000..603a7b2a1c --- /dev/null +++ b/dotnet/Qpid.Client/Client/AMQConnectionException.cs @@ -0,0 +1,31 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client +{ + public class AMQConnectionException : AMQException + { + public AMQConnectionException(String message, Exception e) : base(message, e) + { + } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/Client/AMQDestination.cs b/dotnet/Qpid.Client/Client/AMQDestination.cs new file mode 100644 index 0000000000..7ea6db4ee8 --- /dev/null +++ b/dotnet/Qpid.Client/Client/AMQDestination.cs @@ -0,0 +1,233 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client +{ + public abstract class AMQDestination + { + protected readonly string _exchangeName; + protected readonly string _exchangeClass; + protected readonly string _destinationName; + protected readonly bool _isExclusive; + protected readonly bool _isAutoDelete; + protected bool _isDurable; + + public bool IsDurable + { + get { return _isDurable; } + } + + protected string _queueName; + + protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, bool isExclusive, + bool isAutoDelete, String queueName) + { + // XXX: This is ugly - OnlyRequired because of ReplyToDestination. +// if (destinationName == null) +// { +// throw new ArgumentNullException("destinationName"); +// } + + // XXX: This is ugly - OnlyRequired because of SendingDestinationAdapter. +// if (exchangeName == null) +// { +// throw new ArgumentNullException("exchangeName"); +// } + + // XXX: This is ugly - OnlyRequired because of SendingDestinationAdapter. +// if (exchangeClass == null) +// { +// throw new ArgumentNullException("exchangeClass"); +// } + + _exchangeName = exchangeName; + _exchangeClass = exchangeClass; + _destinationName = destinationName; + _isExclusive = isExclusive; + _isAutoDelete = isAutoDelete; + _queueName = queueName; + } + + public string Name + { + get + { + return _destinationName; + } + } + + public abstract string RoutingKey + { + get; + } + + public abstract string EncodedName + { + get; + } + + public bool AutoDelete + { + get + { + return _isAutoDelete; + } + } + + public string QueueName + { + get + { + return _queueName; + } + set + { + _queueName = value; + } + } + + public string ExchangeName + { + get + { + return _exchangeName; + } + } + + public string ExchangeClass + { + get + { + return _exchangeClass; + } + } + + public bool IsExclusive + { + get + { + return _isExclusive; + } + } + + public bool IsAutoDelete + { + get + { + return _isAutoDelete; + } + } + + public override string ToString() + { + return "Destination: " + _destinationName + ", " + + "Queue Name: " + _queueName + ", Exchange: " + _exchangeName + + ", Exchange class: " + _exchangeClass + ", Exclusive: " + _isExclusive + + ", AutoDelete: " + _isAutoDelete; // +", Routing Key: " + RoutingKey; + } + + public override bool Equals(object o) + { + if (this == o) + { + return true; + } + if (o == null || GetType() != o.GetType()) + { + return false; + } + + AMQDestination that = (AMQDestination) o; + + if (!StringsNotEqualNullSafe(_destinationName, that._destinationName)) + { + return false; + } + if (!StringsNotEqualNullSafe(_exchangeClass, that._exchangeClass)) + { + return false; + } + if (!StringsNotEqualNullSafe(_exchangeName, that._exchangeName)) + { + return false; + } + if (!StringsNotEqualNullSafe(_queueName, that._queueName)) + { + return false; + } + if (_isExclusive != that._isExclusive) + { + return false; + } + if (_isAutoDelete != that._isAutoDelete) + { + return false; + } + return true; + } + + private bool StringsNotEqualNullSafe(string one, string two) + { + if ((one == null && two != null) || + (one != null && !one.Equals(two))) + { + return false; + } + else + { + return true; + } + } + + public override int GetHashCode() + { + int result; + if (_exchangeName == null) + { + result = "".GetHashCode(); + } + else + { + result = _exchangeName.GetHashCode(); + } + if (_exchangeClass != null) + { + result = 29 * result + _exchangeClass.GetHashCode(); + } + if (_destinationName != null) + { + result = 29 * result + _destinationName.GetHashCode(); + } + if (_queueName != null) + { + result = 29 * result + _queueName.GetHashCode(); + } + result = result * (_isExclusive ? 13 : 7); + result = result * (_isAutoDelete ? 13 : 7); + + Console.WriteLine("FIXME HashCode for " + this + " = " + result); + return result; + } + + public abstract bool IsNameRequired { get; } + } +} diff --git a/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs b/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs new file mode 100644 index 0000000000..c00a427494 --- /dev/null +++ b/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs @@ -0,0 +1,313 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Text; +using Qpid.Client.qms; + +namespace Qpid.Client +{ + public class AmqBrokerInfo : BrokerInfo + { + private string _host = "localhost"; + private int _port = 5672; + private string _transport = "amqp"; + + public readonly string URL_FORMAT_EXAMPLE = + "<transport>://<hostname>[:<port Default=\""+BrokerDetailsConstants.DEFAULT_PORT+"\">][?<option>='<value>'[,<option>='<value>']]"; + + public const long DEFAULT_CONNECT_TIMEOUT = 30000L; + + private Hashtable _options = new Hashtable(); + + public AmqBrokerInfo() + { + } + + // TODO: port URL parsing. + public AmqBrokerInfo(string url) + { + throw new NotImplementedException(); +// this(); +// // URL should be of format tcp://host:port?option='value',option='value' +// try +// { +// URI connection = new URI(url); +// +// string transport = connection.getScheme(); +// +// // Handles some defaults to minimise changes to existing broker URLS e.g. localhost +// if (transport != null) +// { +// //todo this list of valid transports should be enumerated somewhere +// if ((!(transport.equalsIgnoreCase("vm") || +// transport.equalsIgnoreCase("tcp")))) +// { +// if (transport.equalsIgnoreCase("localhost")) +// { +// connection = new URI(DEFAULT_TRANSPORT + "://" + url); +// transport = connection.getScheme(); +// } +// else +// { +// if (url.charAt(transport.length()) == ':' && url.charAt(transport.length()+1) != '/' ) +// { +// //Then most likely we have a host:port value +// connection = new URI(DEFAULT_TRANSPORT + "://" + url); +// transport = connection.getScheme(); +// } +// else +// { +// URLHelper.parseError(0, transport.length(), "Unknown transport", url); +// } +// } +// } +// } +// else +// { +// //Default the transport +// connection = new URI(DEFAULT_TRANSPORT + "://" + url); +// transport = connection.getScheme(); +// } +// +// if (transport == null) +// { +// URLHelper.parseError(-1, "Unknown transport:'" + transport + "'" + +// " In broker URL:'" + url + "' Format: " + URL_FORMAT_EXAMPLE, ""); +// } +// +// setTransport(transport); +// +// string host = connection.getHost(); +// +// // Fix for Java 1.5 +// if (host == null) +// { +// host = ""; +// } +// +// setHost(host); +// +// int port = connection.getPort(); +// +// if (port == -1) +// { +// // Another fix for Java 1.5 URI handling +// string auth = connection.getAuthority(); +// +// if (auth != null && auth.startsWith(":")) +// { +// setPort(Integer.parseInt(auth.substring(1))); +// } +// else +// { +// setPort(DEFAULT_PORT); +// } +// } +// else +// { +// setPort(port); +// } +// +// string querystring = connection.getQuery(); +// +// URLHelper.parseOptions(_options, querystring); +// +// //Fragment is #string (not used) +// } +// catch (URISyntaxException uris) +// { +// if (uris instanceof URLSyntaxException) +// { +// throw (URLSyntaxException) uris; +// } +// +// URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput()); +// } + } + + public AmqBrokerInfo(string transport, string host, int port, bool useSSL) : this() + { + _transport = transport; + _host = host; + _port = port; + + if (useSSL) + { + setOption(BrokerDetailsConstants.OPTIONS_SSL, "true"); + } + } + + public string getHost() + { + return _host; + } + + public void setHost(string _host) + { + this._host = _host; + } + + public int getPort() + { + return _port; + } + + public void setPort(int _port) + { + this._port = _port; + } + + public string getTransport() + { + return _transport; + } + + public void setTransport(string _transport) + { + this._transport = _transport; + } + + public string getOption(string key) + { + return (string)_options[key]; + } + + public void setOption(string key, string value) + { + _options[key] = value; + } + + public long getTimeout() + { + if (_options.ContainsKey(BrokerDetailsConstants.OPTIONS_CONNECT_TIMEOUT)) + { + try + { + return long.Parse((string)_options[BrokerDetailsConstants.OPTIONS_CONNECT_TIMEOUT]); + } + catch (FormatException nfe) + { + //Do nothing as we will use the default below. + } + } + + return BrokerDetailsConstants.DEFAULT_CONNECT_TIMEOUT; + } + + public void setTimeout(long timeout) + { + setOption(BrokerDetailsConstants.OPTIONS_CONNECT_TIMEOUT, timeout.ToString()); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append(_transport); + sb.Append("://"); + + if (!(_transport.ToLower().Equals("vm"))) + { + sb.Append(_host); + } + + sb.Append(':'); + sb.Append(_port); + + // XXX +// sb.Append(printOptionsURL()); + + return sb.ToString(); + } + + public override bool Equals(object o) + { + if (!(o is BrokerInfo)) + { + return false; + } + + BrokerInfo bd = (BrokerInfo) o; + + return StringEqualsIgnoreCase(_host, bd.getHost()) && + (_port == bd.getPort()) && + StringEqualsIgnoreCase(_transport, bd.getTransport()) && + (useSSL() == bd.useSSL()); + + //todo do we need to compare all the options as well? + } + + // TODO: move to util class. + private bool StringEqualsIgnoreCase(string one, string two) + { + return one.ToLower().Equals(two.ToLower()); + } + +// private string printOptionsURL() +// { +// stringBuffer optionsURL = new stringBuffer(); +// +// optionsURL.Append('?'); +// +// if (!(_options.isEmpty())) +// { +// +// for (string key : _options.keySet()) +// { +// optionsURL.Append(key); +// +// optionsURL.Append("='"); +// +// optionsURL.Append(_options.get(key)); +// +// optionsURL.Append("'"); +// +// optionsURL.Append(URLHelper.DEFAULT_OPTION_SEPERATOR); +// } +// } +// +// //remove the extra DEFAULT_OPTION_SEPERATOR or the '?' if there are no options +// optionsURL.deleteCharAt(optionsURL.length() - 1); +// +// return optionsURL.tostring(); +// } + + public bool useSSL() + { + // To be friendly to users we should be case insensitive. + // or simply force users to conform to OPTIONS_SSL + // todo make case insensitive by trying ssl Ssl sSl ssL SSl SsL sSL SSL + + if (_options.ContainsKey(BrokerDetailsConstants.OPTIONS_SSL)) + { + return StringEqualsIgnoreCase((string)_options[BrokerDetailsConstants.OPTIONS_SSL], "true"); + } + + return false; + } + + public void useSSL(bool ssl) + { + setOption(BrokerDetailsConstants.OPTIONS_SSL, ssl.ToString()); + } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/Client/AmqChannel.cs b/dotnet/Qpid.Client/Client/AmqChannel.cs new file mode 100644 index 0000000000..02818940dd --- /dev/null +++ b/dotnet/Qpid.Client/Client/AmqChannel.cs @@ -0,0 +1,1071 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Text.RegularExpressions; +using System.Threading; +using log4net; +using Qpid.Client.Message; +using Qpid.Collections; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client +{ + public class AmqChannel : Closeable, IChannel + { + private const int BASIC_CONTENT_TYPE = 60; + + private static readonly ILog _logger = LogManager.GetLogger(typeof (AmqChannel)); + + private static int _nextSessionNumber = 0; + + private int _sessionNumber; + + // Used in the consume method. We generate the consume tag on the client so that we can use the nowait feature. + private int _nextConsumerNumber = 1; + + internal const int DEFAULT_PREFETCH = 5000; + + private AMQConnection _connection; + + private bool _transacted; + + private AcknowledgeMode _acknowledgeMode; + + private ushort _channelId; + + private int _defaultPrefetch = DEFAULT_PREFETCH; + + private BlockingQueue _queue = new LinkedBlockingQueue(); + + private Dispatcher _dispatcher; + + private MessageFactoryRegistry _messageFactoryRegistry; + + /// <summary> + /// Set of all producers created by this session + /// </summary> + private Hashtable _producers = Hashtable.Synchronized(new Hashtable()); + + /// <summary> + /// Maps from consumer tag to JMSMessageConsumer instance + /// </summary> + private Hashtable _consumers = Hashtable.Synchronized(new Hashtable()); + + /// <summary> + /// The counter of the _next producer id. This id is generated by the session and used only to allow the + /// producer to identify itself to the session when deregistering itself. + /// + /// Access to this id does not require to be synchronized since according to the JMS specification only one + /// thread of control is allowed to create producers for any given session instance. + /// </summary> + private long _nextProducerId; + + /// <summary> + /// Responsible for decoding a message fragment and passing it to the appropriate message consumer. + /// </summary> + private class Dispatcher + { + private int _stopped = 0; + + private AmqChannel _containingChannel; + + public Dispatcher(AmqChannel containingChannel) + { + _containingChannel = containingChannel; + } + + /// <summary> + /// Runs the dispatcher. This is intended to be Run in a separate thread. + /// </summary> + public void RunDispatcher() + { + UnprocessedMessage message; + + while (_stopped == 0 && (message = (UnprocessedMessage)_containingChannel._queue.DequeueBlocking()) != null) + { + //_queue.size() + DispatchMessage(message); + } + + _logger.Info("Dispatcher thread terminating for channel " + _containingChannel._channelId); + } + +// private void DispatchMessage(UnprocessedMessage message) + private void DispatchMessage(UnprocessedMessage message) + { + if (message.DeliverBody != null) + { + BasicMessageConsumer consumer = (BasicMessageConsumer) _containingChannel._consumers[message.DeliverBody.ConsumerTag]; + + if (consumer == null) + { + _logger.Warn("Received a message from queue " + message.DeliverBody.ConsumerTag + " without a handler - ignoring..."); + } + else + { + consumer.NotifyMessage(message, _containingChannel.AcknowledgeMode, _containingChannel.ChannelId); + } + } + else + { + try + { + // Bounced message is processed here, away from the mina thread + AbstractQmsMessage bouncedMessage = _containingChannel._messageFactoryRegistry. + CreateMessage(0, false, message.ContentHeader, message.Bodies); + + int errorCode = message.BounceBody.ReplyCode; + string reason = message.BounceBody.ReplyText; + _logger.Debug("Message returned with error code " + errorCode + " (" + reason + ")"); + + _containingChannel._connection.ExceptionReceived(new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage)); + } + catch (Exception e) + { + _logger.Error("Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", e); + } + } + } + + public void StopDispatcher() + { + Interlocked.Exchange(ref _stopped, 1); + } + } + + internal AmqChannel(AMQConnection con, ushort channelId, bool transacted, AcknowledgeMode acknowledgeMode, int defaultPrefetch) : + this(con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.NewDefaultRegistry(), defaultPrefetch) + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="AmqChannel"/> class. + /// </summary> + /// <param name="con">The con.</param> + /// <param name="channelId">The channel id.</param> + /// <param name="transacted">if set to <c>true</c> [transacted].</param> + /// <param name="acknowledgeMode">The acknowledge mode.</param> + /// <param name="messageFactoryRegistry">The message factory registry.</param> + internal AmqChannel(AMQConnection con, ushort channelId, bool transacted, AcknowledgeMode acknowledgeMode, + MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetch) + { + _sessionNumber = Interlocked.Increment(ref _nextSessionNumber); + _connection = con; + _transacted = transacted; + if (transacted) + { + _acknowledgeMode = AcknowledgeMode.SessionTransacted; + } + else + { + _acknowledgeMode = acknowledgeMode; + } + _channelId = channelId; + _messageFactoryRegistry = messageFactoryRegistry; + } + + public IBytesMessage CreateBytesMessage() + { + lock (_connection.FailoverMutex) + { + CheckNotClosed(); + try + { + return (IBytesMessage)_messageFactoryRegistry.CreateMessage("application/octet-stream"); + } + catch (AMQException e) + { + throw new QpidException("Unable to create message: " + e); + } + } + } + + public IMessage CreateMessage() + { + lock (_connection.FailoverMutex) + { + CheckNotClosed(); + try + { + // TODO: this is supposed to create a message consisting only of message headers + return (IBytesMessage)_messageFactoryRegistry.CreateMessage("application/octet-stream"); + } + catch (AMQException e) + { + throw new QpidException("Unable to create message: " + e); + } + } + } + + public ITextMessage CreateTextMessage() + { + lock (_connection.FailoverMutex) + { + CheckNotClosed(); + + try + { + return (ITextMessage)_messageFactoryRegistry.CreateMessage("text/plain"); + } + catch (AMQException e) + { + throw new QpidException("Unable to create message: " + e); + } + } + } + + public ITextMessage CreateTextMessage(string text) + { + lock (_connection.FailoverMutex) + { + CheckNotClosed(); + try + { + ITextMessage msg = (ITextMessage)_messageFactoryRegistry.CreateMessage("text/plain"); + msg.Text = text; + return msg; + } + catch (AMQException e) + { + throw new QpidException("Unable to create message: " + e); + } + } + } + + public bool Transacted + { + get + { + CheckNotClosed(); + return _transacted; + } + } + + public AcknowledgeMode AcknowledgeMode + { + get + { + CheckNotClosed(); + return _acknowledgeMode; + } + } + + public void Commit() + { + CheckNotClosed(); + CheckTransacted(); // throws IllegalOperationException if not a transacted session + + /*Channel.Commit frame = new Channel.Commit(); + frame.channelId = _channelId; + frame.confirmTag = 1;*/ + + // try + // { + // _connection.getProtocolHandler().writeCommandFrameAndWaitForReply(frame, new ChannelReplyListener(_channelId)); + // } + // catch (AMQException e) + // { + // throw new JMSException("Error creating session: " + e); + // } + throw new NotImplementedException(); + //_logger.Info("Transaction commited on channel " + _channelId); + } + + public void Rollback() + { + CheckNotClosed(); + CheckTransacted(); // throws IllegalOperationException if not a transacted session + + /*Channel.Rollback frame = new Channel.Rollback(); + frame.channelId = _channelId; + frame.confirmTag = 1;*/ + + // try + // { + // _connection.getProtocolHandler().writeCommandFrameAndWaitForReply(frame, new ChannelReplyListener(_channelId)); + // } + // catch (AMQException e) + // { + // throw new JMSException("Error rolling back session: " + e); + // } + throw new NotImplementedException(); + //_logger.Info("Transaction rolled back on channel " + _channelId); + } + + public override void Close() + { + lock (_connection.FailoverMutex) + { + // We must close down all producers and consumers in an orderly fashion. This is the only method + // that can be called from a different thread of control from the one controlling the session + + lock (_closingLock) + { + SetClosed(); + + // we pass null since this is not an error case + CloseProducersAndConsumers(null); + + try + { + _connection.CloseSession(this); + } + catch (AMQException e) + { + throw new QpidException("Error closing session: " + e); + } + finally + { + _connection.DeregisterSession(_channelId); + } + } + } + } + + private void SetClosed() + { + Interlocked.Exchange(ref _closed, CLOSED); + } + + /// <summary> + /// Close all producers or consumers. This is called either in the error case or when closing the session normally. + /// <param name="amqe">the exception, may be null to indicate no error has occurred</param> + /// + private void CloseProducersAndConsumers(AMQException amqe) + { + try + { + CloseProducers(); + } + catch (QpidException e) + { + _logger.Error("Error closing session: " + e, e); + } + try + { + CloseConsumers(amqe); + } + catch (QpidException e) + { + _logger.Error("Error closing session: " + e, e); + } + } + + /** + * Called when the server initiates the closure of the session + * unilaterally. + * @param e the exception that caused this session to be closed. Null causes the + */ + public void Closed(Exception e) + { + lock (_connection.FailoverMutex) + { + // An AMQException has an error code and message already and will be passed in when closure occurs as a + // result of a channel close request + SetClosed(); + AMQException amqe; + if (e is AMQException) + { + amqe = (AMQException) e; + } + else + { + amqe = new AMQException("Closing session forcibly", e); + } + _connection.DeregisterSession(_channelId); + CloseProducersAndConsumers(amqe); + } + } + + /// <summary> + /// Called to close message producers cleanly. This may or may <b>not</b> be as a result of an error. There is + /// currently no way of propagating errors to message producers (this is a JMS limitation). + /// </summary> + private void CloseProducers() + { + _logger.Info("Closing producers on session " + this); + // we need to clone the list of producers since the close() method updates the _producers collection + // which would result in a concurrent modification exception + ArrayList clonedProducers = new ArrayList(_producers.Values); + + foreach (BasicMessageProducer prod in clonedProducers) + { + _logger.Info("Closing producer " + prod); + prod.Close(); + } + // at this point the _producers map is empty + } + + /// <summary> + /// Called to close message consumers cleanly. This may or may <b>not</b> be as a result of an error. + /// <param name="error">not null if this is a result of an error occurring at the connection level</param> + /// + private void CloseConsumers(Exception error) + { + if (_dispatcher != null) + { + _dispatcher.StopDispatcher(); + } + // we need to clone the list of consumers since the close() method updates the _consumers collection + // which would result in a concurrent modification exception + ArrayList clonedConsumers = new ArrayList(_consumers.Values); + + foreach (BasicMessageConsumer con in clonedConsumers) + { + if (error != null) + { + con.NotifyError(error); + } + else + { + con.Close(); + } + } + // at this point the _consumers map will be empty + } + + public void Recover() + { + CheckNotClosed(); + CheckNotTransacted(); // throws IllegalOperationException if not a transacted session + + // TODO: This cannot be implemented using 0.8 semantics + throw new NotImplementedException(); + } + + public void Run() + { + throw new NotImplementedException(); + } + +// public IMessagePublisher CreatePublisher(string exchangeName, string exchangeClass) +// { +// return CreatePublisher(exchangeClass, exchangeName, null); +// } + +// public IMessagePublisher CreatePublisher(string exchangeName, string exchangeClass, string routingKey) +// { +// return CreatePublisherBuilder().withExchangeName(exchangeName) +// .withRoutingKey(routingKey).Create(); +// } + + public IMessagePublisher CreatePublisher(string exchangeName, string routingKey, DeliveryMode deliveryMode, + long timeToLive, bool immediate, bool mandatory, int priority) + { + _logger.Debug(string.Format("Using new CreatePublisher exchangeName={0}, exchangeClass={1} routingKey={2}", + exchangeName, "none", routingKey)); + return CreateProducerImpl(exchangeName, routingKey, deliveryMode, + timeToLive, immediate, mandatory, priority); + } + + // TODO: Create a producer that doesn't require an IDestination. +// private IMessagePublisher CreateProducerImpl(IDestination destination) +// { +// lock (_closingLock) +// { +// CheckNotClosed(); +// +// AMQDestination amqd = (AMQDestination)destination; +// +// try +// { +// return new BasicMessageProducer(amqd, _transacted, _channelId, +// this, GetNextProducerId()); +// } +// catch (AMQException e) +// { +// _logger.Error("Error creating message producer: " + e, e); +// throw new QpidException("Error creating message producer", e); +// } +// } +// } + + public IMessagePublisher CreateProducerImpl(string exchangeName, string routingKey, + DeliveryMode deliveryMode, + long timeToLive, bool immediate, bool mandatory, int priority) + { + lock (_closingLock) + { + CheckNotClosed(); + + try + { + return new BasicMessageProducer(exchangeName, routingKey, _transacted, _channelId, + this, GetNextProducerId(), + deliveryMode, timeToLive, immediate, mandatory, priority); + } + catch (AMQException e) + { + _logger.Error("Error creating message producer: " + e, e); + throw new QpidException("Error creating message producer", e); + } + } + } + + public IMessageConsumer CreateConsumer(string queueName, + int prefetch, + bool noLocal, + bool exclusive, + bool durable, + string subscriptionName) + { + _logger.Debug(String.Format("CreateConsumer queueName={0} prefetch={1} noLocal={2} exclusive={3} durable={4} subscriptionName={5}", + queueName, prefetch, noLocal, exclusive, durable, subscriptionName)); + return CreateConsumerImpl(queueName, prefetch, noLocal, exclusive, durable, subscriptionName); + } + + private IMessageConsumer CreateConsumerImpl(string queueName, + int prefetch, + bool noLocal, + bool exclusive, + bool durable, + string subscriptionName) + { + + if (durable || subscriptionName != null) + { + throw new NotImplementedException(); // TODO: durable subscriptions. + } + + lock (_closingLock) + { + CheckNotClosed(); + + BasicMessageConsumer consumer = new BasicMessageConsumer(_channelId, queueName, noLocal, + _messageFactoryRegistry, this); + try + { + RegisterConsumer(consumer); + } + catch (AMQException e) + { + throw new QpidException("Error registering consumer: " + e, e); + } + + return consumer; + } + } + +// public IDestination CreateQueue(string queueName) +// { +// return new AMQQueue(queueName); +// } +// +// public IDestination CreateTopic(String topicName) +// { +// return new AMQTopic(topicName); +// } + + public IFieldTable CreateFieldTable() + { + return new FieldTable(); + } + +// public IDestination CreateTemporaryQueue() +// { +// return new AMQQueue("TempQueue" + DateTime.Now.Ticks.ToString(), true); +// +//// return new AMQTemporaryQueue(); // XXX: port AMQTemporaryQueue and AMQQueue changes. +// } + +// public IDestination CreateTemporaryTopic() +// { +// throw new NotImplementedException(); // FIXME +// } + + public void Unsubscribe(String name) + { + throw new NotImplementedException(); // FIXME + } + + private void CheckTransacted() + { + if (!Transacted) + { + throw new InvalidOperationException("Channel is not transacted"); + } + } + + private void CheckNotTransacted() + { + if (Transacted) + { + throw new InvalidOperationException("Channel is transacted"); + } + } + + public void MessageReceived(UnprocessedMessage message) + { + if (_logger.IsDebugEnabled) + { + _logger.Debug("Message received in session with channel id " + _channelId); + } + _queue.EnqueueBlocking(message); + } + + public int DefaultPrefetch + { + get + { + return _defaultPrefetch; + } + set + { + _defaultPrefetch = value; + } + } + + public ushort ChannelId + { + get + { + return _channelId; + } + } + + public AMQConnection Connection + { + get + { + return _connection; + } + } + + /// <summary> + /// Send an acknowledgement for all messages up to a specified number on this session. + /// <param name="messageNbr">the message number up to an including which all messages will be acknowledged.</param> + /// </summary> + public void SendAcknowledgement(ulong messageNbr) + { + /*if (_logger.IsDebugEnabled) + { + _logger.Debug("Channel Ack being sent for channel id " + _channelId + " and message number " + messageNbr); + }*/ + /*Channel.Ack frame = new Channel.Ack(); + frame.channelId = _channelId; + frame.messageNbr = messageNbr; + _connection.getProtocolHandler().writeFrame(frame);*/ + } + + internal void Start() + { + _dispatcher = new Dispatcher(this); + Thread dispatcherThread = new Thread(new ThreadStart(_dispatcher.RunDispatcher)); + dispatcherThread.IsBackground = true; + dispatcherThread.Start(); + } + + internal void RegisterConsumer(string consumerTag, IMessageConsumer consumer) + { + _consumers[consumerTag] = consumer; + } + + /// <summary> + /// Called by the MessageConsumer when closing, to deregister the consumer from the + /// map from consumerTag to consumer instance. + /// </summary> + /// <param name="consumerTag">the consumer tag, that was broker-generated</param> + internal void DeregisterConsumer(string consumerTag) + { + _consumers.Remove(consumerTag); + } + + internal void RegisterProducer(long producerId, IMessagePublisher publisher) + { + _producers[producerId] = publisher; + } + + internal void DeregisterProducer(long producerId) + { + _producers.Remove(producerId); + } + + private long GetNextProducerId() + { + return ++_nextProducerId; + } + + public void Dispose() + { + Close(); + } + + /** + * Called to mark the session as being closed. Useful when the session needs to be made invalid, e.g. after + * failover when the client has veoted resubscription. + * + * The caller of this method must already hold the failover mutex. + */ + internal void MarkClosed() + { + SetClosed(); + _connection.DeregisterSession(_channelId); + MarkClosedProducersAndConsumers(); + } + + private void MarkClosedProducersAndConsumers() + { + try + { + // no need for a markClosed* method in this case since there is no protocol traffic closing a producer + CloseProducers(); + } + catch (QpidException e) + { + _logger.Error("Error closing session: " + e, e); + } + try + { + MarkClosedConsumers(); + } + catch (QpidException e) + { + _logger.Error("Error closing session: " + e, e); + } + } + + private void MarkClosedConsumers() + { + if (_dispatcher != null) + { + _dispatcher.StopDispatcher(); + } + // we need to clone the list of consumers since the close() method updates the _consumers collection + // which would result in a concurrent modification exception + ArrayList clonedConsumers = new ArrayList(_consumers.Values); + + foreach (BasicMessageConsumer consumer in clonedConsumers) + { + consumer.MarkClosed(); + } + // at this point the _consumers map will be empty + } + + /** + * Resubscribes all producers and consumers. This is called when performing failover. + * @throws AMQException + */ + internal void Resubscribe() + { + ResubscribeProducers(); + ResubscribeConsumers(); + } + + private void ResubscribeProducers() + { + // FIXME: This needs to Replay DeclareExchange method calls. + +// ArrayList producers = new ArrayList(_producers.Values); +// _logger.Debug(String.Format("Resubscribing producers = {0} producers.size={1}", producers, producers.Count)); +// foreach (BasicMessageProducer producer in producers) +// { +// producer.Resubscribe(); +// } + } + + private void ResubscribeConsumers() + { + ArrayList consumers = new ArrayList(_consumers.Values); + _consumers.Clear(); + + foreach (BasicMessageConsumer consumer in consumers) + { + RegisterConsumer(consumer); + } + } + + /// <summary> + /// Callers must hold the failover mutex before calling this method. + /// </summary> + /// <param name="consumer"></param> + void RegisterConsumer(BasicMessageConsumer consumer) + { + String consumerTag = ConsumeFromQueue(consumer.QueueName, consumer.Prefetch, consumer.NoLocal, + consumer.Exclusive, consumer.AcknowledgeMode); + + consumer.ConsumerTag = consumerTag; + _consumers.Add(consumerTag, consumer); + } + + public void Bind(string queueName, string exchangeName, string routingKey, IFieldTable args) + { + DoBind(queueName, exchangeName, routingKey, (FieldTable)args); + } + + public void Bind(string queueName, string exchangeName, string routingKey) + { + DoBind(queueName, exchangeName, routingKey, new FieldTable()); + } + + internal void DoBind(string queueName, string exchangeName, string routingKey, FieldTable args) + { + _logger.Debug(string.Format("QueueBind queueName={0} exchangeName={1} routingKey={2}, arg={3}", + queueName, exchangeName, routingKey, args)); + + AMQFrame queueBind = QueueBindBody.CreateAMQFrame(_channelId, 0, + queueName, exchangeName, + routingKey, true, args); + _connection.ProtocolWriter.Write(queueBind); + } + + +// /** +// * Declare the queue. +// * @param amqd +// * @param protocolHandler +// * @return the queue name. This is useful where the broker is generating a queue name on behalf of the client. +// * @throws AMQException +// */ +// private String DeclareQueue(AMQDestination amqd) +// { +// // For queues (but not topics) we generate the name in the client rather than the +// // server. This allows the name to be reused on failover if required. In general, +// // the destination indicates whether it wants a name generated or not. +// if (amqd.IsNameRequired) +// { +// amqd.QueueName = GenerateUniqueName(); +// } +// +// return DoDeclareQueue(amqd); +// } + + private String ConsumeFromQueue(String queueName, int prefetch, + bool noLocal, bool exclusive, AcknowledgeMode acknowledgeMode) + { + // Need to generate a consumer tag on the client so we can exploit the nowait flag. + String tag = string.Format("{0}-{1}", _sessionNumber, _nextConsumerNumber++); + + AMQFrame basicConsume = BasicConsumeBody.CreateAMQFrame(_channelId, 0, + queueName, tag, noLocal, + acknowledgeMode == AcknowledgeMode.NoAcknowledge, + exclusive, true); + + _connection.ProtocolWriter.Write(basicConsume); + return tag; + } + + public void DeleteExchange(string exchangeName) + { + throw new NotImplementedException(); // FIXME + } + + public void DeleteQueue() + { + throw new NotImplementedException(); // FIXME + } + + public MessageConsumerBuilder CreateConsumerBuilder(string queueName) + { + return new MessageConsumerBuilder(this, queueName); + } + + public MessagePublisherBuilder CreatePublisherBuilder() + { + return new MessagePublisherBuilder(this); + } + +// public void Publish(string exchangeName, string routingKey, bool mandatory, bool immediate, +// IMessage message, DeliveryMode deliveryMode, int priority, uint timeToLive, +// bool disableTimestamps) +// { +// lock (Connection.FailoverMutex) +// { +// DoBasicPublish(exchangeName, routingKey, mandatory, immediate, (AbstractQmsMessage)message, deliveryMode, timeToLive, priority, disableTimestamps); +// } +// } + + internal void BasicPublish(string exchangeName, string routingKey, bool mandatory, bool immediate, + AbstractQmsMessage message, DeliveryMode deliveryMode, int priority, uint timeToLive, + bool disableTimestamps) + { + lock (Connection.FailoverMutex) + { + DoBasicPublish(exchangeName, routingKey, mandatory, immediate, message, deliveryMode, timeToLive, priority, disableTimestamps); + } + } + + private void DoBasicPublish(string exchangeName, string routingKey, bool mandatory, bool immediate, AbstractQmsMessage message, DeliveryMode deliveryMode, uint timeToLive, int priority, bool disableTimestamps) + { + AMQFrame publishFrame = BasicPublishBody.CreateAMQFrame(_channelId, 0, exchangeName, + routingKey, mandatory, immediate); + + long currentTime = 0; + if (!disableTimestamps) + { + currentTime = DateTime.UtcNow.Ticks; + message.Timestamp = currentTime; + } + byte[] payload = message.Data; + BasicContentHeaderProperties contentHeaderProperties = message.ContentHeaderProperties; + + if (timeToLive > 0) + { + if (!disableTimestamps) + { + contentHeaderProperties.Expiration = (uint)currentTime + timeToLive; + } + } + else + { + contentHeaderProperties.Expiration = 0; + } + contentHeaderProperties.SetDeliveryMode(deliveryMode); + contentHeaderProperties.Priority = (byte)priority; + + ContentBody[] contentBodies = CreateContentBodies(payload); + AMQFrame[] frames = new AMQFrame[2 + contentBodies.Length]; + for (int i = 0; i < contentBodies.Length; i++) + { + frames[2 + i] = ContentBody.CreateAMQFrame(_channelId, contentBodies[i]); + } + if (contentBodies.Length > 0 && _logger.IsDebugEnabled) + { + _logger.Debug(string.Format("Sending content body frames to {{exchangeName={0} routingKey={1}}}", exchangeName, routingKey)); + } + + // weight argument of zero indicates no child content headers, just bodies + AMQFrame contentHeaderFrame = ContentHeaderBody.CreateAMQFrame(_channelId, BASIC_CONTENT_TYPE, 0, contentHeaderProperties, + (uint)payload.Length); + if (_logger.IsDebugEnabled) + { + _logger.Debug(string.Format("Sending content header frame to {{exchangeName={0} routingKey={1}}}", exchangeName, routingKey)); + } + + frames[0] = publishFrame; + frames[1] = contentHeaderFrame; + CompositeAMQDataBlock compositeFrame = new CompositeAMQDataBlock(frames); + Connection.ConvenientProtocolWriter.WriteFrame(compositeFrame); + } + + /// <summary> + /// Create content bodies. This will split a large message into numerous bodies depending on the negotiated + /// maximum frame size. + /// </summary> + /// <param name="payload"></param> + /// <returns>return the array of content bodies</returns> + private ContentBody[] CreateContentBodies(byte[] payload) + { + if (payload == null) + { + return null; + } + else if (payload.Length == 0) + { + return new ContentBody[0]; + } + // we substract one from the total frame maximum size to account for the end of frame marker in a body frame + // (0xCE byte). + long framePayloadMax = Connection.MaximumFrameSize - 1; + int lastFrame = (payload.Length % framePayloadMax) > 0 ? 1 : 0; + int frameCount = (int)(payload.Length / framePayloadMax) + lastFrame; + ContentBody[] bodies = new ContentBody[frameCount]; + + if (frameCount == 1) + { + bodies[0] = new ContentBody(); + bodies[0].Payload = payload; + } + else + { + long remaining = payload.Length; + for (int i = 0; i < bodies.Length; i++) + { + bodies[i] = new ContentBody(); + byte[] framePayload = new byte[(remaining >= framePayloadMax) ? (int)framePayloadMax : (int)remaining]; + Array.Copy(payload, (int)framePayloadMax * i, framePayload, 0, framePayload.Length); + bodies[i].Payload = framePayload; + remaining -= framePayload.Length; + } + } + return bodies; + } + + public string GenerateUniqueName() + { + string result = _connection.ProtocolSession.GenerateQueueName(); + return Regex.Replace(result, "[^a-z0-9_]", "_"); + } + + public void DeclareQueue(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete) + { + DoQueueDeclare(queueName, isDurable, isExclusive, isAutoDelete); + } + + private string DoDeclareQueue(AMQDestination amqd) + { + string queueName = amqd.QueueName; + bool isDurable = amqd.IsDurable; + bool isExclusive = amqd.IsExclusive; + + DoQueueDeclare(queueName, isDurable, isExclusive, amqd.AutoDelete); + + _logger.Debug("returning amqp.QueueName = " + amqd.QueueName); + return amqd.QueueName; + } + + private void DoQueueDeclare(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete) + { + _logger.Debug(string.Format("DeclareQueue name={0} durable={1} exclusive={2}, auto-delete={3}", + queueName, isDurable, isExclusive, isAutoDelete)); + + AMQFrame queueDeclare = QueueDeclareBody.CreateAMQFrame(_channelId, 0, queueName, + false, isDurable, isExclusive, + isAutoDelete, true, null); + + _connection.ProtocolWriter.Write(queueDeclare); + } + + public void DeclareExchange(String exchangeName, String exchangeClass) + { + _logger.Debug(string.Format("DeclareExchange vame={0} exchangeClass={1}", exchangeName, exchangeClass)); + + DeclareExchange(_channelId, 0, exchangeName, exchangeClass, false, false, false, false, true, null); + } + + // AMQP-level method. + private void DeclareExchange(ushort channelId, ushort ticket, string exchangeName, + string exchangeClass, bool passive, bool durable, + bool autoDelete, bool xinternal, bool noWait, FieldTable args) + { + _logger.Debug(String.Format("DeclareExchange channelId={0} exchangeName={1} exchangeClass={2}", + _channelId, exchangeName, exchangeClass)); + + AMQFrame exchangeDeclareFrame = ExchangeDeclareBody.CreateAMQFrame( + channelId, ticket, exchangeName, exchangeClass, passive, durable, autoDelete, xinternal, noWait, args); + +// Console.WriteLine(string.Format("XXX AMQP:DeclareExchange frame=[{0}]", exchangeDeclareFrame)); + + // FIXME: Probably need to record the exchangeDeclareBody for later replay. + ExchangeDeclareBody exchangeDeclareBody = (ExchangeDeclareBody)exchangeDeclareFrame.BodyFrame; +// Console.WriteLine(string.Format("XXX AMQP:DeclareExchangeBody=[{0}]", exchangeDeclareBody)); + if (exchangeDeclareBody.Nowait) + { + _connection.ProtocolWriter.Write(exchangeDeclareFrame); + } + else + { + _connection.ConvenientProtocolWriter.SyncWrite(exchangeDeclareFrame, typeof (ExchangeDeclareOkBody)); + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs b/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs new file mode 100644 index 0000000000..6d2f1c67b6 --- /dev/null +++ b/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs @@ -0,0 +1,404 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using Qpid.Client.Message; +using Qpid.Collections; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client +{ + public class BasicMessageConsumer : Closeable, IMessageConsumer + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(BasicMessageConsumer)); + + private bool _noLocal; + + /// We need to store the "raw" field table so that we can resubscribe in the event of failover being required. +// private FieldTable _rawSelectorFieldTable; +// +// public FieldTable RawSelectorFieldTable +// { +// get { return _rawSelectorFieldTable; } +// } + + /** + * We store the exclusive field in order to be able to reuse it when resubscribing in the event of failover + */ + private bool _exclusive; + + public bool Exclusive + { + get { return _exclusive; } + } + + public bool NoLocal + { + get { return _noLocal; } + set { _noLocal = value; } + } + + AcknowledgeMode _acknowledgeMode = AcknowledgeMode.NoAcknowledge; + + public AcknowledgeMode AcknowledgeMode + { + get { return _acknowledgeMode; } + } + + private MessageReceivedDelegate _messageListener; + + /// <summary> + /// The consumer tag allows us to close the consumer by sending a jmsCancel method to the + /// broker + /// </summary> + private string _consumerTag; + + /// <summary> + /// We need to know the channel id when constructing frames + /// </summary> + private ushort _channelId; + + private readonly string _queueName; + + /// <summary> + /// Protects the setting of a messageListener + /// </summary> + private readonly object _syncLock = new object(); + + /** + * We store the prefetch field in order to be able to reuse it when resubscribing in the event of failover + */ + private int _prefetch; + + /// <summary> + /// When true indicates that either a message listener is set or that + /// a blocking receive call is in progress + /// </summary> + private bool _receiving; + + /// <summary> + /// Used in the blocking receive methods to receive a message from + /// the Channel thread. Argument true indicates we want strict FIFO semantics + /// </summary> + private readonly SynchronousQueue _synchronousQueue = new SynchronousQueue(true); + + private MessageFactoryRegistry _messageFactory; + + private AmqChannel _channel; + + public BasicMessageConsumer(ushort channelId, string queueName, bool noLocal, + MessageFactoryRegistry messageFactory, AmqChannel channel) + { + _channelId = channelId; + _queueName = queueName; + _noLocal = noLocal; + _messageFactory = messageFactory; + _channel = channel; + } + + #region IMessageConsumer Members + + public MessageReceivedDelegate OnMessage + { + get + { + return _messageListener; + } + set + { + CheckNotClosed(); + + lock (_syncLock) + { + // If someone is already receiving + if (_messageListener != null && _receiving) + { + throw new InvalidOperationException("Another thread is already receiving..."); + } + + _messageListener = value; + + _receiving = (_messageListener != null); + + if (_receiving) + { + _logger.Debug("Message listener set for queue with name " + _queueName); + } + } + } + } + + public IMessage Receive(long delay) + { + CheckNotClosed(); + + lock (_syncLock) + { + // If someone is already receiving + if (_receiving) + { + throw new InvalidOperationException("Another thread is already receiving (possibly asynchronously)..."); + } + + _receiving = true; + } + + try + { + object o; + if (delay > 0) + { + //o = _synchronousQueue.Poll(l, TimeUnit.MILLISECONDS); + throw new NotImplementedException("Need to implement synchronousQueue.Poll(timeout"); + } + else + { + o = _synchronousQueue.DequeueBlocking(); + } + return ReturnMessageOrThrow(o); + } + finally + { + lock (_syncLock) + { + _receiving = false; + } + } + } + + public IMessage Receive() + { + return Receive(0); + } + + public IMessage ReceiveNoWait() + { + CheckNotClosed(); + + lock (_syncLock) + { + // If someone is already receiving + if (_receiving) + { + throw new InvalidOperationException("Another thread is already receiving (possibly asynchronously)..."); + } + + _receiving = true; + } + + try + { + object o = _synchronousQueue.Dequeue(); + return ReturnMessageOrThrow(o); + } + finally + { + lock (_syncLock) + { + _receiving = false; + } + } + } + + #endregion + + /// <summary> + /// We can get back either a Message or an exception from the queue. This method examines the argument and deals + /// with it by throwing it (if an exception) or returning it (in any other case). + /// </summary> + /// <param name="o">the object off the queue</param> + /// <returns> a message only if o is a Message</returns> + /// <exception>JMSException if the argument is a throwable. If it is a QpidMessagingException it is rethrown as is, but if not + /// a QpidMessagingException is created with the linked exception set appropriately</exception> + private IMessage ReturnMessageOrThrow(object o) + { + // errors are passed via the queue too since there is no way of interrupting the poll() via the API. + if (o is Exception) + { + Exception e = (Exception) o; + throw new QpidException("Message consumer forcibly closed due to error: " + e, e); + } + else + { + return (IMessage) o; + } + } + + #region IDisposable Members + + public void Dispose() + { + Close(); + } + + #endregion + + public override void Close() + { + lock (_channel.Connection.FailoverMutex) + { + lock (_closingLock) + { + Interlocked.Exchange(ref _closed, CLOSED); + + AMQFrame cancelFrame = BasicCancelBody.CreateAMQFrame(_channelId, _consumerTag, false); + + try + { + _channel.Connection.ConvenientProtocolWriter.SyncWrite( + cancelFrame, typeof(BasicCancelOkBody)); + } + catch (AMQException e) + { + _logger.Error("Error closing consumer: " + e, e); + throw new QpidException("Error closing consumer: " + e); + } + finally + { + DeregisterConsumer(); + } + } + } + } + + /// <summary> + /// Called from the AmqChannel when a message has arrived for this consumer. This methods handles both the case + /// of a message listener or a synchronous receive() caller. + /// </summary> + /// <param name="messageFrame">the raw unprocessed mesage</param> + /// <param name="acknowledgeMode">the acknowledge mode requested for this message</param> + /// <param name="channelId">channel on which this message was sent</param> + internal void NotifyMessage(UnprocessedMessage messageFrame, AcknowledgeMode acknowledgeMode, ushort channelId) + { + if (_logger.IsDebugEnabled) + { + _logger.Debug("notifyMessage called with message number " + messageFrame.DeliverBody.DeliveryTag); + } + try + { + AbstractQmsMessage jmsMessage = _messageFactory.CreateMessage(messageFrame.DeliverBody.DeliveryTag, + messageFrame.DeliverBody.Redelivered, + messageFrame.ContentHeader, + messageFrame.Bodies); + + /*if (acknowledgeMode == AcknowledgeMode.PreAcknowledge) + { + _channel.sendAcknowledgement(messageFrame.deliverBody.deliveryTag); + }*/ + if (acknowledgeMode == AcknowledgeMode.ClientAcknowledge) + { + // we set the session so that when the user calls acknowledge() it can call the method on session + // to send out the appropriate frame + jmsMessage.Channel = _channel; + } + + lock (_syncLock) + { + if (_messageListener != null) + { + _messageListener.Invoke(jmsMessage); + } + else + { + _synchronousQueue.Enqueue(jmsMessage); + } + } + if (acknowledgeMode == AcknowledgeMode.AutoAcknowledge) + { + _channel.SendAcknowledgement(messageFrame.DeliverBody.DeliveryTag); + } + } + catch (Exception e) + { + _logger.Error("Caught exception (dump follows) - ignoring...", e); + } + } + + internal void NotifyError(Exception cause) + { + lock (_syncLock) + { + SetClosed(); + + // we have no way of propagating the exception to a message listener - a JMS limitation - so we + // deal with the case where we have a synchronous receive() waiting for a message to arrive + if (_messageListener == null) + { + // offer only succeeds if there is a thread waiting for an item from the queue + if (_synchronousQueue.EnqueueNoThrow(cause)) + { + _logger.Debug("Passed exception to synchronous queue for propagation to receive()"); + } + } + DeregisterConsumer(); + } + } + + private void SetClosed() + { + Interlocked.Exchange(ref _closed, CLOSED); + } + + /// <summary> + /// Perform cleanup to deregister this consumer. This occurs when closing the consumer in both the clean + /// case and in the case of an error occurring. + /// </summary> + internal void DeregisterConsumer() + { + _channel.DeregisterConsumer(_consumerTag); + } + + public string ConsumerTag + { + get + { + return _consumerTag; + } + set + { + _consumerTag = value; + } + } + + /** + * Called when you need to invalidate a consumer. Used for example when failover has occurred and the + * client has vetoed automatic resubscription. + * The caller must hold the failover mutex. + */ + internal void MarkClosed() + { + SetClosed(); + DeregisterConsumer(); + } + + public int Prefetch + { + get { return _prefetch; } + } + + public string QueueName + { + get { return _queueName; } + } + } +} diff --git a/dotnet/Qpid.Client/Client/BasicMessageProducer.cs b/dotnet/Qpid.Client/Client/BasicMessageProducer.cs new file mode 100644 index 0000000000..a93d2db675 --- /dev/null +++ b/dotnet/Qpid.Client/Client/BasicMessageProducer.cs @@ -0,0 +1,275 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using Qpid.Client.Message; +using Qpid.Messaging; + +namespace Qpid.Client +{ + public class BasicMessageProducer : Closeable, IMessagePublisher + { + protected readonly ILog _logger = LogManager.GetLogger(typeof(BasicMessageProducer)); + + /// <summary> + /// If true, messages will not get a timestamp. + /// </summary> + private bool _disableTimestamps; + + /// <summary> + /// Priority of messages created by this producer. + /// </summary> + private int _messagePriority; + + /// <summary> + /// Time to live of messages. Specified in milliseconds but AMQ has 1 second resolution. + /// + private long _timeToLive; + + /// <summary> + /// Delivery mode used for this producer. + /// </summary> + private DeliveryMode _deliveryMode; + + private bool _immediate; + private bool _mandatory; + + string _exchangeName; + string _routingKey; + + /// <summary> + /// Default encoding used for messages produced by this producer. + /// </summary> + private string _encoding; + + /// <summary> + /// Default encoding used for message produced by this producer. + /// </summary> + private string _mimeType; + + /// <summary> + /// True if this producer was created from a transacted session + /// </summary> + private bool _transacted; + + private ushort _channelId; + + /// <summary> + /// This is an id generated by the session and is used to tie individual producers to the session. This means we + /// can deregister a producer with the session when the producer is closed. We need to be able to tie producers + /// to the session so that when an error is propagated to the session it can close the producer (meaning that + /// a client that happens to hold onto a producer reference will get an error if he tries to use it subsequently). + /// </summary> + private long _producerId; + + /// <summary> + /// The session used to create this producer + /// </summary> + private AmqChannel _channel; + + /// <summary> + /// Default value for immediate flag is false, i.e. a consumer does not need to be attached to a queue + /// </summary> + protected const bool DEFAULT_IMMEDIATE = false; + + /// <summary> + /// Default value for mandatory flag is true, i.e. server will not silently drop messages where no queue is + /// connected to the exchange for the message + /// </summary> + protected const bool DEFAULT_MANDATORY = true; + + public BasicMessageProducer(string exchangeName, string routingKey, + bool transacted, + ushort channelId, + AmqChannel channel, + long producerId, + DeliveryMode deliveryMode, + long timeToLive, + bool immediate, + bool mandatory, + int priority) + { + _exchangeName = exchangeName; + _routingKey = routingKey; + _transacted = transacted; + _channelId = channelId; + _channel = channel; + _producerId = producerId; + _deliveryMode = deliveryMode; + _timeToLive = timeToLive; + _immediate = immediate; + _mandatory = mandatory; + _messagePriority = priority; + + _channel.RegisterProducer(producerId, this); + } + + + #region IMessagePublisher Members + + public DeliveryMode DeliveryMode + { + get + { + CheckNotClosed(); + return _deliveryMode; + } + set + { + CheckNotClosed(); + _deliveryMode = value; + } + } + + public string ExchangeName + { + get { return _exchangeName; } + } + + public string RoutingKey + { + get { return _routingKey; } + } + + public bool DisableMessageID + { + get + { + throw new Exception("The method or operation is not implemented."); + } + set + { + throw new Exception("The method or operation is not implemented."); + } + } + + public bool DisableMessageTimestamp + { + get + { + CheckNotClosed(); + return _disableTimestamps; + } + set + { + CheckNotClosed(); + _disableTimestamps = value; + } + } + + public int Priority + { + get + { + CheckNotClosed(); + return _messagePriority; + } + set + { + CheckNotClosed(); + if (value < 0 || value > 9) + { + throw new ArgumentOutOfRangeException("Priority of " + value + " is illegal. Value must be in range 0 to 9"); + } + _messagePriority = value; + } + } + + public override void Close() + { + _logger.Info("Closing producer " + this); + Interlocked.Exchange(ref _closed, CLOSED); + _channel.DeregisterProducer(_producerId); + } + + public void Send(IMessage msg, DeliveryMode deliveryMode, int priority, long timeToLive) + { + CheckNotClosed(); + SendImpl(_exchangeName, _routingKey, (AbstractQmsMessage)msg, deliveryMode, priority, (uint)timeToLive, DEFAULT_MANDATORY, + DEFAULT_IMMEDIATE); + } + + public void Send(IMessage msg) + { + CheckNotClosed(); + SendImpl(_exchangeName, _routingKey, (AbstractQmsMessage)msg, _deliveryMode, _messagePriority, (uint)_timeToLive, + DEFAULT_MANDATORY, DEFAULT_IMMEDIATE); + } + + // This is a short-term hack (knowing that this code will be re-vamped sometime soon) + // to facilitate publishing messages to potentially non-existent recipients. + public void Send(IMessage msg, bool mandatory) + { + CheckNotClosed(); + SendImpl(_exchangeName, _routingKey, (AbstractQmsMessage)msg, _deliveryMode, _messagePriority, (uint)_timeToLive, + mandatory, DEFAULT_IMMEDIATE); + } + + public long TimeToLive + { + get + { + CheckNotClosed(); + return _timeToLive; + } + set + { + CheckNotClosed(); + if (value < 0) + { + throw new ArgumentOutOfRangeException("Time to live must be non-negative - supplied value was " + value); + } + _timeToLive = value; + } + } + + #endregion + + private void SendImpl(string exchangeName, string routingKey, AbstractQmsMessage message, DeliveryMode deliveryMode, int priority, uint timeToLive, bool mandatory, bool immediate) + { + _channel.BasicPublish(exchangeName, routingKey, mandatory, immediate, message, deliveryMode, priority, timeToLive, _disableTimestamps); + } + + public string MimeType + { + set + { + CheckNotClosed(); + _mimeType = value; + } + } + + public string Encoding + { + set + { + CheckNotClosed(); + _encoding = value; + } + } + + public void Dispose() + { + Close(); + } + } +} diff --git a/dotnet/Qpid.Client/Client/Closeable.cs b/dotnet/Qpid.Client/Client/Closeable.cs new file mode 100644 index 0000000000..159f71ac08 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Closeable.cs @@ -0,0 +1,71 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client +{ + public abstract class Closeable + { + /// <summary> + /// Used to ensure orderly closing of the object. The only method that is allowed to be called + /// from another thread of control is close(). + /// </summary> + protected readonly object _closingLock = new object(); + + /// <summary> + /// All access to this field should be using the Inerlocked class, to make it atomic. + /// Hence it is an int since you cannot use a bool with the Interlocked class. + /// </summary> + protected int _closed = NOT_CLOSED; + + protected const int CLOSED = 1; + protected const int NOT_CLOSED = 2; + + /// <summary> + /// Checks the not closed. + /// </summary> + protected void CheckNotClosed() + { + if (_closed == CLOSED) + { + throw new InvalidOperationException("Object " + ToString() + " has been closed"); + } + } + + /// <summary> + /// Gets a value indicating whether this <see cref="Closeable"/> is closed. + /// </summary> + /// <value><c>true</c> if closed; otherwise, <c>false</c>.</value> + public bool Closed + { + get + { + return _closed == CLOSED; + } + } + + /// <summary> + /// Close the resource + /// </summary> + /// <exception cref="QpidMessagingException">If something goes wrong</exception> + public abstract void Close(); + } +} diff --git a/dotnet/Qpid.Client/Client/Collections/LinkedHashtable.cs b/dotnet/Qpid.Client/Client/Collections/LinkedHashtable.cs new file mode 100644 index 0000000000..43e9a819e4 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Collections/LinkedHashtable.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections; + +namespace Qpid.Collections +{ + public class LinkedHashtable : DictionaryBase + { + /// <summary> + /// Maps from key to LinkedDictionaryEntry + /// </summary> + private Hashtable _indexedValues = new Hashtable(); + + private LinkedDictionaryEntry _head; + + private LinkedDictionaryEntry _tail; + + public class LinkedDictionaryEntry + { + public LinkedDictionaryEntry previous; + public LinkedDictionaryEntry next; + public object key; + public object value; + + public LinkedDictionaryEntry(object key, object value) + { + this.key = key; + this.value = value; + } + } + + public object this[object index] + { + get + { + return ((LinkedDictionaryEntry)_indexedValues[index]).value; + } + + set + { + Dictionary[index] = value; + } + } + + protected override void OnInsertComplete(object key, object value) + { + LinkedDictionaryEntry de = new LinkedDictionaryEntry(key, value); + if (_head == null) + { + _head = de; + _tail = de; + } + else + { + _tail.next = de; + de.previous = _tail; + _tail = de; + } + _indexedValues[key] = de; + } + + protected override void OnSetComplete(object key, object oldValue, object newValue) + { + if (oldValue == null) + { + OnInsertComplete(key, newValue); + } + } + + protected override void OnRemoveComplete(object key, object value) + { + LinkedDictionaryEntry de = (LinkedDictionaryEntry)_indexedValues[key]; + LinkedDictionaryEntry prev = de.previous; + if (prev == null) + { + _head = de.next; + } + else + { + prev.next = de.next; + } + + LinkedDictionaryEntry next = de.next; + if (next == null) + { + _tail = de; + } + else + { + next.previous = de.previous; + } + } + + public ICollection Values + { + get + { + return InnerHashtable.Values; + } + } + + public bool Contains(object key) + { + return InnerHashtable.Contains(key); + } + + public void Remove(object key) + { + Dictionary.Remove(key); + } + + public LinkedDictionaryEntry Head + { + get + { + return _head; + } + } + + public LinkedDictionaryEntry Tail + { + get + { + return _tail; + } + } + + private class LHTEnumerator : IEnumerator + { + private LinkedHashtable _container; + + private LinkedDictionaryEntry _current; + + /// <summary> + /// Set once we have navigated off the end of the collection + /// </summary> + private bool _needsReset = false; + + public LHTEnumerator(LinkedHashtable container) + { + _container = container; + } + + public object Current + { + get + { + if (_current == null) + { + throw new Exception("Iterator before first element"); + } + else + { + return _current; + } + } + } + + public bool MoveNext() + { + if (_needsReset) + { + return false; + } + else if (_current == null) + { + _current = _container.Head; + } + else + { + _current = _current.next; + } + _needsReset = (_current == null); + return !_needsReset; + } + + public void Reset() + { + _current = null; + _needsReset = false; + } + } + + public new IEnumerator GetEnumerator() + { + return new LHTEnumerator(this); + } + + public void MoveToHead(object key) + { + LinkedDictionaryEntry de = (LinkedDictionaryEntry)_indexedValues[key]; + if (de == null) + { + throw new ArgumentException("Key " + key + " not found"); + } + // if the head is the element then there is nothing to do + if (_head == de) + { + return; + } + de.previous.next = de.next; + if (de.next != null) + { + de.next.previous = de.previous; + } + else + { + _tail = de.previous; + } + de.next = _head; + _head = de; + de.previous = null; + } + } +} diff --git a/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs b/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs new file mode 100644 index 0000000000..20f158f0ea --- /dev/null +++ b/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs @@ -0,0 +1,82 @@ +/* + * + * 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. + * + */ +namespace Qpid.Client +{ + public class ConnectionTuneParameters + { + private uint _frameMax; + + private ushort _channelMax; + + private uint _hearbeat; + + private uint _txnLimit; + + public uint FrameMax + { + get + { + return _frameMax; + } + set + { + _frameMax = value; + } + } + + public ushort ChannelMax + { + get + { + return _channelMax; + } + set + { + _channelMax = value; + } + } + + public uint Heartbeat + { + get + { + return _hearbeat; + } + set + { + _hearbeat = value; + } + } + + public uint TxnLimit + { + get + { + return _txnLimit; + } + set + { + _txnLimit = value; + } + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Failover/FailoverException.cs b/dotnet/Qpid.Client/Client/Failover/FailoverException.cs new file mode 100644 index 0000000000..b13b28a66b --- /dev/null +++ b/dotnet/Qpid.Client/Client/Failover/FailoverException.cs @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.Failover +{ + /// <summary> + /// This exception is thrown when failover is taking place and we need to let other + /// parts of the client know about this. + /// </summary> + class FailoverException : Exception + { + public FailoverException(String message) : base(message) + { + } + } +} diff --git a/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs b/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs new file mode 100644 index 0000000000..89a9809253 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs @@ -0,0 +1,173 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; + +namespace Qpid.Client.Failover +{ + public class FailoverHandler + { + private static readonly ILog _log = LogManager.GetLogger(typeof(FailoverHandler)); + + private AMQConnection _connection; + + /** + * Used where forcing the failover host + */ + private String _host; + + /** + * Used where forcing the failover port + */ + private int _port; + + public FailoverHandler(AMQConnection connection) + { + _connection = connection; + } + + public void Run() + { + if (Thread.CurrentThread.IsBackground) + { + throw new InvalidOperationException("FailoverHandler must Run on a non-background thread."); + } + + AMQProtocolListener pl = _connection.ProtocolListener; + pl.FailoverLatch = new ManualResetEvent(false); + + // We wake up listeners. If they can handle failover, they will extend the + // FailoverSupport class and will in turn block on the latch until failover + // has completed before retrying the operation + _connection.ProtocolListener.PropagateExceptionToWaiters(new FailoverException("Failing over about to start")); + + // Since failover impacts several structures we protect them all with a single mutex. These structures + // are also in child objects of the connection. This allows us to manipulate them without affecting + // client code which runs in a separate thread. + lock (_connection.FailoverMutex) + { + _log.Info("Starting failover process"); + + // We switch in a new state manager temporarily so that the interaction to get to the "connection open" + // state works, without us having to terminate any existing "state waiters". We could theoretically + // have a state waiter waiting until the connection is closed for some reason. Or in future we may have + // a slightly more complex state model therefore I felt it was worthwhile doing this. + AMQStateManager existingStateManager = _connection.ProtocolListener.StateManager; + _connection.ProtocolListener.StateManager = new AMQStateManager(); + if (!_connection.FirePreFailover(_host != null)) + { + _connection.ProtocolListener.StateManager = existingStateManager; + if (_host != null) + { + _connection.ExceptionReceived(new AMQDisconnectedException("Redirect was vetoed by client")); + } + else + { + _connection.ExceptionReceived(new AMQDisconnectedException("Failover was vetoed by client")); + } + pl.FailoverLatch.Set(); + pl.FailoverLatch = null; + return; + } + bool failoverSucceeded; + // when host is non null we have a specified failover host otherwise we all the client to cycle through + // all specified hosts + + // if _host has value then we are performing a redirect. + if (_host != null) + { + failoverSucceeded = _connection.AttemptReconnection(_host, _port, false); + } + else + { + failoverSucceeded = _connection.AttemptReconnection(); + } + + // XXX: at this point it appears that we are going to set StateManager to existingStateManager in + // XXX: both paths of control. + if (!failoverSucceeded) + { + _connection.ProtocolListener.StateManager = existingStateManager; + _connection.ExceptionReceived( + new AMQDisconnectedException("Server closed connection and no failover " + + "was successful")); + } + else + { + _connection.ProtocolListener.StateManager = existingStateManager; + try + { + if (_connection.FirePreResubscribe()) + { + _log.Info("Resubscribing on new connection"); + _connection.ResubscribeSessions(); + } + else + { + _log.Info("Client vetoed automatic resubscription"); + } + _connection.FireFailoverComplete(); + _connection.ProtocolListener.FailoverState = FailoverState.NOT_STARTED; + _log.Info("Connection failover completed successfully"); + } + catch (Exception e) + { + _log.Info("Failover process failed - exception being propagated by protocol handler"); + _connection.ProtocolListener.FailoverState = FailoverState.FAILED; + try + { + _connection.ProtocolListener.OnException(e); + } + catch (Exception ex) + { + _log.Error("Error notifying protocol session of error: " + ex, ex); + } + } + } + } + pl.FailoverLatch.Set(); + } + + public String getHost() + { + return _host; + } + + public void setHost(String host) + { + _host = host; + } + + public int getPort() + { + return _port; + } + + public void setPort(int port) + { + _port = port; + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Failover/FailoverState.cs b/dotnet/Qpid.Client/Client/Failover/FailoverState.cs new file mode 100644 index 0000000000..04322eeed4 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Failover/FailoverState.cs @@ -0,0 +1,31 @@ +/* + * + * 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. + * + */ +namespace Qpid.Client.Failover +{ + /// <summary> + /// Enumeration of failover states. Used to handle failover from within AMQProtocolHandler where MINA events need to be + /// dealt with and can happen during failover. + /// </summary> + enum FailoverState + { + NOT_STARTED, IN_PROGRESS, FAILED + } +} diff --git a/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs b/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs new file mode 100644 index 0000000000..591c0b1d4f --- /dev/null +++ b/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs @@ -0,0 +1,55 @@ +/* + * + * 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. + * + */ +using log4net; + +namespace Qpid.Client.Failover +{ + public abstract class FailoverSupport + { + private static readonly ILog _log = LogManager.GetLogger(typeof(FailoverSupport)); + + public object execute(AMQConnection con) + { + // We wait until we are not in the middle of failover before acquiring the mutex and then proceeding. + // Any method that can potentially block for any reason should use this class so that deadlock will not + // occur. The FailoverException is propagated by the AMQProtocolHandler to any listeners (e.g. frame listeners) + // that might be causing a block. When that happens, the exception is caught here and the mutex is released + // before waiting for the failover to complete (either successfully or unsuccessfully). + while (true) + { + con.ProtocolListener.BlockUntilNotFailingOver(); + lock (con.FailoverMutex) + { + try + { + return operation(); + } + catch (FailoverException e) + { + _log.Info("Failover exception caught during operation", e); + } + } + } + } + + protected abstract object operation(); + } +} diff --git a/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs new file mode 100644 index 0000000000..d6e196c8dd --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Client.Message; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class BasicDeliverMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(BasicDeliverMethodHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + UnprocessedMessage msg = new UnprocessedMessage(); + msg.DeliverBody = (BasicDeliverBody) evt.Method; + msg.ChannelId = evt.ChannelId; + _logger.Debug("New JmsDeliver method received"); + evt.ProtocolSession.UnprocessedMessageReceived(msg); + } + } +} diff --git a/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs new file mode 100644 index 0000000000..78526f906f --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs @@ -0,0 +1,44 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Client.Message; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class BasicReturnMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(BasicReturnMethodHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + _logger.Debug("New JmsBounce method received"); + UnprocessedMessage msg = new UnprocessedMessage(); + msg.DeliverBody = null; + msg.BounceBody = (BasicReturnBody) evt.Method; + msg.ChannelId = evt.ChannelId; + + evt.ProtocolSession.UnprocessedMessageReceived(msg); + } + } +} diff --git a/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs new file mode 100644 index 0000000000..1031f804a6 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs @@ -0,0 +1,57 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class ChannelCloseMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(ChannelCloseMethodHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + _logger.Debug("ChannelClose method received"); + ChannelCloseBody method = (ChannelCloseBody) evt.Method; + + int errorCode = method.ReplyCode; + string reason = method.ReplyText; + if (_logger.IsDebugEnabled) + { + _logger.Debug("Channel close reply code: " + errorCode + ", reason: " + reason); + } + + AMQFrame frame = ChannelCloseOkBody.CreateAMQFrame(evt.ChannelId); + evt.ProtocolSession.WriteFrame(frame); + //if (errorCode != AMQConstant.REPLY_SUCCESS.getCode()) + // HACK + if (errorCode != 200) + { + _logger.Debug("Channel close received with errorCode " + errorCode + ", throwing exception"); + evt.ProtocolSession.AMQConnection.ExceptionReceived(new AMQChannelClosedException(errorCode, "Error: " + reason)); + } + evt.ProtocolSession.ChannelClosed(evt.ChannelId, errorCode, reason); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs new file mode 100644 index 0000000000..c3acc0b098 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using System; +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class ConnectionCloseMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionCloseMethodHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + _logger.Debug("ConnectionClose frame received"); + ConnectionCloseBody method = (ConnectionCloseBody) evt.Method; + + int errorCode = method.ReplyCode; + String reason = method.ReplyText; + + evt.ProtocolSession.WriteFrame(ConnectionCloseOkBody.CreateAMQFrame(evt.ChannelId)); + stateManager.ChangeState(AMQState.CONNECTION_CLOSED); + if (errorCode != 200) + { + _logger.Debug("Connection close received with error code " + errorCode); + throw new AMQConnectionClosedException(errorCode, "Error: " + reason); + } + + // this actually closes the connection in the case where it is not an error. + evt.ProtocolSession.CloseProtocolSession(); + } + } +} diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs new file mode 100644 index 0000000000..0cd60457ea --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class ConnectionCloseOkHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionCloseOkHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + _logger.Debug("ConnectionCloseOk frame received"); + ConnectionCloseOkBody method = (ConnectionCloseOkBody)evt.Method; + stateManager.ChangeState(AMQState.CONNECTION_CLOSED); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs new file mode 100644 index 0000000000..b43e2700f6 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs @@ -0,0 +1,34 @@ +/* + * + * 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. + * + */ +using Qpid.Client.Protocol; +using Qpid.Client.State; + +namespace Qpid.Client.Handler +{ + public class ConnectionOpenOkMethodHandler : IStateAwareMethodListener + { + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + stateManager.ChangeState(AMQState.CONNECTION_OPEN); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs new file mode 100644 index 0000000000..4437290f5c --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs @@ -0,0 +1,67 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; + +namespace Qpid.Client.Handler +{ + public class ConnectionRedirectMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionRedirectMethodHandler)); + + private const int DEFAULT_REDIRECT_PORT = 5672; + + private static ConnectionRedirectMethodHandler _handler = new ConnectionRedirectMethodHandler(); + + public static ConnectionRedirectMethodHandler GetInstance() + { + return _handler; + } + + private ConnectionRedirectMethodHandler() + { + } + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + /*_logger.Info("ConnectionRedirect frame received"); + ConnectionRedirectBody method = (ConnectionRedirectBody) evt.Method; + + // the host is in the form hostname:port with the port being optional + int portIndex = method.Host.IndexOf(':'); + String host; + int port; + if (portIndex == -1) + { + host = method.Host; + port = DEFAULT_REDIRECT_PORT; + } + else + { + host = method.Host.Substring(0, portIndex); + port = Int32.Parse(method.Host.Substring(portIndex + 1)); + } + evt.ProtocolSession.Failover(host, port);*/ + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs new file mode 100644 index 0000000000..7c0fbd8f40 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class ConnectionSecureMethodHandler : IStateAwareMethodListener + { + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + AMQFrame response = ConnectionSecureOkBody.CreateAMQFrame(evt.ChannelId, null); + evt.ProtocolSession.WriteFrame(response); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs new file mode 100644 index 0000000000..2bba8662bb --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs @@ -0,0 +1,113 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class ConnectionStartMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _log = LogManager.GetLogger(typeof(ConnectionStartMethodHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + ConnectionStartBody body = (ConnectionStartBody) evt.Method; + AMQProtocolSession ps = evt.ProtocolSession; + string username = ps.Username; + string password = ps.Password; + + try + { + if (body.Mechanisms == null) + { + throw new AMQException("mechanism not specified in ConnectionStart method frame"); + } + string allMechanisms = Encoding.ASCII.GetString(body.Mechanisms); + string[] mechanisms = allMechanisms.Split(' '); + string selectedMechanism = null; + foreach (string mechanism in mechanisms) + { + if (mechanism.Equals("PLAIN")) + { + selectedMechanism = mechanism; + break; + } + } + + if (selectedMechanism == null) + { + throw new AMQException("No supported security mechanism found, passed: " + mechanisms); + } + + // we always write out a null authzid which we don't currently use + byte[] plainData = new byte[1 + ps.Username.Length + 1 + ps.Password.Length]; + Encoding.UTF8.GetBytes(username, 0, username.Length, plainData, 1); + Encoding.UTF8.GetBytes(password, 0, password.Length, plainData, username.Length + 2); + if (body.Locales == null) + { + throw new AMQException("Locales is not defined in Connection Start method"); + } + string allLocales = Encoding.ASCII.GetString(body.Locales); + string[] locales = allLocales.Split(new char[] { ' ' }); + string selectedLocale; + if (locales != null && locales.Length > 0) + { + selectedLocale = locales[0]; + } + else + { + throw new AMQException("No locales sent from server, passed: " + locales); + } + + stateManager.ChangeState(AMQState.CONNECTION_NOT_TUNED); + FieldTable clientProperties = new FieldTable(); + clientProperties["product"] = "Qpid.NET"; + clientProperties["version"] = "1.0"; + clientProperties["platform"] = GetFullSystemInfo(); + AMQFrame frame = ConnectionStartOkBody.CreateAMQFrame(evt.ChannelId, clientProperties, selectedMechanism, + plainData, selectedLocale); + ps.WriteFrame(frame); + } + catch (Exception e) + { + throw new AMQException(_log, "Unable to decode data: " + e, e); + } + } + + private string GetFullSystemInfo() + { + /*StringBuffer fullSystemInfo = new StringBuffer(); + fullSystemInfo.append(System.getProperty("java.runtime.name")); + fullSystemInfo.append(", " + System.getProperty("java.runtime.version")); + fullSystemInfo.append(", " + System.getProperty("java.vendor")); + fullSystemInfo.append(", " + System.getProperty("os.arch")); + fullSystemInfo.append(", " + System.getProperty("os.name")); + fullSystemInfo.append(", " + System.getProperty("os.version")); + fullSystemInfo.append(", " + System.getProperty("sun.os.patch.level"));*/ + // TODO: add in details here + return ".NET 1.1 Client"; + } + } +} diff --git a/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs b/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs new file mode 100644 index 0000000000..8b276c09e9 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs @@ -0,0 +1,65 @@ +/* + * + * 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. + * + */ +using System; +using log4net; +using Qpid.Client.Protocol; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Handler +{ + public class ConnectionTuneMethodHandler : IStateAwareMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionTuneMethodHandler)); + + public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + { + _logger.Debug("ConnectionTune frame received"); + ConnectionTuneBody frame = (ConnectionTuneBody) evt.Method; + AMQProtocolSession session = evt.ProtocolSession; + + ConnectionTuneParameters parameters = session.ConnectionTuneParameters; + if (parameters == null) + { + parameters = new ConnectionTuneParameters(); + } + + _logger.Info(String.Format("ConnectionTune.heartbeat = {0}.", frame.Heartbeat)); + + parameters.FrameMax = frame.FrameMax; + parameters.FrameMax = 65535; + //params.setChannelMax(frame.channelMax); + parameters.Heartbeat = frame.Heartbeat; + session.ConnectionTuneParameters = parameters; + + stateManager.ChangeState(AMQState.CONNECTION_NOT_OPENED); + session.WriteFrame(ConnectionTuneOkBody.CreateAMQFrame( + evt.ChannelId, frame.ChannelMax, 65535, frame.Heartbeat)); + session.WriteFrame(ConnectionOpenBody.CreateAMQFrame( + evt.ChannelId, session.AMQConnection.VirtualHost, null, true)); + + if (frame.Heartbeat > 0) + { + evt.ProtocolSession.AMQConnection.StartHeartBeatThread(frame.Heartbeat); + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/Message/AMQMessage.cs b/dotnet/Qpid.Client/Client/Message/AMQMessage.cs new file mode 100644 index 0000000000..eb34fa45db --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/AMQMessage.cs @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ +using Qpid.Framing; + +namespace Qpid.Client.Message +{ + public class AMQMessage + { + protected IContentHeaderProperties _contentHeaderProperties; + + /// <summary> + /// If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required + /// </summary> + protected AmqChannel _channel; + + public AMQMessage(IContentHeaderProperties properties) + { + _contentHeaderProperties = properties; + } + + public AmqChannel Channel + { + get + { + return _channel; + } + + set + { + _channel = value; + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs b/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs new file mode 100644 index 0000000000..e485bb6d34 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs @@ -0,0 +1,49 @@ +/* + * + * 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. + * + */ +using System.Collections; +using Qpid.Framing; + +namespace Qpid.Client.Message +{ + public abstract class AbstractQmsMessageFactory : IMessageFactory + { + public AbstractQmsMessage CreateMessage(ulong messageNbr, bool redelivered, ContentHeaderBody contentHeader, IList bodies) + { + AbstractQmsMessage msg = CreateMessageWithBody(messageNbr, contentHeader, bodies); + msg.Redelivered = redelivered; + return msg; + } + + public abstract AbstractQmsMessage CreateMessage(); + + /// <summary> + /// + /// </summary> + /// <param name="messageNbr"></param> + /// <param name="contentHeader"></param> + /// <param name="bodies"></param> + /// <returns></returns> + /// <exception cref="AMQException"></exception> + protected abstract AbstractQmsMessage CreateMessageWithBody(ulong messageNbr, + ContentHeaderBody contentHeader, + IList bodies); + } +} diff --git a/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs b/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs new file mode 100644 index 0000000000..c84e9de1b9 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs @@ -0,0 +1,800 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Text; +using log4net; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client.Message +{ + public class SendOnlyDestination : AMQDestination + { + private static readonly ILog _log = LogManager.GetLogger(typeof(string)); + + public SendOnlyDestination(string exchangeName, string routingKey) + : base(exchangeName, null, null, false, false, routingKey) + { + _log.Debug( + string.Format("Creating SendOnlyDestination with exchangeName={0} and routingKey={1}", + exchangeName, routingKey)); + } + + public override string EncodedName + { + get { return ExchangeName + ":" + QueueName; } + } + + public override string RoutingKey + { + get { return QueueName; } + } + + public override bool IsNameRequired + { + get { throw new NotImplementedException(); } + } + } + + public abstract class AbstractQmsMessage : AMQMessage, IMessage + { + private static readonly ILog _log = LogManager.GetLogger(typeof(AbstractQmsMessage)); + + protected ulong _messageNbr; + + protected bool _redelivered; + + protected AbstractQmsMessage() : base(new BasicContentHeaderProperties()) + { + } + + protected AbstractQmsMessage(ulong messageNbr, BasicContentHeaderProperties contentHeader) + : this(contentHeader) + { + _messageNbr = messageNbr; + } + + protected AbstractQmsMessage(BasicContentHeaderProperties contentHeader) + : base(contentHeader) + { + } + + public string MessageId + { + get + { + if (ContentHeaderProperties.MessageId == null) + { + ContentHeaderProperties.MessageId = "ID:" + _messageNbr; + } + return ContentHeaderProperties.MessageId; + } + set + { + ContentHeaderProperties.MessageId = value; + } + } + + public long Timestamp + { + get + { + // TODO: look at ulong/long choice + return (long) ContentHeaderProperties.Timestamp; + } + set + { + ContentHeaderProperties.Timestamp = (ulong) value; + } + } + + public byte[] CorrelationIdAsBytes + { + get + { + return Encoding.Default.GetBytes(ContentHeaderProperties.CorrelationId); + } + set + { + ContentHeaderProperties.CorrelationId = Encoding.Default.GetString(value); + } + } + + public string CorrelationId + { + get + { + return ContentHeaderProperties.CorrelationId; + } + set + { + ContentHeaderProperties.ContentType = value; + } + } + + struct Dest + { + public string ExchangeName; + public string RoutingKey; + + public Dest(string exchangeName, string routingKey) + { + ExchangeName = exchangeName; + RoutingKey = routingKey; + } + } + + public string ReplyToExchangeName + { + get + { + Dest dest = ReadReplyToHeader(); + return dest.ExchangeName; + } + set + { + Dest dest = ReadReplyToHeader(); + dest.ExchangeName = value; + WriteReplyToHeader(dest); + } + } + + public string ReplyToRoutingKey + { + get + { + Dest dest = ReadReplyToHeader(); + return dest.RoutingKey; + } + set + { + Dest dest = ReadReplyToHeader(); + dest.RoutingKey = value; + WriteReplyToHeader(dest); + } + } + + private Dest ReadReplyToHeader() + { + string replyToEncoding = ContentHeaderProperties.ReplyTo; + if (replyToEncoding == null) + { + return new Dest(); + } + else + { + string routingKey; + string exchangeName = GetExchangeName(replyToEncoding, out routingKey); + return new Dest(exchangeName, routingKey); + } + } + + private void WriteReplyToHeader(Dest dest) + { + string encodedDestination = string.Format("{0}:{1}", dest.ExchangeName, dest.RoutingKey); + ContentHeaderProperties.ReplyTo = encodedDestination; + } + + private static string GetExchangeName(string replyToEncoding, out string routingKey) + { + string[] split = replyToEncoding.Split(new char[':']); + if (_log.IsDebugEnabled) + { + _log.Debug(string.Format("replyToEncoding = '{0}'", replyToEncoding)); + _log.Debug(string.Format("split = {0}", split)); + _log.Debug(string.Format("split.Length = {0}", split.Length)); + } + if (split.Length == 1) + { + // Using an alternative split implementation here since it appears that string.Split + // is broken in .NET. It doesn't split when the first character is the delimiter. + // Here we check for the first character being the delimiter. This handles the case + // where ExchangeName is empty (i.e. sends will be to the default exchange). + if (replyToEncoding[0] == ':') + { + split = new string[2]; + split[0] = null; + split[1] = replyToEncoding.Substring(1); + if (_log.IsDebugEnabled) + { + _log.Debug("Alternative split method..."); + _log.Debug(string.Format("split = {0}", split)); + _log.Debug(string.Format("split.Length = {0}", split.Length)); + } + } + } + if (split.Length != 2) + { + throw new QpidException("Illegal value in ReplyTo property: " + replyToEncoding); + } + + string exchangeName = split[0]; + routingKey = split[1]; + return exchangeName; + } + + public DeliveryMode DeliveryMode + { + get + { + byte b = ContentHeaderProperties.DeliveryMode; + switch (b) + { + case 1: + return DeliveryMode.NonPersistent; + case 2: + return DeliveryMode.Persistent; + default: + throw new QpidException("Illegal value for delivery mode in content header properties"); + } + } + set + { + ContentHeaderProperties.DeliveryMode = (byte)(value==DeliveryMode.NonPersistent?1:2); + } + } + + public bool Redelivered + { + get + { + return _redelivered; + } + set + { + _redelivered = value; + } + } + + public string Type + { + get + { + return MimeType; + } + set + { + //MimeType = value; + } + } + + public long Expiration + { + get + { + return ContentHeaderProperties.Expiration; + } + set + { + ContentHeaderProperties.Expiration = (uint) value; + } + } + + public int Priority + { + get + { + return ContentHeaderProperties.Priority; + } + set + { + ContentHeaderProperties.Priority = (byte) value; + } + } + + // FIXME: implement + public string ContentType + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + // FIXME: implement + public string ContentEncoding + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + public void Acknowledge() + { + // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge + // is not specified. In our case, we only set the session field where client acknowledge mode is specified. + if (_channel != null) + { + _channel.SendAcknowledgement(_messageNbr); + } + } + + public IHeaders Headers + { + get { return new QpidHeaders(this); } + } + + public abstract void ClearBody(); + + /// <summary> + /// Get a String representation of the body of the message. Used in the + /// toString() method which outputs this before message properties. + /// </summary> + /// <exception cref="QpidException"></exception> + public abstract string ToBodyString(); + + /// <summary> + /// Return the raw byte array that is used to populate the frame when sending + /// the message. + /// </summary> + /// <value>a byte array of message data</value> + public abstract byte[] Data + { + get; + set; + } + + public abstract string MimeType + { + get; + } + + public override string ToString() + { + try + { + StringBuilder buf = new StringBuilder("Body:\n"); + buf.Append(ToBodyString()); + buf.Append("\nQmsTimestamp: ").Append(Timestamp); + buf.Append("\nQmsExpiration: ").Append(Expiration); + buf.Append("\nQmsPriority: ").Append(Priority); + buf.Append("\nQmsDeliveryMode: ").Append(DeliveryMode); + buf.Append("\nReplyToExchangeName: ").Append(ReplyToExchangeName); + buf.Append("\nReplyToRoutingKey: ").Append(ReplyToRoutingKey); + buf.Append("\nAMQ message number: ").Append(_messageNbr); + buf.Append("\nProperties:"); + if (ContentHeaderProperties.Headers == null) + { + buf.Append("<NONE>"); + } + else + { + buf.Append(Headers.ToString()); + } + return buf.ToString(); + } + catch (Exception e) + { + return e.ToString(); + } + } + + public IFieldTable UnderlyingMessagePropertiesMap + { + get + { + return ContentHeaderProperties.Headers; + } + set + { + ContentHeaderProperties.Headers = (FieldTable)value; + } + } + + public FieldTable PopulateHeadersFromMessageProperties() + { + if (ContentHeaderProperties.Headers == null) + { + return null; + } + else + { + // + // We need to convert every property into a String representation + // Note that type information is preserved in the property name + // + FieldTable table = new FieldTable(); + foreach (DictionaryEntry entry in ContentHeaderProperties.Headers) + { + string propertyName = (string) entry.Key; + if (propertyName == null) + { + continue; + } + else + { + table[propertyName] = entry.Value.ToString(); + } + } + return table; + } + } + + /// <summary> + /// Get the AMQ message number assigned to this message + /// </summary> + /// <returns>the message number</returns> + public ulong MessageNbr + { + get + { + return _messageNbr; + } + set + { + _messageNbr = value; + } + } + + public BasicContentHeaderProperties ContentHeaderProperties + { + get + { + return (BasicContentHeaderProperties) _contentHeaderProperties; + } + } + } + + internal class QpidHeaders : IHeaders + { + public const char BOOLEAN_PROPERTY_PREFIX = 'B'; + public const char BYTE_PROPERTY_PREFIX = 'b'; + public const char SHORT_PROPERTY_PREFIX = 's'; + public const char INT_PROPERTY_PREFIX = 'i'; + public const char LONG_PROPERTY_PREFIX = 'l'; + public const char FLOAT_PROPERTY_PREFIX = 'f'; + public const char DOUBLE_PROPERTY_PREFIX = 'd'; + public const char STRING_PROPERTY_PREFIX = 'S'; + + AbstractQmsMessage _message; + + public QpidHeaders(AbstractQmsMessage message) + { + _message = message; + } + + public bool Contains(string name) + { + CheckPropertyName(name); + if (_message.ContentHeaderProperties.Headers == null) + { + return false; + } + else + { + // TODO: fix this + return _message.ContentHeaderProperties.Headers.Contains(STRING_PROPERTY_PREFIX + name); + } + } + + public void Clear() + { + if (_message.ContentHeaderProperties.Headers != null) + { + _message.ContentHeaderProperties.Headers.Clear(); + } + } + + public string this[string name] + { + get + { + return GetString(name); + } + set + { + SetString(name, value); + } + } + + public bool GetBoolean(string name) + { + CheckPropertyName(name); + if (_message.ContentHeaderProperties.Headers == null) + { + return false; + } + else + { + object b = _message.ContentHeaderProperties.Headers[BOOLEAN_PROPERTY_PREFIX + name]; + + if (b == null) + { + return false; + } + else + { + return (bool)b; + } + } + } + + public void SetBoolean(string name, bool b) + { + CheckPropertyName(name); + _message.ContentHeaderProperties.Headers[BOOLEAN_PROPERTY_PREFIX + name] = b; + } + + public byte GetByte(string propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return 0; + } + else + { + object b = _message.ContentHeaderProperties.Headers[BYTE_PROPERTY_PREFIX + propertyName]; + if (b == null) + { + return 0; + } + else + { + return (byte)b; + } + } + } + + public void SetByte(string propertyName, byte b) + { + CheckPropertyName(propertyName); + _message.ContentHeaderProperties.Headers[BYTE_PROPERTY_PREFIX + propertyName] = b; + } + + public short GetShort(string propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return 0; + } + else + { + object s = _message.ContentHeaderProperties.Headers[SHORT_PROPERTY_PREFIX + propertyName]; + if (s == null) + { + return 0; + } + else + { + return (short)s; + } + } + } + + public void SetShort(string propertyName, short i) + { + CheckPropertyName(propertyName); + _message.ContentHeaderProperties.Headers[SHORT_PROPERTY_PREFIX + propertyName] = i; + } + + public int GetInt(string propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return 0; + } + else + { + object i = _message.ContentHeaderProperties.Headers[INT_PROPERTY_PREFIX + propertyName]; + if (i == null) + { + return 0; + } + else + { + return (int)i; + } + } + } + + public void SetInt(string propertyName, int i) + { + CheckPropertyName(propertyName); + _message.ContentHeaderProperties.Headers[INT_PROPERTY_PREFIX + propertyName] = i; + } + + public long GetLong(string propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return 0; + } + else + { + object l = _message.ContentHeaderProperties.Headers[LONG_PROPERTY_PREFIX + propertyName]; + if (l == null) + { + // temp - the spec says do this but this throws a NumberFormatException + //return Long.valueOf(null).longValue(); + return 0; + } + else + { + return (long)l; + } + } + } + + public void SetLong(string propertyName, long l) + { + CheckPropertyName(propertyName); + _message.ContentHeaderProperties.Headers[LONG_PROPERTY_PREFIX + propertyName] = l; + } + + public float GetFloat(String propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return 0; + } + else + { + object f = _message.ContentHeaderProperties.Headers[FLOAT_PROPERTY_PREFIX + propertyName]; + if (f == null) + { + return 0; + } + else + { + return (float)f; + } + } + } + + public void SetFloat(string propertyName, float f) + { + CheckPropertyName(propertyName); + _message.ContentHeaderProperties.Headers[FLOAT_PROPERTY_PREFIX + propertyName] = f; + } + + public double GetDouble(string propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return 0; + } + else + { + object d = _message.ContentHeaderProperties.Headers[DOUBLE_PROPERTY_PREFIX + propertyName]; + if (d == null) + { + return 0; + } + else + { + return (double)d; + } + } + } + + public void SetDouble(string propertyName, double v) + { + CheckPropertyName(propertyName); + _message.ContentHeaderProperties.Headers[DOUBLE_PROPERTY_PREFIX + propertyName] = v; + } + + public string GetString(string propertyName) + { + CheckPropertyName(propertyName); + if (_message.ContentHeaderProperties.Headers == null) + { + return null; + } + else + { + return (string)_message.ContentHeaderProperties.Headers[STRING_PROPERTY_PREFIX + propertyName]; + } + } + + public void SetString(string propertyName, string value) + { + CheckPropertyName(propertyName); + CreatePropertyMapIfRequired(); + propertyName = STRING_PROPERTY_PREFIX + propertyName; + _message.ContentHeaderProperties.Headers[propertyName] = value; + } + + private void CheckPropertyName(string propertyName) + { + if (propertyName == null) + { + throw new ArgumentException("Property name must not be null"); + } + else if ("".Equals(propertyName)) + { + throw new ArgumentException("Property name must not be the empty string"); + } + + if (_message.ContentHeaderProperties.Headers == null) + { + _message.ContentHeaderProperties.Headers = new FieldTable(); + } + } + + private void CreatePropertyMapIfRequired() + { + if (_message.ContentHeaderProperties.Headers == null) + { + _message.ContentHeaderProperties.Headers = new FieldTable(); + } + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder("{"); + int i = 0; + foreach (DictionaryEntry entry in _message.ContentHeaderProperties.Headers) + { + ++i; + if (i > 1) + { + buf.Append(", "); + } + string propertyName = (string)entry.Key; + if (propertyName == null) + { + buf.Append("\nInternal error: Property with NULL key defined"); + } + else + { + buf.Append(propertyName.Substring(1)); + + buf.Append(" : "); + + char typeIdentifier = propertyName[0]; + buf.Append(typeIdentifierToName(typeIdentifier)); + buf.Append(" = ").Append(entry.Value); + } + } + buf.Append("}"); + return buf.ToString(); + } + + private static string typeIdentifierToName(char typeIdentifier) + { + switch (typeIdentifier) + { + case BOOLEAN_PROPERTY_PREFIX: + return "boolean"; + case BYTE_PROPERTY_PREFIX: + return "byte"; + case SHORT_PROPERTY_PREFIX: + return "short"; + case INT_PROPERTY_PREFIX: + return "int"; + case LONG_PROPERTY_PREFIX: + return "long"; + case FLOAT_PROPERTY_PREFIX: + return "float"; + case DOUBLE_PROPERTY_PREFIX: + return "double"; + case STRING_PROPERTY_PREFIX: + return "string"; + default: + return "unknown ( '" + typeIdentifier + "')"; + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs b/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs new file mode 100644 index 0000000000..2e71bfc948 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs @@ -0,0 +1,49 @@ +/* + * + * 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. + * + */ +using System.Collections; +using Qpid.Framing; + +namespace Qpid.Client.Message +{ + public interface IMessageFactory + { + /// <summary> + /// Create a message + /// </summary> + /// <param name="messageNbr"></param> + /// <param name="redelivered"></param> + /// <param name="contentHeader"></param> + /// <param name="bodies"></param> + /// <returns></returns> + /// <exception cref="QpidMessagingException">if the message cannot be created</exception> + AbstractQmsMessage CreateMessage(ulong messageNbr, bool redelivered, + ContentHeaderBody contentHeader, + IList bodies); + + /// <summary> + /// Creates the message. + /// </summary> + /// <returns></returns> + /// <exception cref="QpidMessagingException">if the message cannot be created</exception> + AbstractQmsMessage CreateMessage(); + } +} + diff --git a/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs b/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs new file mode 100644 index 0000000000..3965d531bb --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs @@ -0,0 +1,117 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client.Message +{ + public class MessageFactoryRegistry + { + private readonly Hashtable _mimeToFactoryMap = new Hashtable(); + + public void RegisterFactory(string mimeType, IMessageFactory mf) + { + if (mf == null) + { + throw new ArgumentNullException("Message factory"); + } + if (mimeType == null) + { + throw new ArgumentNullException("mf"); + } + _mimeToFactoryMap[mimeType] = mf; + } + + public void DeregisterFactory(string mimeType) + { + _mimeToFactoryMap.Remove(mimeType); + } + + /// <summary> + /// Create a message. This looks up the MIME type from the content header and instantiates the appropriate + /// concrete message type. + /// </summary> + /// <param name="messageNbr">the AMQ message id</param> + /// <param name="redelivered">true if redelivered</param> + /// <param name="contentHeader">the content header that was received</param> + /// <param name="bodies">a list of ContentBody instances</param> + /// <returns>the message.</returns> + /// <exception cref="AMQException"/> + /// <exception cref="QpidException"/> + public AbstractQmsMessage CreateMessage(ulong messageNbr, bool redelivered, + ContentHeaderBody contentHeader, + IList bodies) + { + BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.Properties; + + if (properties.ContentType == null) + { + properties.ContentType = ""; + } + + IMessageFactory mf = (IMessageFactory) _mimeToFactoryMap[properties.ContentType]; + if (mf == null) + { + throw new AMQException("Unsupport MIME type of " + properties.ContentType); + } + else + { + return mf.CreateMessage(messageNbr, redelivered, contentHeader, bodies); + } + } + + public AbstractQmsMessage CreateMessage(string mimeType) + { + if (mimeType == null) + { + throw new ArgumentNullException("Mime type must not be null"); + } + IMessageFactory mf = (IMessageFactory) _mimeToFactoryMap[mimeType]; + if (mf == null) + { + throw new AMQException("Unsupport MIME type of " + mimeType); + } + else + { + return mf.CreateMessage(); + } + } + + /// <summary> + /// Construct a new registry with the default message factories registered + /// </summary> + /// <returns>a message factory registry</returns> + public static MessageFactoryRegistry NewDefaultRegistry() + { + MessageFactoryRegistry mf = new MessageFactoryRegistry(); + mf.RegisterFactory("text/plain", new QpidTextMessageFactory()); + mf.RegisterFactory("text/xml", new QpidTextMessageFactory()); + mf.RegisterFactory("application/octet-stream", new QpidBytesMessageFactory()); + // TODO: use bytes message for default message factory + // MJA - just added this bit back in... + mf.RegisterFactory("", new QpidBytesMessageFactory()); + return mf; + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs b/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs new file mode 100644 index 0000000000..b7911b44b9 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs @@ -0,0 +1,581 @@ +/* + * + * 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. + * + */ +using System; +using System.IO; +using System.Text; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client.Message +{ + public class QpidBytesMessage : AbstractQmsMessage, IBytesMessage + { + private const string MIME_TYPE = "application/octet-stream"; + + /// <summary> + /// The backingstore for the data + /// </summary> + private MemoryStream _dataStream; + + private int _bodyLength; + + private BinaryReader _reader; + + private BinaryWriter _writer; + + public QpidBytesMessage() : this(null) + { + } + + /// <summary> + /// Construct a bytes message with existing data. + /// </summary> + /// <param name="data">if data is not null, the message is immediately in read only mode. if data is null, it is in + /// write-only mode</param> + QpidBytesMessage(byte[] data) : base() + { + // superclass constructor has instantiated a content header at this point + ContentHeaderProperties.ContentType = MIME_TYPE; + if (data == null) + { + _dataStream = new MemoryStream(); + _writer = new BinaryWriter(_dataStream); + } + else + { + _dataStream = new MemoryStream(data); + _bodyLength = data.Length; + _reader = new BinaryReader(_dataStream); + } + } + + public QpidBytesMessage(ulong messageNbr, byte[] data, ContentHeaderBody contentHeader) + // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea + : base(messageNbr, (BasicContentHeaderProperties) contentHeader.Properties) + { + ContentHeaderProperties.ContentType = MIME_TYPE; + _dataStream = new MemoryStream(data); + _bodyLength = data.Length; + _reader = new BinaryReader(_dataStream); + } + + public override void ClearBody() + { + if (_reader != null) + { + _reader.Close(); + _reader = null; + } + _dataStream = new MemoryStream(); + _bodyLength = 0; + + _writer = new BinaryWriter(_dataStream); + } + + public override string ToBodyString() + { + CheckReadable(); + try + { + return GetText(); + } + catch (IOException e) + { + throw new QpidException(e.ToString()); + } + } + + private string GetText() + { + if (_dataStream != null) + { + // we cannot just read the underlying buffer since it may be larger than the amount of + // "filled" data. Length is not the same as Capacity. + byte[] data = new byte[_dataStream.Length]; + _dataStream.Read(data, 0, (int)_dataStream.Length); + return Encoding.UTF8.GetString(data); + } + else + { + return null; + } + } + + public override byte[] Data + { + get + { + if (_dataStream == null) + { + return null; + } + else + { + byte[] data = new byte[_dataStream.Length]; + _dataStream.Position = 0; + _dataStream.Read(data, 0, (int) _dataStream.Length); + return data; + } + } + set + { + throw new NotSupportedException("Cannot set data payload except during construction"); + } + } + + public override string MimeType + { + get + { + return MIME_TYPE; + } + } + + public long BodyLength + { + get + { + CheckReadable(); + return _bodyLength; + } + } + + /// <summary> + /// + /// </summary> + /// <exception cref="MessageNotReadableException">if the message is in write mode</exception> + private void CheckReadable() + { + if (_reader == null) + { + throw new MessageNotReadableException("You need to call reset() to make the message readable"); + } + } + + private void CheckWritable() + { + if (_reader != null) + { + throw new MessageNotWriteableException("You need to call clearBody() to make the message writable"); + } + } + + public bool ReadBoolean() + { + CheckReadable(); + try + { + return _reader.ReadBoolean(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public byte ReadByte() + { + CheckReadable(); + try + { + return _reader.ReadByte(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public short ReadSignedByte() + { + CheckReadable(); + try + { + return _reader.ReadSByte(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public short ReadShort() + { + CheckReadable(); + try + { + return _reader.ReadInt16(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public char ReadChar() + { + CheckReadable(); + try + { + return _reader.ReadChar(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public int ReadInt() + { + CheckReadable(); + try + { + return _reader.ReadInt32(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public long ReadLong() + { + CheckReadable(); + try + { + return _reader.ReadInt64(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public float ReadFloat() + { + CheckReadable(); + try + { + return _reader.ReadSingle(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public double ReadDouble() + { + CheckReadable(); + try + { + return _reader.ReadDouble(); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public string ReadUTF() + { + CheckReadable(); + try + { + byte[] data = _reader.ReadBytes((int)_dataStream.Length); + return Encoding.UTF8.GetString(data); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public int ReadBytes(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + CheckReadable(); + try + { + return _reader.Read(bytes, 0, bytes.Length); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public int ReadBytes(byte[] bytes, int count) + { + CheckReadable(); + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (count < 0) + { + throw new ArgumentOutOfRangeException("count must be >= 0"); + } + if (count > bytes.Length) + { + count = bytes.Length; + } + + try + { + return _reader.Read(bytes, 0, count); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteBoolean(bool b) + { + CheckWritable(); + try + { + _writer.Write(b); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteByte(byte b) + { + CheckWritable(); + try + { + _writer.Write(b); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteShort(short i) + { + CheckWritable(); + try + { + _writer.Write(i); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteChar(char c) + { + CheckWritable(); + try + { + _writer.Write(c); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteSignedByte(short value) + { + CheckWritable(); + try + { + _writer.Write(value); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteDouble(double value) + { + CheckWritable(); + try + { + _writer.Write(value); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteFloat(float value) + { + CheckWritable(); + try + { + _writer.Write(value); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteInt(int value) + { + CheckWritable(); + try + { + _writer.Write(value); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteLong(long value) + { + CheckWritable(); + try + { + _writer.Write(value); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void Write(int i) + { + CheckWritable(); + try + { + _writer.Write(i); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void Write(long l) + { + CheckWritable(); + try + { + _writer.Write(l); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void Write(float v) + { + CheckWritable(); + try + { + _writer.Write(v); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void Write(double v) + { + CheckWritable(); + try + { + _writer.Write(v); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteUTF(string value) + { + CheckWritable(); + try + { + byte[] encodedData = Encoding.UTF8.GetBytes(value); + _writer.Write(encodedData); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteBytes(byte[] bytes) + { + CheckWritable(); + try + { + _writer.Write(bytes); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void WriteBytes(byte[] bytes, int offset, int length) + { + CheckWritable(); + try + { + _writer.Write(bytes, offset, length); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public void Reset() + { + CheckWritable(); + try + { + _writer.Close(); + _writer = null; + _reader = new BinaryReader(_dataStream); + _bodyLength = (int) _dataStream.Length; + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs b/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs new file mode 100644 index 0000000000..3f2a6c531f --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs @@ -0,0 +1,60 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using Qpid.Framing; + +namespace Qpid.Client.Message +{ + public class QpidBytesMessageFactory : AbstractQmsMessageFactory + { + protected override AbstractQmsMessage CreateMessageWithBody(ulong messageNbr, + ContentHeaderBody contentHeader, + IList bodies) + { + byte[] data; + + // we optimise the non-fragmented case to avoid copying + if (bodies != null && bodies.Count == 1) + { + data = ((ContentBody)bodies[0]).Payload; + } + else + { + data = new byte[(long)contentHeader.BodySize]; + int currentPosition = 0; + foreach (ContentBody cb in bodies) + { + Array.Copy(cb.Payload, 0, data, currentPosition, cb.Payload.Length); + currentPosition += cb.Payload.Length; + } + } + + return new QpidBytesMessage(messageNbr, data, contentHeader); + } + + public override AbstractQmsMessage CreateMessage() + { + return new QpidBytesMessage(); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs b/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs new file mode 100644 index 0000000000..4c16038d4b --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs @@ -0,0 +1,137 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using Qpid.Framing; +using Qpid.Messaging; + +namespace Qpid.Client.Message +{ + public class QpidTextMessage : AbstractQmsMessage, ITextMessage + { + private const string MIME_TYPE = "text/plain"; + + private byte[] _data; + + private string _decodedValue; + + public QpidTextMessage() : this(null, null) + { + } + + public QpidTextMessage(byte[] data, String encoding) : base() + { + // the superclass has instantied a content header at this point + ContentHeaderProperties.ContentType= MIME_TYPE; + _data = data; + ContentHeaderProperties.Encoding = encoding; + } + + public QpidTextMessage(ulong messageNbr, byte[] data, BasicContentHeaderProperties contentHeader) + : base(messageNbr, contentHeader) + { + contentHeader.ContentType = MIME_TYPE; + _data = data; + } + + public QpidTextMessage(byte[] data) : this(data, null) + { + } + + public QpidTextMessage(string text) + { + Text = text; + } + + public override void ClearBody() + { + _data = null; + _decodedValue = null; + } + + public override string ToBodyString() + { + return Text; + } + + public override byte[] Data + { + get + { + return _data; + } + set + { + _data = value; + } + } + + public override string MimeType + { + get + { + return MIME_TYPE; + } + } + + public string Text + { + get + { + if (_data == null && _decodedValue == null) + { + return null; + } + else if (_decodedValue != null) + { + return _decodedValue; + } + else + { + if (ContentHeaderProperties.Encoding != null) + { + // throw ArgumentException if the encoding is not supported + _decodedValue = Encoding.GetEncoding(ContentHeaderProperties.Encoding).GetString(_data); + } + else + { + _decodedValue = Encoding.Default.GetString(_data); + } + return _decodedValue; + } + } + + set + { + if (ContentHeaderProperties.Encoding == null) + { + _data = Encoding.Default.GetBytes(value); + } + else + { + // throw ArgumentException if the encoding is not supported + _data = Encoding.GetEncoding(ContentHeaderProperties.Encoding).GetBytes(value); + } + _decodedValue = value; + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs b/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs new file mode 100644 index 0000000000..5457b2301e --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs @@ -0,0 +1,60 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using Qpid.Framing; + +namespace Qpid.Client.Message +{ + public class QpidTextMessageFactory : AbstractQmsMessageFactory + { + protected override AbstractQmsMessage CreateMessageWithBody(ulong messageNbr, ContentHeaderBody contentHeader, + IList bodies) + { + byte[] data; + + // we optimise the non-fragmented case to avoid copying + if (bodies != null && bodies.Count == 1) + { + data = ((ContentBody)bodies[0]).Payload; + } + else + { + data = new byte[(int)contentHeader.BodySize]; + int currentPosition = 0; + foreach (ContentBody cb in bodies) + { + Array.Copy(cb.Payload, 0, data, currentPosition, cb.Payload.Length); + currentPosition += cb.Payload.Length; + } + } + + return new QpidTextMessage(messageNbr, data, (BasicContentHeaderProperties)contentHeader.Properties); + } + + + public override AbstractQmsMessage CreateMessage() + { + return new QpidTextMessage(); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs b/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs new file mode 100644 index 0000000000..679114d105 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs @@ -0,0 +1,48 @@ +/* + * + * 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. + * + */ +using System; +using log4net; + +namespace Qpid.Client.Message +{ + /// <summary> + /// Raised when a message body is received unexpectedly by the client. This typically occurs when the + /// length of bodies received does not match with the declared length in the content header. + /// </summary> + public class UnexpectedBodyReceivedException : AMQException + { + public UnexpectedBodyReceivedException(ILog logger, string msg, Exception t) + : base(logger, msg, t) + { + } + + public UnexpectedBodyReceivedException(ILog logger, string msg) + : base(logger, msg) + { + } + + public UnexpectedBodyReceivedException(ILog logger, int errorCode, string msg) + : base(logger, errorCode, msg) + { + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs b/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs new file mode 100644 index 0000000000..cb4e64718b --- /dev/null +++ b/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs @@ -0,0 +1,56 @@ +/* + * + * 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. + * + */ +using System.Collections; +using Qpid.Framing; + +namespace Qpid.Client.Message +{ + public class UnprocessedMessage + { + private ulong _bytesReceived = 0; + + public BasicDeliverBody DeliverBody; + public BasicReturnBody BounceBody; + public ushort ChannelId; + public ContentHeaderBody ContentHeader; + + /// <summary> + /// List of ContentBody instances. Due to fragmentation you don't know how big this will be in general + /// </summary> + /// TODO: write and use linked list class + public IList Bodies = new ArrayList(); + + public void ReceiveBody(ContentBody body) + { + Bodies.Add(body); + if (body.Payload != null) + { + _bytesReceived += (uint)body.Payload.Length; + } + } + + public bool IsAllBodyDataReceived() + { + return _bytesReceived == ContentHeader.BodySize; + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs b/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs new file mode 100644 index 0000000000..ab40a83b3e --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs @@ -0,0 +1,75 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using Qpid.Framing; + +namespace Qpid.Client.Protocol +{ + public class AMQMethodEvent + { + private AMQMethodBody _method; + + private ushort _channelId; + + private AMQProtocolSession _protocolSession; + + public AMQMethodEvent(ushort channelId, AMQMethodBody method, AMQProtocolSession protocolSession) + { + _channelId = channelId; + _method = method; + _protocolSession = protocolSession; + } + + public AMQMethodBody Method + { + get + { + return _method; + } + } + + public ushort ChannelId + { + get + { + return _channelId; + } + } + + public AMQProtocolSession ProtocolSession + { + get + { + return _protocolSession; + } + } + + public override String ToString() + { + StringBuilder buf = new StringBuilder("Method event: "); + buf.Append("\nChannel id: ").Append(_channelId); + buf.Append("\nMethod: ").Append(_method); + return buf.ToString(); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs b/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs new file mode 100644 index 0000000000..7256ab9250 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs @@ -0,0 +1,289 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Threading; +using log4net; +using Qpid.Client.Failover; +using Qpid.Client.Protocol.Listener; +using Qpid.Client.State; +using Qpid.Framing; + +namespace Qpid.Client.Protocol +{ + public class AMQProtocolListener : IProtocolListener + { + private static readonly ILog _log = LogManager.GetLogger(typeof(AMQProtocolListener)); + + /** + * We create the failover handler when the session is created since it needs a reference to the IoSession in order + * to be able to send errors during failover back to the client application. The session won't be available in the + * case where we failing over due to a Connection.Redirect message from the broker. + */ + private FailoverHandler _failoverHandler; + + /** + * This flag is used to track whether failover is being attempted. It is used to prevent the application constantly + * attempting failover where it is failing. + */ + internal FailoverState _failoverState = FailoverState.NOT_STARTED; + + internal FailoverState FailoverState + { + get { return _failoverState; } + set { _failoverState = value; } + } + + internal ManualResetEvent FailoverLatch; + + AMQConnection _connection; + AMQStateManager _stateManager; + + public AMQStateManager StateManager + { + get { return _stateManager; } + set { _stateManager = value; } + } + + //private readonly CopyOnWriteArraySet _frameListeners = new CopyOnWriteArraySet(); + private readonly ArrayList _frameListeners = ArrayList.Synchronized(new ArrayList()); + + AMQProtocolSession _protocolSession = null; // FIXME + public AMQProtocolSession ProtocolSession { set { _protocolSession = value; } } // FIXME: can this be fixed? + + + private readonly Object _lock = new Object(); + + public AMQProtocolListener(AMQConnection connection, AMQStateManager stateManager) + { + _connection = connection; + _stateManager = stateManager; + _failoverHandler = new FailoverHandler(connection); + } + + public void OnMessage(IDataBlock message) + { + // Handle incorrect protocol version. + if (message is ProtocolInitiation) + { + string error = String.Format("Protocol mismatch - {0}", message.ToString()); + AMQException e = new AMQProtocolHeaderException(error); + _log.Error("Closing connection because of protocol mismatch", e); + //_protocolSession.CloseProtocolSession(); + _stateManager.Error(e); + return; + } + + AMQFrame frame = (AMQFrame)message; + + if (frame.BodyFrame is AMQMethodBody) + { + if (_log.IsDebugEnabled) + { + _log.Debug("Method frame received: " + frame); + } + AMQMethodEvent evt = new AMQMethodEvent(frame.Channel, (AMQMethodBody)frame.BodyFrame, _protocolSession); + try + { + bool wasAnyoneInterested = false; + lock (_frameListeners.SyncRoot) + { + foreach (IAMQMethodListener listener in _frameListeners) + { + wasAnyoneInterested = listener.MethodReceived(evt) || wasAnyoneInterested; + } + } + if (!wasAnyoneInterested) + { + throw new AMQException("AMQMethodEvent " + evt + " was not processed by any listener."); + } + } + catch (Exception e) + { + foreach (IAMQMethodListener listener in _frameListeners) + { + listener.Error(e); + } + } + } + else if (frame.BodyFrame is ContentHeaderBody) + { + _protocolSession.MessageContentHeaderReceived(frame.Channel, + (ContentHeaderBody)frame.BodyFrame); + } + else if (frame.BodyFrame is ContentBody) + { + _protocolSession.MessageContentBodyReceived(frame.Channel, + (ContentBody)frame.BodyFrame); + } + else if (frame.BodyFrame is HeartbeatBody) + { + _log.Debug("HeartBeat received"); + } + //_connection.BytesReceived(_protocolSession.Channel.ReadBytes); // XXX: is this really useful? + } + + public void OnException(Exception cause) + { + _log.Warn("Protocol Listener received exception", cause); + lock (_lock) + { + if (_failoverState == FailoverState.NOT_STARTED) + { + if (!(cause is AMQUndeliveredException)) + { + WhenClosed(); + } + } + // We reach this point if failover was attempted and failed therefore we need to let the calling app + // know since we cannot recover the situation. + else if (_failoverState == FailoverState.FAILED) + { + // we notify the state manager of the error in case we have any clients waiting on a state + // change. Those "waiters" will be interrupted and can handle the exception + AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); + PropagateExceptionToWaiters(amqe); + _connection.ExceptionReceived(cause); + } + } + } + + /** + * When the broker connection dies we can either get sessionClosed() called or exceptionCaught() followed by + * sessionClosed() depending on whether we were trying to send data at the time of failure. + * + * @param session + * @throws Exception + */ + void WhenClosed() + { + _connection.StopHeartBeatThread(); + + // TODO: Server just closes session with no warning if auth fails. + if (_connection.Closed) + { + _log.Info("Channel closed called by client"); + } + else + { + _log.Info("Channel closed called with failover state currently " + _failoverState); + + // Reconnectablility was introduced here so as not to disturb the client as they have made their intentions + // known through the policy settings. + + if ((_failoverState != FailoverState.IN_PROGRESS) && _connection.IsFailoverAllowed) + { + _log.Info("FAILOVER STARTING"); + if (_failoverState == FailoverState.NOT_STARTED) + { + _failoverState = FailoverState.IN_PROGRESS; + startFailoverThread(); + } + else + { + _log.Info("Not starting failover as state currently " + _failoverState); + } + } + else + { + _log.Info("Failover not allowed by policy."); + + if (_failoverState != FailoverState.IN_PROGRESS) + { + _log.Info("sessionClose() not allowed to failover"); + _connection.ExceptionReceived( + new AMQDisconnectedException("Server closed connection and reconnection not permitted.")); + } + else + { + _log.Info("sessionClose() failover in progress"); + } + } + } + + _log.Info("Protocol Channel [" + this + "] closed"); + } + + /// <summary> + /// There are two cases where we have other threads potentially blocking for events to be handled by this + /// class. These are for the state manager (waiting for a state change) or a frame listener (waiting for a + /// particular type of frame to arrive). When an error occurs we need to notify these waiters so that they can + /// react appropriately. + /// + /// <param name="e">the exception to propagate</param> + /// </summary> + public void PropagateExceptionToWaiters(Exception e) + { + // FIXME: not sure if required as StateManager is in _frameListeners. Probably something to do with fail-over. + _stateManager.Error(e); + + foreach (IAMQMethodListener listener in _frameListeners) + { + listener.Error(e); + } + } + + public void AddFrameListener(IAMQMethodListener listener) + { + _frameListeners.Add(listener); + } + + public void RemoveFrameListener(IAMQMethodListener listener) + { + if (_log.IsDebugEnabled) + { + _log.Debug("Removing frame listener: " + listener.ToString()); + } + _frameListeners.Remove(listener); + } + + public void BlockUntilNotFailingOver() + { + if (FailoverLatch != null) + { + FailoverLatch.WaitOne(); + } + } + + /// <summary> + /// "Failover" for redirection. + /// </summary> + /// <param name="host"></param> + /// <param name="port"></param> + public void Failover(string host, int port) + { + _failoverHandler.setHost(host); + _failoverHandler.setPort(port); + // see javadoc for FailoverHandler to see rationale for separate thread + startFailoverThread(); + } + + private void startFailoverThread() + { + Thread failoverThread = new Thread(new ThreadStart(_failoverHandler.Run)); + failoverThread.Name = "Failover"; + // Do not inherit daemon-ness from current thread as this can be a daemon + // thread such as a AnonymousIoService thread. + failoverThread.IsBackground = false; + failoverThread.Start(); + } + } +} diff --git a/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs b/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs new file mode 100644 index 0000000000..65aca0d942 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs @@ -0,0 +1,269 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using log4net; +using Qpid.Client.Message; +using Qpid.Client.Transport; +using Qpid.Framing; + +namespace Qpid.Client.Protocol +{ + public class AMQProtocolSession + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(AMQProtocolSession)); + + private readonly IProtocolWriter _protocolWriter; + private readonly IConnectionCloser _connectionCloser; + + /** + * Counter to ensure unique queue names + */ + private int _queueId = 1; + private readonly Object _queueIdLock = new Object(); + + /// <summary> + /// Maps from the channel id to the AmqChannel that it represents. + /// </summary> + //private ConcurrentMap _channelId2SessionMap = new ConcurrentHashMap(); + private Hashtable _channelId2SessionMap = Hashtable.Synchronized(new Hashtable()); + + //private ConcurrentMap _closingChannels = new ConcurrentHashMap(); + private Hashtable _closingChannels = Hashtable.Synchronized(new Hashtable()); + + /// <summary> + /// Maps from a channel id to an unprocessed message. This is used to tie together the + /// JmsDeliverBody (which arrives first) with the subsequent content header and content bodies. + /// </summary> + //private ConcurrentMap _channelId2UnprocessedMsgMap = new ConcurrentHashMap(); + private Hashtable _channelId2UnprocessedMsgMap = Hashtable.Synchronized(new Hashtable()); + + private AMQConnection _connection; + + public AMQProtocolSession(IProtocolWriter protocolWriter, IConnectionCloser connectionCloser, AMQConnection connection) + { + _protocolWriter = protocolWriter; + _connectionCloser = connectionCloser; + _connection = connection; + } + + public void Init() + { + // start the process of setting up the connection. This is the first place that + // data is written to the server. + _protocolWriter.Write(new ProtocolInitiation()); + } + + public string Username + { + get + { + return AMQConnection.Username; + } + } + + public string Password + { + get + { + return AMQConnection.Password; + } + } + + ConnectionTuneParameters _connectionTuneParameters; // TODO: should be able to have this in the Java too. + + public ConnectionTuneParameters ConnectionTuneParameters + { + get + { + return _connectionTuneParameters; + } + set + { + _connectionTuneParameters = value; + AMQConnection con = AMQConnection; + con.SetMaximumChannelCount(value.ChannelMax); + con.MaximumFrameSize = value.FrameMax; + } + } + + /// <summary> + /// Callback invoked from the BasicDeliverMethodHandler when a message has been received. + /// This is invoked on the MINA dispatcher thread. + /// </summary> + /// <param name="message">the unprocessed message</param> + /// <exception cname="AMQException">if this was not expected</exception> + public void UnprocessedMessageReceived(UnprocessedMessage message) + { + _channelId2UnprocessedMsgMap[message.ChannelId] = message; + } + + public void MessageContentHeaderReceived(ushort channelId, ContentHeaderBody contentHeader) + { + UnprocessedMessage msg = (UnprocessedMessage) _channelId2UnprocessedMsgMap[channelId]; + if (msg == null) + { + throw new AMQException("Error: received content header without having received a JMSDeliver frame first"); + } + if (msg.ContentHeader != null) + { + throw new AMQException("Error: received duplicate content header or did not receive correct number of content body frames"); + } + msg.ContentHeader = contentHeader; + if (contentHeader.BodySize == 0) + { + DeliverMessageToAMQSession(channelId, msg); + } + } + + public void MessageContentBodyReceived(ushort channelId, ContentBody contentBody) + { + UnprocessedMessage msg = (UnprocessedMessage) _channelId2UnprocessedMsgMap[channelId]; + if (msg == null) + { + throw new AMQException("Error: received content body without having received a BasicDeliver frame first"); + } + if (msg.ContentHeader == null) + { + _channelId2UnprocessedMsgMap.Remove(channelId); + throw new AMQException("Error: received content body without having received a ContentHeader frame first"); + } + try + { + msg.ReceiveBody(contentBody); + } + catch (UnexpectedBodyReceivedException e) + { + _channelId2UnprocessedMsgMap.Remove(channelId); + throw e; + } + if (msg.IsAllBodyDataReceived()) + { + DeliverMessageToAMQSession(channelId, msg); + } + } + + /// <summary> + /// Deliver a message to the appropriate session, removing the unprocessed message + /// from our map + /// <param name="channelId">the channel id the message should be delivered to</param> + /// <param name="msg"> the message</param> + private void DeliverMessageToAMQSession(ushort channelId, UnprocessedMessage msg) + { + AmqChannel channel = (AmqChannel) _channelId2SessionMap[channelId]; + channel.MessageReceived(msg); + _channelId2UnprocessedMsgMap.Remove(channelId); + } + + /// <summary> + /// Convenience method that writes a frame to the protocol session. Equivalent + /// to calling getProtocolSession().write(). + /// </summary> + /// <param name="frame">the frame to write</param> + public void WriteFrame(IDataBlock frame) + { + _protocolWriter.Write(frame); + } + + public void AddSessionByChannel(ushort channelId, AmqChannel channel) + { + if (channel == null) + { + throw new ArgumentNullException("Attempt to register a null channel"); + } + _logger.Debug("Add channel with channel id " + channelId); + _channelId2SessionMap[channelId] = channel; + } + + public void RemoveSessionByChannel(ushort channelId) + { + _logger.Debug("Removing session with channelId " + channelId); + _channelId2SessionMap.Remove(channelId); + } + + /// <summary> + /// Starts the process of closing a channel + /// </summary> + /// <param name="channel" the AmqChannel being closed</param> + public void CloseSession(AmqChannel channel) + { + _logger.Debug("closeSession called on protocol channel for channel " + channel.ChannelId); + ushort channelId = channel.ChannelId; + + // we need to know when a channel is closing so that we can respond + // with a channel.close frame when we receive any other type of frame + // on that channel + _closingChannels[channelId] = channel; + + } + + /// <summary> + /// Called from the ChannelClose handler when a channel close frame is received. + /// This method decides whether this is a response or an initiation. The latter + /// case causes the AmqChannel to be closed and an exception to be thrown if + /// appropriate. + /// </summary> + /// <param name="channelId">the id of the channel (session)</param> + /// <returns>true if the client must respond to the server, i.e. if the server + /// initiated the channel close, false if the channel close is just the server + /// responding to the client's earlier request to close the channel.</returns> + public bool ChannelClosed(ushort channelId, int code, string text) + { + // if this is not a response to an earlier request to close the channel + if (!_closingChannels.ContainsKey(channelId)) + { + _closingChannels.Remove(channelId); + AmqChannel channel = (AmqChannel) _channelId2SessionMap[channelId]; + channel.Closed(new AMQException(_logger, code, text)); + return true; + } + else + { + return false; + } + } + + public AMQConnection AMQConnection + { + get + { + return _connection; + } + } + + public void CloseProtocolSession() + { + _logger.Debug("Closing protocol session"); + _connectionCloser.Close(); + } + + internal string GenerateQueueName() + { + int id; + lock(_queueIdLock) + { + id = _queueId++; + } + + return "tmp_" + _connection.Transport.getLocalEndPoint() + "_" + id; + } + } +} diff --git a/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs b/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs new file mode 100644 index 0000000000..be8a24a9f4 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs @@ -0,0 +1,27 @@ +/* + * + * 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. + * + */ +namespace Qpid.Client.Protocol +{ + public interface IConnectionCloser + { + void Close(); + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs b/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs new file mode 100644 index 0000000000..6ac8a7537e --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Client.Protocol.Listener; +using Qpid.Framing; + +namespace Qpid.Client.Protocol +{ + public interface IProtocolListener + { + void OnMessage(IDataBlock message); + void OnException(Exception e); + + // XXX: .NET way of doing listeners? + void AddFrameListener(IAMQMethodListener listener); + void RemoveFrameListener(IAMQMethodListener listener); + } +} diff --git a/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs b/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs new file mode 100644 index 0000000000..99643fe59f --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs @@ -0,0 +1,109 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using Qpid.Framing; + +namespace Qpid.Client.Protocol.Listener +{ + public abstract class BlockingMethodFrameListener : IAMQMethodListener + { + private ManualResetEvent _resetEvent; + + public abstract bool ProcessMethod(ushort channelId, AMQMethodBody frame); + + /// <summary> + /// This is set if there is an exception thrown from processCommandFrame and the + /// exception is rethrown to the caller of blockForFrame() + /// </summary> + private volatile Exception _error; + + protected ushort _channelId; + + protected AMQMethodEvent _doneEvt = null; + + public BlockingMethodFrameListener(ushort channelId) + { + _channelId = channelId; + _resetEvent = new ManualResetEvent(false); + } + + /// <summary> + /// This method is called by the MINA dispatching thread. Note that it could + /// be called before BlockForFrame() has been called. + /// </summary> + /// <param name="evt">the frame event</param> + /// <returns>true if the listener has dealt with this frame</returns> + /// <exception cref="AMQException"></exception> + public bool MethodReceived(AMQMethodEvent evt) + { + AMQMethodBody method = evt.Method; + + try + { + bool ready = (evt.ChannelId == _channelId) && ProcessMethod(evt.ChannelId, method); + if (ready) + { + _doneEvt = evt; + _resetEvent.Set(); + } + + return ready; + } + catch (AMQException e) + { + Error(e); + // we rethrow the error here, and the code in the frame dispatcher will go round + // each listener informing them that an exception has been thrown + throw e; + } + } + + /// <summary> + /// This method is called by the thread that wants to wait for a frame. + /// </summary> + public AMQMethodEvent BlockForFrame() + { + _resetEvent.WaitOne(); + //at this point the event will have been signalled. The error field might or might not be set + // depending on whether an error occurred + if (_error != null) + { + throw _error; + } + + return _doneEvt; + } + + /// <summary> + /// This is a callback, called by the MINA dispatcher thread only. It is also called from within this + /// class to avoid code repetition but again is only called by the MINA dispatcher thread. + /// </summary> + /// <param name="e">the exception that caused the error</param> + public void Error(Exception e) + { + // set the error so that the thread that is blocking (in BlockForFrame()) + // can pick up the exception and rethrow to the caller + _error = e; + _resetEvent.Set(); + } + } +} diff --git a/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs b/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs new file mode 100644 index 0000000000..db82eb1013 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs @@ -0,0 +1,45 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.Protocol.Listener +{ + public interface IAMQMethodListener + { + /// <summary> + /// Invoked when a method frame has been received + /// <param name="evt">the event</param> + /// <returns>true if the handler has processed the method frame, false otherwise. Note + /// that this does not prohibit the method event being delivered to subsequent listeners + /// but can be used to determine if nobody has dealt with an incoming method frame.</param> + /// <exception cname="AMQException">if an error has occurred. This exception will be delivered + /// to all registered listeners using the error() method (see below) allowing them to + /// perform cleanup if necessary.</exception> + bool MethodReceived(AMQMethodEvent evt); + + /// <summary> + /// Callback when an error has occurred. Allows listeners to clean up. + /// </summary> + /// <param name="e">the exception</param> + void Error(Exception e); + } +} + diff --git a/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs b/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs new file mode 100644 index 0000000000..65460a0c2e --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Framing; + +namespace Qpid.Client.Protocol.Listener +{ + public class SpecificMethodFrameListener : BlockingMethodFrameListener + { + private readonly Type _expectedClass; + + public SpecificMethodFrameListener(ushort channelId, Type expectedClass) : base(channelId) + { + _expectedClass = expectedClass; + } + + public override bool ProcessMethod(ushort channelId, AMQMethodBody frame) + { + return _expectedClass.IsInstanceOfType(frame); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs b/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs new file mode 100644 index 0000000000..32847f9b9b --- /dev/null +++ b/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs @@ -0,0 +1,78 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Client.Protocol.Listener; +using Qpid.Client.Transport; +using Qpid.Framing; + +namespace Qpid.Client.Protocol +{ + /// <summary> + /// A convenient interface to writing protocol frames. + /// </summary> + public class ProtocolWriter + { + IProtocolWriter _protocolWriter; + IProtocolListener _protocolListener; + + public ProtocolWriter(IProtocolWriter protocolWriter, IProtocolListener protocolListener) + { + _protocolWriter = protocolWriter; + _protocolListener = protocolListener; + } + + public void WriteFrame(IDataBlock frame) + { + _protocolWriter.Write(frame); + } + + /// <summary> + /// Convenience method that writes a frame to the protocol session and waits for + /// a particular response. Equivalent to calling getProtocolSession().write() then + /// waiting for the response. + /// </summary> + /// <param name="frame">the frame</param> + /// <param name="listener">the blocking listener. Note the calling thread will block.</param> + private AMQMethodEvent SyncWrite(AMQFrame frame, BlockingMethodFrameListener listener) + { + try + { + _protocolListener.AddFrameListener(listener); + _protocolWriter.Write(frame); + return listener.BlockForFrame(); + } + finally + { + _protocolListener.RemoveFrameListener(listener); + } + // When control resumes before this line, a reply will have been received + // that matches the criteria defined in the blocking listener + } + + public AMQMethodEvent SyncWrite(AMQFrame frame, Type responseType) + { + // TODO: If each frame knew it's response type, then the responseType argument would + // TODO: not be neccesary. + return SyncWrite(frame, new SpecificMethodFrameListener(frame.Channel, responseType)); + } + } +} + diff --git a/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs b/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs new file mode 100644 index 0000000000..f0c4c91db8 --- /dev/null +++ b/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs @@ -0,0 +1,142 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Net; +using log4net; +using Qpid.Client.qms; + +namespace Qpid.Client +{ + public class QpidConnectionInfo : ConnectionInfo + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(QpidConnectionInfo)); + + string _username = "guest"; + string _password = "guest"; + string _virtualHost = "/default"; + + string _failoverMethod = null; + IDictionary _failoverOptions = new Hashtable(); + IDictionary _options = new Hashtable(); + IList _brokerInfos = new ArrayList(); // List<BrokerInfo> + string _clientName = String.Format("{0}{1:G}", Dns.GetHostName(), DateTime.Now.Ticks); + + public string asUrl() + { + string result = "amqp://"; + foreach (BrokerInfo info in _brokerInfos) + { + result += info.ToString(); + } + return result; + + } + + public string getFailoverMethod() + { + return _failoverMethod; + } + + public string getFailoverOption(string key) + { + return (string) _failoverOptions[key]; + } + + public int getBrokerCount() + { + return _brokerInfos.Count; + } + + public BrokerInfo GetBrokerDetails(int index) + { + return (BrokerInfo)_brokerInfos[index]; + } + + public void AddBrokerInfo(BrokerInfo brokerInfo) + { + if (!_brokerInfos.Contains(brokerInfo)) + { + _brokerInfos.Add(brokerInfo); + } + } + + public IList GetAllBrokerInfos() + { + return _brokerInfos; + } + + public string GetClientName() + { + return _clientName; + } + + public void SetClientName(string clientName) + { + _clientName = clientName; + } + + public string getUsername() + { + return _username; + } + + public void setUsername(string username) + { + _username = username; + } + + public string getPassword() + { + return _password; + } + + public void setPassword(string password) + { + _password = password; + } + + public string getVirtualHost() + { + return _virtualHost; + } + + public void setVirtualHost(string virtualHost) + { + _virtualHost = virtualHost; + } + + public string getOption(string key) + { + return (string) _options[key]; + } + + public void setOption(string key, string value) + { + _options[key] = value; + } + + public override string ToString() + { + return asUrl(); + } + } +} diff --git a/dotnet/Qpid.Client/Client/State/AMQState.cs b/dotnet/Qpid.Client/Client/State/AMQState.cs new file mode 100644 index 0000000000..fc71fe647c --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/AMQState.cs @@ -0,0 +1,34 @@ +/* + * + * 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. + * + */ +namespace Qpid.Client.State +{ + public enum AMQState + { + CONNECTION_NOT_STARTED, + CONNECTION_NOT_TUNED, + CONNECTION_NOT_OPENED, + CONNECTION_OPEN, + CONNECTION_CLOSING, + CONNECTION_CLOSED, + ALL // all is a special state used in the state manager. It is not valid to be "in" the state "all". + } +} + diff --git a/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs b/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs new file mode 100644 index 0000000000..60d44da824 --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ +namespace Qpid.Client.State +{ + public class AMQStateChangedEvent + { + private readonly AMQState _oldState; + + private readonly AMQState _newState; + + public AMQStateChangedEvent(AMQState oldState, AMQState newState) + { + _oldState = oldState; + _newState = newState; + } + + public AMQState OldState + { + get + { + return _oldState; + } + } + + public AMQState NewState + { + get + { + return _newState; + } + } + + } +} diff --git a/dotnet/Qpid.Client/Client/State/AMQStateManager.cs b/dotnet/Qpid.Client/Client/State/AMQStateManager.cs new file mode 100644 index 0000000000..05f673d520 --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/AMQStateManager.cs @@ -0,0 +1,225 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using log4net; +using Qpid.Client.Handler; +using Qpid.Client.Protocol; +using Qpid.Client.Protocol.Listener; +using Qpid.Framing; + +namespace Qpid.Client.State +{ + public class AMQStateManager : IAMQMethodListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(AMQStateManager)); + + const bool InfoLoggingHack = true; + + /// <summary> + /// The current state + /// </summary> + private AMQState _currentState; + + /// <summary> + /// Maps from an AMQState instance to a Map from Class to StateTransitionHandler. + /// The class must be a subclass of AMQFrame. + /// </summary> + private readonly IDictionary _state2HandlersMap = new Hashtable(); + + //private CopyOnWriteArraySet _stateListeners = new CopyOnWriteArraySet(); + private ArrayList _stateListeners = ArrayList.Synchronized(new ArrayList(5)); + + public AMQStateManager() + { + _currentState = AMQState.CONNECTION_NOT_STARTED; + RegisterListeners(); + } + + private void RegisterListeners() + { + IStateAwareMethodListener connectionStart = new ConnectionStartMethodHandler(); + IStateAwareMethodListener connectionClose = new ConnectionCloseMethodHandler(); + IStateAwareMethodListener connectionCloseOk = new ConnectionCloseOkHandler(); + IStateAwareMethodListener connectionTune = new ConnectionTuneMethodHandler(); + IStateAwareMethodListener connectionSecure = new ConnectionSecureMethodHandler(); + IStateAwareMethodListener connectionOpenOk = new ConnectionOpenOkMethodHandler(); + IStateAwareMethodListener channelClose = new ChannelCloseMethodHandler(); + IStateAwareMethodListener basicDeliver = new BasicDeliverMethodHandler(); + IStateAwareMethodListener basicReturn = new BasicReturnMethodHandler(); + + // We need to register a map for the null (i.e. all state) handlers otherwise you get + // a stack overflow in the handler searching code when you present it with a frame for which + // no handlers are registered. + _state2HandlersMap[AMQState.ALL] = new Hashtable(); + + { + Hashtable notStarted = new Hashtable(); + notStarted[typeof(ConnectionStartBody)] = connectionStart; + notStarted[typeof(ConnectionCloseBody)] = connectionClose; + _state2HandlersMap[AMQState.CONNECTION_NOT_STARTED] = notStarted; + } + { + Hashtable notTuned = new Hashtable(); + notTuned[typeof(ConnectionTuneBody)] = connectionTune; + notTuned[typeof(ConnectionSecureBody)] = connectionSecure; + notTuned[typeof(ConnectionCloseBody)] = connectionClose; + _state2HandlersMap[AMQState.CONNECTION_NOT_TUNED] = notTuned; + } + { + Hashtable notOpened = new Hashtable(); + notOpened[typeof(ConnectionOpenOkBody)] = connectionOpenOk; + notOpened[typeof(ConnectionCloseBody)] = connectionClose; + _state2HandlersMap[AMQState.CONNECTION_NOT_OPENED] = notOpened; + } + { + Hashtable open = new Hashtable(); + open[typeof(ChannelCloseBody)] = channelClose; + open[typeof(ConnectionCloseBody)] = connectionClose; + open[typeof(BasicDeliverBody)] = basicDeliver; + open[typeof(BasicReturnBody)] = basicReturn; + _state2HandlersMap[AMQState.CONNECTION_OPEN] = open; + } + { + Hashtable closing = new Hashtable(); + closing[typeof(ConnectionCloseOkBody)] = connectionCloseOk; + _state2HandlersMap[AMQState.CONNECTION_CLOSING] = closing; + } + } + + public AMQState CurrentState + { + get + { + return _currentState; + } + } + + /// <summary> + /// Changes the state. + /// </summary> + /// <param name="newState">The new state.</param> + /// <exception cref="AMQException">if there is an error changing state</exception> + public void ChangeState(AMQState newState) + { + if (InfoLoggingHack) + { + _logger.Info("State changing to " + newState + " from old state " + _currentState); + } + _logger.Debug("State changing to " + newState + " from old state " + _currentState); + AMQState oldState = _currentState; + _currentState = newState; + + foreach (IStateListener l in _stateListeners) + { + l.StateChanged(oldState, newState); + } + } + + public void Error(Exception e) + { + _logger.Debug("State manager receive error notification: " + e); + foreach (IStateListener l in _stateListeners) + { + l.Error(e); + } + } + + public bool MethodReceived(AMQMethodEvent evt) + { + _logger.Debug(String.Format("Finding method handler. currentState={0} type={1}", _currentState, evt.Method.GetType())); + IStateAwareMethodListener handler = FindStateTransitionHandler(_currentState, evt.Method); + if (handler != null) + { + handler.MethodReceived(this, evt); + return true; + } + return false; + } + + /// <summary> + /// Finds the state transition handler. + /// </summary> + /// <param name="currentState">State of the current.</param> + /// <param name="frame">The frame.</param> + /// <returns></returns> + /// <exception cref="IllegalStateTransitionException">if the state transition if not allowed</exception> + private IStateAwareMethodListener FindStateTransitionHandler(AMQState currentState, + AMQMethodBody frame) + { + Type clazz = frame.GetType(); + if (_logger.IsDebugEnabled) + { + _logger.Debug("Looking for state transition handler for frame " + clazz); + } + IDictionary classToHandlerMap = (IDictionary) _state2HandlersMap[currentState]; + + if (classToHandlerMap == null) + { + // if no specialised per state handler is registered look for a + // handler registered for "all" states + return FindStateTransitionHandler(AMQState.ALL, frame); + } + IStateAwareMethodListener handler = (IStateAwareMethodListener) classToHandlerMap[clazz]; + if (handler == null) + { + if (currentState == AMQState.ALL) + { + _logger.Debug("No state transition handler defined for receiving frame " + frame); + return null; + } + else + { + // if no specialised per state handler is registered look for a + // handler registered for "all" states + return FindStateTransitionHandler(AMQState.ALL, frame); + } + } + else + { + return handler; + } + } + + public void AddStateListener(IStateListener listener) + { + _logger.Debug("Adding state listener"); + _stateListeners.Add(listener); + } + + public void RemoveStateListener(IStateListener listener) + { + _stateListeners.Remove(listener); + } + + public void AttainState(AMQState s) + { + if (_currentState != s) + { + _logger.Debug("Adding state wait to reach state " + s); + StateWaiter sw = new StateWaiter(s); + AddStateListener(sw); + sw.WaituntilStateHasChanged(); + // at this point the state will have changed. + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs b/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs new file mode 100644 index 0000000000..ff27cd841e --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs @@ -0,0 +1,28 @@ +/* + * + * 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. + * + */ +namespace Qpid.Client.State +{ + public interface IAMQStateListener + { + void StateChanged(AMQStateChangedEvent evt); + } +} + diff --git a/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs b/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs new file mode 100644 index 0000000000..256fe1c3f3 --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs @@ -0,0 +1,30 @@ +/* + * + * 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. + * + */ +using Qpid.Client.Protocol; + +namespace Qpid.Client.State +{ + public interface IStateAwareMethodListener + { + void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt); + } +} + diff --git a/dotnet/Qpid.Client/Client/State/IStateListener.cs b/dotnet/Qpid.Client/Client/State/IStateListener.cs new file mode 100644 index 0000000000..6073b2bb0c --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/IStateListener.cs @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.State +{ + public interface IStateListener + { + void StateChanged(AMQState oldState, AMQState newState); + + void Error(Exception e); + } +} + diff --git a/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs b/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs new file mode 100644 index 0000000000..723ae04397 --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs @@ -0,0 +1,56 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.State +{ + public class IllegalStateTransitionException : AMQException + { + private AMQState _originalState; + + private Type _frame; + + public IllegalStateTransitionException(AMQState originalState, Type frame) + : base("No valid state transition defined for receiving frame " + frame + + " from state " + originalState) + { + _originalState = originalState; + _frame = frame; + } + + public AMQState OriginalState + { + get + { + return _originalState; + } + } + + public Type FrameType + { + get + { + return _frame; + } + } + } +} + diff --git a/dotnet/Qpid.Client/Client/State/StateWaiter.cs b/dotnet/Qpid.Client/Client/State/StateWaiter.cs new file mode 100644 index 0000000000..cb7f604499 --- /dev/null +++ b/dotnet/Qpid.Client/Client/State/StateWaiter.cs @@ -0,0 +1,99 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; +using log4net; + +namespace Qpid.Client.State +{ + public class StateWaiter : IStateListener + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(StateWaiter)); + + private readonly AMQState _state; + + private volatile bool _newStateAchieved; + + private volatile Exception _exception; + + private ManualResetEvent _resetEvent = new ManualResetEvent(false); + + public StateWaiter(AMQState state) + { + _state = state; + } + + public void StateChanged(AMQState oldState, AMQState newState) + { + if (_logger.IsDebugEnabled) + { + _logger.Debug("stateChanged called"); + } + if (_state == newState) + { + _newStateAchieved = true; + + if (_logger.IsDebugEnabled) + { + _logger.Debug("New state reached so notifying monitor"); + } + _resetEvent.Set(); + } + } + + public void Error(Exception e) + { + if (_logger.IsDebugEnabled) + { + _logger.Debug("exceptionThrown called"); + } + + _exception = e; + _resetEvent.Set(); + } + + public void WaituntilStateHasChanged() + { + // + // The guard is required in case we are woken up by a spurious + // notify(). + // + while (!_newStateAchieved && _exception == null) + { + _logger.Debug("State not achieved so waiting..."); + _resetEvent.WaitOne(); + } + + if (_exception != null) + { + _logger.Debug("Throwable reached state waiter: " + _exception); + if (_exception is AMQException) + { + throw _exception; + } + else + { + throw new AMQException("Error: " + _exception, _exception); + } + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs b/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs new file mode 100644 index 0000000000..1024fa5575 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs @@ -0,0 +1,47 @@ +/* + * + * 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. + * + */ +using Qpid.Codec; +using Qpid.Codec.Demux; +using Qpid.Framing; + +namespace Qpid.Client.Transport +{ + public class AMQProtocolProvider + { + private DemuxingProtocolCodecFactory _factory; + + public AMQProtocolProvider() + { + _factory = new DemuxingProtocolCodecFactory(); + _factory.Register(new AMQDataBlockEncoder()); + _factory.Register(new AMQDataBlockDecoder()); + _factory.Register(new ProtocolInitiation.Decoder()); + } + + public IProtocolCodecFactory CodecFactory + { + get + { + return _factory; + } + } + } +} diff --git a/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs b/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs new file mode 100644 index 0000000000..d3add546fe --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs @@ -0,0 +1,94 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using log4net; +using Qpid.Buffer; +using Qpid.Codec; +using Qpid.Codec.Support; +using Qpid.Framing; + +namespace Qpid.Client.Transport +{ + public class AmqpChannel : IProtocolChannel + { + // Warning: don't use this log for regular logging. + static readonly ILog _protocolTraceLog = LogManager.GetLogger("Qpid.Client.ProtocolChannel.Tracing"); + + IByteChannel byteChannel; + IProtocolEncoder encoder; + IProtocolDecoder decoder; + + public AmqpChannel(IByteChannel byteChannel) + { + this.byteChannel = byteChannel; + + AMQProtocolProvider protocolProvider = new AMQProtocolProvider(); + IProtocolCodecFactory factory = protocolProvider.CodecFactory; + encoder = factory.Encoder; + decoder = factory.Decoder; + } + + public Queue Read() + { + ByteBuffer buffer = byteChannel.Read(); + + Queue frames = Decode(buffer); + + // TODO: Refactor to decorator. + if (_protocolTraceLog.IsDebugEnabled) + { + foreach (object o in frames) + { + _protocolTraceLog.Debug(String.Format("READ {0}", o)); + } + } + + return frames; + } + + public void Write(IDataBlock o) + { + // TODO: Refactor to decorator. + if (_protocolTraceLog.IsDebugEnabled) + { + _protocolTraceLog.Debug(String.Format("WRITE {0}", o)); + } + + byteChannel.Write(Encode(o)); + } + + private ByteBuffer Encode(object o) + { + SingleProtocolEncoderOutput output = new SingleProtocolEncoderOutput(); + encoder.Encode(o, output); + return output.buffer; + } + + private Queue Decode(ByteBuffer byteBuffer) + { + SimpleProtocolDecoderOutput outx = new SimpleProtocolDecoderOutput(); + decoder.Decode(byteBuffer, outx); + return outx.MessageQueue; + } + } +} + diff --git a/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs b/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs new file mode 100644 index 0000000000..4a3ff385a8 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs @@ -0,0 +1,30 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Client.Transport +{ + public interface IByteChannel + { + ByteBuffer Read(); + void Write(ByteBuffer buffer); + } +} diff --git a/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs b/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs new file mode 100644 index 0000000000..4943a45d68 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +using System.Collections; + +namespace Qpid.Client.Transport +{ + public interface IProtocolChannel : IProtocolWriter + { + Queue Read(); + } +} diff --git a/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs b/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs new file mode 100644 index 0000000000..ac19977927 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +using Qpid.Framing; + +namespace Qpid.Client.Transport +{ + public interface IProtocolWriter + { + void Write(IDataBlock o); + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/Client/Transport/ITransport.cs b/dotnet/Qpid.Client/Client/Transport/ITransport.cs new file mode 100644 index 0000000000..aebe58b439 --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/ITransport.cs @@ -0,0 +1,31 @@ +/* + * + * 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. + * + */ +using Qpid.Client.Protocol; + +namespace Qpid.Client.Transport +{ + public interface ITransport : IConnectionCloser + { + void Open(); + string getLocalEndPoint(); + IProtocolWriter ProtocolWriter { get; } + } +} diff --git a/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs b/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs new file mode 100644 index 0000000000..5b5392769a --- /dev/null +++ b/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Buffer; +using Qpid.Codec; + +namespace Qpid.Client.Transport +{ + public class SingleProtocolEncoderOutput : IProtocolEncoderOutput + { + public ByteBuffer buffer; + + public void Write(ByteBuffer buf) + { + if (buffer != null) + { + throw new InvalidOperationException("{0} does not allow the writing of more than one buffer"); + } + buffer = buf; + } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/Properties/AssemblyInfo.cs b/dotnet/Qpid.Client/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..0c7da88839 --- /dev/null +++ b/dotnet/Qpid.Client/Properties/AssemblyInfo.cs @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.Client")] +[assembly: AssemblyDescription("Qpid Client API implementation")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("380cb124-07a8-40c2-b67d-69a0d94cb620")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("0.5.*")] diff --git a/dotnet/Qpid.Client/Qpid.Client.csproj b/dotnet/Qpid.Client/Qpid.Client.csproj new file mode 100644 index 0000000000..eb84402e1f --- /dev/null +++ b/dotnet/Qpid.Client/Qpid.Client.csproj @@ -0,0 +1,133 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{68987C05-3768-452C-A6FC-6BA1D372852F}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Client</RootNamespace>
+ <AssemblyName>Qpid.Client</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.0.30714, Culture=neutral, PublicKeyToken=500ffcafb14f92df">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Client\AmqBrokerInfo.cs" />
+ <Compile Include="Client\AMQConnection.cs" />
+ <Compile Include="Client\AMQConnectionException.cs" />
+ <Compile Include="Client\AMQDestination.cs" />
+ <Compile Include="Client\AmqChannel.cs" />
+ <Compile Include="Client\QpidConnectionInfo.cs" />
+ <Compile Include="Client\BasicMessageConsumer.cs" />
+ <Compile Include="Client\BasicMessageProducer.cs" />
+ <Compile Include="Client\Closeable.cs" />
+ <Compile Include="Client\ConnectionTuneParameters.cs" />
+ <Compile Include="Client\Failover\FailoverException.cs" />
+ <Compile Include="Client\Failover\FailoverHandler.cs" />
+ <Compile Include="Client\Failover\FailoverState.cs" />
+ <Compile Include="Client\Failover\FailoverSupport.cs" />
+ <Compile Include="Client\Handler\BasicDeliverMethodHandler.cs" />
+ <Compile Include="Client\Handler\BasicReturnMethodHandler.cs" />
+ <Compile Include="Client\Handler\ChannelCloseMethodHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionCloseMethodHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionCloseOkHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionOpenOkMethodHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionRedirectMethodHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionSecureMethodHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionStartMethodHandler.cs" />
+ <Compile Include="Client\Handler\ConnectionTuneMethodHandler.cs" />
+ <Compile Include="Client\Message\AbstractQmsMessage.cs" />
+ <Compile Include="Client\Message\AMQMessage.cs" />
+ <Compile Include="Client\Message\AMQMessageFactory.cs" />
+ <Compile Include="Client\Message\IMessageFactory.cs" />
+ <Compile Include="Client\Message\MessageFactoryRegistry.cs" />
+ <Compile Include="Client\Message\UnexpectedBodyReceivedException.cs" />
+ <Compile Include="Client\Message\UnprocessedMessage.cs" />
+ <Compile Include="Client\Message\QpidBytesMessage.cs" />
+ <Compile Include="Client\Message\QpidBytesMessageFactory.cs" />
+ <Compile Include="Client\Message\QpidTextMessage.cs" />
+ <Compile Include="Client\Message\QpidTextMessageFactory.cs" />
+ <Compile Include="Client\Protocol\AMQMethodEvent.cs" />
+ <Compile Include="Client\Protocol\AMQProtocolListener.cs" />
+ <Compile Include="Client\Protocol\AMQProtocolSession.cs" />
+ <Compile Include="Client\Protocol\Listener\BlockingMethodFrameListener.cs" />
+ <Compile Include="Client\Protocol\Listener\IAMQMethodListener.cs" />
+ <Compile Include="Client\Protocol\IConnectionCloser.cs" />
+ <Compile Include="Client\Protocol\ProtocolWriter.cs" />
+ <Compile Include="Client\Protocol\IProtocolListener.cs" />
+ <Compile Include="Client\State\AMQState.cs" />
+ <Compile Include="Client\State\AMQStateChangedEvent.cs" />
+ <Compile Include="Client\State\AMQStateManager.cs" />
+ <Compile Include="Client\State\IAMQStateListener.cs" />
+ <Compile Include="Client\State\IllegalStateTransitionException.cs" />
+ <Compile Include="Client\State\IStateAwareMethodListener.cs" />
+ <Compile Include="Client\State\IStateListener.cs" />
+ <Compile Include="Client\Protocol\Listener\SpecificMethodFrameListener.cs" />
+ <Compile Include="Client\State\StateWaiter.cs" />
+ <Compile Include="Client\Transport\AmqpChannel.cs" />
+ <Compile Include="Client\Transport\AMQProtocolProvider.cs" />
+ <Compile Include="Client\Transport\IByteChannel.cs" />
+ <Compile Include="Client\Transport\IProtocolChannel.cs" />
+ <Compile Include="Client\Transport\IProtocolWriter.cs" />
+ <Compile Include="Client\Transport\ITransport.cs" />
+ <Compile Include="Client\Transport\SingleProtocolEncoderOutput.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="qms\BrokerInfo.cs" />
+ <Compile Include="qms\ConnectionInfo.cs" />
+ <Compile Include="qms\FailoverPolicy.cs" />
+ <Compile Include="qms\failover\FailoverMethod.cs" />
+ <Compile Include="qms\failover\FailoverRoundRobin.cs" />
+ <Compile Include="qms\failover\FailoverSingleServer.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Client/default.build b/dotnet/Qpid.Client/default.build new file mode 100644 index 0000000000..00e2854326 --- /dev/null +++ b/dotnet/Qpid.Client/default.build @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<project name="XMS.AMQ.Client" default="build"> + <property name="nant.settings.currentframework" value="net-1.0" /> + <property name="basename" value="XMSClient"/> + <property name="debug" value="true"/> + <property name="CommonCollectionsDir" value="../CommonCollections"/> + <property name="MINADir" value="../minadotnet"/> + <property name="XMSCommonDir" value="../xmscommon"/> + + <if test="${debug}"> + <property name="targetdir" value="bin/${nant.settings.currentframework}/Debug"/> + </if> + <ifnot test="${debug}"> + <property name="targetdir" value="bin/${nant.settings.currentframework}/Release"/> + </ifnot> + + <target name="clean"> + <delete> + <fileset> + <include name="${targetdir}/${basename}.dll"/> + <include name="${targetdir}/${basename}.pdb"/> + </fileset> + </delete> + </target> + + <target name="init"> + <mkdir dir="${targetdir}"/> + </target> + + <target name="build" depends="init"> + <csc target="library" output="${targetdir}/${basename}.dll" debug="${debug}"> + <sources> + <include name="**/*.cs"/> + <exclude name="Properties/Settings.Designer.cs" /> + </sources> + <references> + <lib> + <include name="${CommonCollectionsDir}/${targetdir}" /> + <include name="${MINADir}/${targetdir}" /> + <include name="${XMSCommonDir}/${targetdir}" /> + <include name="${XMSCommonDir}/lib/**" /> + <include name="lib/**" /> + </lib> + <include name="CommonCollections.dll" /> + <include name="log4net.dll" /> + <include name="MINA.dll" /> + <include name="IBM.XMS.dll" /> + <include name="XMSCommon.dll" /> + </references> + </csc> + </target> +</project>
\ No newline at end of file diff --git a/dotnet/Qpid.Client/qms/BrokerInfo.cs b/dotnet/Qpid.Client/qms/BrokerInfo.cs new file mode 100644 index 0000000000..dd0504968e --- /dev/null +++ b/dotnet/Qpid.Client/qms/BrokerInfo.cs @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.qms +{ + /// <summary> + /// Know URL option names. + /// <seealso cref="ConnectionInfo"/> + /// </summary> + public class BrokerDetailsConstants + { + public const String OPTIONS_RETRY = "retries"; + public const String OPTIONS_SSL = ConnectionUrlConstants.OPTIONS_SSL; + public const String OPTIONS_CONNECT_TIMEOUT = "connecttimeout"; + public const int DEFAULT_PORT = 5672; + public const String DEFAULT_TRANSPORT = "tcp"; + + public readonly string URL_FORMAT_EXAMPLE = + "<transport>://<hostname>[:<port Default=\"" + DEFAULT_PORT + "\">][?<option>='<value>'[,<option>='<value>']]"; + + public const long DEFAULT_CONNECT_TIMEOUT = 30000L; + } + + public interface BrokerInfo + { + String getHost(); + void setHost(string host); + + int getPort(); + void setPort(int port); + + String getTransport(); + void setTransport(string transport); + + bool useSSL(); + void useSSL(bool ssl); + + String getOption(string key); + void setOption(string key, string value); + + long getTimeout(); + void setTimeout(long timeout); + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/qms/ConnectionInfo.cs b/dotnet/Qpid.Client/qms/ConnectionInfo.cs new file mode 100644 index 0000000000..1d099daa3e --- /dev/null +++ b/dotnet/Qpid.Client/qms/ConnectionInfo.cs @@ -0,0 +1,76 @@ +/* + * + * 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. + * + */ +using System.Collections; + +namespace Qpid.Client.qms +{ + class ConnectionUrlConstants + { + public const string AMQ_PROTOCOL = "amqp"; + public const string OPTIONS_BROKERLIST = "brokerlist"; + public const string OPTIONS_FAILOVER = "failover"; + public const string OPTIONS_FAILOVER_CYCLE = "cyclecount"; + public const string OPTIONS_SSL = "ssl"; + } + + /** + Connection URL format + amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';vm://:3/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''" + Options are of course optional except for requiring a single broker in the broker list. + The option seperator is defined to be either '&' or ',' + */ + public interface ConnectionInfo + { + string asUrl(); + + string getFailoverMethod(); + + string getFailoverOption(string key); + + int getBrokerCount(); + + BrokerInfo GetBrokerDetails(int index); + + void AddBrokerInfo(BrokerInfo broker); + + IList GetAllBrokerInfos(); + + string GetClientName(); + + void SetClientName(string clientName); + + string getUsername(); + + void setUsername(string username); + + string getPassword(); + + void setPassword(string password); + + string getVirtualHost(); + + void setVirtualHost(string virtualHost); + + string getOption(string key); + + void setOption(string key, string value); + } +} diff --git a/dotnet/Qpid.Client/qms/FailoverPolicy.cs b/dotnet/Qpid.Client/qms/FailoverPolicy.cs new file mode 100644 index 0000000000..15d52491df --- /dev/null +++ b/dotnet/Qpid.Client/qms/FailoverPolicy.cs @@ -0,0 +1,315 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using log4net; +using Qpid.Client.qms.failover; + +namespace Qpid.Client.qms +{ + public class FailoverPolicy + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverPolicy)); + + private const long MINUTE = 60000L; + + private const long DEFAULT_METHOD_TIMEOUT = 1 * MINUTE; + private const long DEFAULT_FAILOVER_TIMEOUT = 4 * MINUTE; + + private FailoverMethod[] _methods = new FailoverMethod[1]; + + private int _currentMethod; + + private int _methodsRetries; + + private int _currentRetry; + + private bool _timing; + + private long _lastMethodTime; + private long _lastFailTime; + + public FailoverPolicy(ConnectionInfo connectionInfo) + { + FailoverMethod method; + + //todo This should be integrated in to the connection url when it supports + // multiple strategies. + + _methodsRetries = 0; + + if (connectionInfo.getFailoverMethod() == null) + { + if (connectionInfo.getBrokerCount() > 1) + { + method = new FailoverRoundRobin(connectionInfo); + } + else + { + method = new FailoverSingleServer(connectionInfo); + } + } + else + { + string failoverMethod = connectionInfo.getFailoverMethod(); + + /* + if (failoverMethod.equals(FailoverMethod.RANDOM)) + { + //todo write a random connection Failover + } + */ + if (failoverMethod.Equals(FailoverMethodConstants.ROUND_ROBIN)) + { + method = new FailoverRoundRobin(connectionInfo); + } + else + { + throw new NotImplementedException("Dynamic loading of FailoverMethods not yet implemented."); +// try +// { +// Type[] constructorSpec = {ConnectionInfo.class}; +// Object [] params = {connectionInfo}; +// +// method = (FailoverMethod) ClassLoader.getSystemClassLoader(). +// loadClass(failoverMethod). +// getConstructor(constructorSpec).newInstance(params); +// } +// catch (Exception cnfe) +// { +// throw new IllegalArgumentException("Unknown failover method:" + failoverMethod); +// } + } + } + + if (method == null) + { + throw new ArgumentException("Unknown failover method specified."); + } + + reset(); + + _methods[_currentMethod] = method; + } + + public FailoverPolicy(FailoverMethod method) : this(method, 0) + { + } + + public FailoverPolicy(FailoverMethod method, int retries) + { + _methodsRetries = retries; + + reset(); + + _methods[_currentMethod] = method; + } + + private void reset() + { + _currentMethod = 0; + _currentRetry = 0; + _timing = false; + + } + + public bool FailoverAllowed() + { + bool failoverAllowed; + + if (_timing) + { + long now = CurrentTimeMilliseconds(); + + if ((now - _lastMethodTime) >= DEFAULT_METHOD_TIMEOUT) + { + _logger.Info("Failover method timeout"); + _lastMethodTime = now; + + if (!nextMethod()) + { + return false; + } + + + } + else if ((now - _lastFailTime) >= DEFAULT_FAILOVER_TIMEOUT) + { + _logger.Info("Failover timeout"); + return false; + } + else + { + _lastMethodTime = now; + } + } + else + { + _timing = true; + _lastMethodTime = CurrentTimeMilliseconds(); + _lastFailTime = _lastMethodTime; + } + + + if (_methods[_currentMethod].failoverAllowed()) + { + failoverAllowed = true; + } + else + { + if (_currentMethod < (_methods.Length - 1)) + { + nextMethod(); + _logger.Info("Changing method to " + _methods[_currentMethod].methodName()); + return FailoverAllowed(); + } + else + { + return cycleMethods(); + } + } + + return failoverAllowed; + } + + private static long CurrentTimeMilliseconds() + { + return DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; + } + + private bool nextMethod() + { + if (_currentMethod < (_methods.Length - 1)) + { + _currentMethod++; + _methods[_currentMethod].reset(); + return true; + } + else + { + return cycleMethods(); + } + } + + private bool cycleMethods() + { + if (_currentRetry < _methodsRetries) + { + _currentRetry++; + + _currentMethod = 0; + + _logger.Info("Retrying methods starting with " + _methods[_currentMethod].methodName()); + _methods[_currentMethod].reset(); + return FailoverAllowed(); + } + else + { + _logger.Debug("All failover methods exhausted"); + return false; + } + } + + /** + * Notification that connection was successful. + */ + public void attainedConnection() + { + _currentRetry = 0; + + _methods[_currentMethod].attainedConnection(); + + _timing = false; + } + + public BrokerInfo GetCurrentBrokerInfo() + { + return _methods[_currentMethod].GetCurrentBrokerInfo(); + } + + public BrokerInfo GetNextBrokerInfo() + { + return _methods[_currentMethod].getNextBrokerDetails(); + } + + public void setBroker(BrokerInfo broker) + { + _methods[_currentMethod].setBroker(broker); + } + + public void addMethod(FailoverMethod method) + { + int len = _methods.Length + 1; + FailoverMethod[] newMethods = new FailoverMethod[len]; + _methods.CopyTo(newMethods, 0); +// System.arraycopy(_methods, 0, newMethods, 0, _methods.length); + int index = len - 1; + newMethods[index] = method; + _methods = newMethods; + } + + public void setMethodRetries(int retries) + { + _methodsRetries = retries; + } + + public FailoverMethod getCurrentMethod() + { + if (_currentMethod >= 0 && _currentMethod < (_methods.Length - 1)) + { + return _methods[_currentMethod]; + } + else + { + return null; + } + } + + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append("Failover Policy:\n"); + + if (FailoverAllowed()) + { + sb.Append("Failover allowed\n"); + } + else + { + sb.Append("Failover not allowed\n"); + } + + sb.Append("Failover policy methods\n"); + for (int i = 0; i < _methods.Length; i++) + { + + if (i == _currentMethod) + { + sb.Append(">"); + } + sb.Append(_methods[i].ToString()); + } + + return sb.ToString(); + } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs b/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs new file mode 100644 index 0000000000..7db9ef32fa --- /dev/null +++ b/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs @@ -0,0 +1,79 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.qms.failover +{ + public class FailoverMethodConstants + { + public const String ROUND_ROBIN = "roundrobin"; + public const String RANDOM = "random"; + } + + public interface FailoverMethod + { + /** + * Reset the Failover to initial conditions + */ + void reset(); + + /** + * Check if failover is possible for this method + * + * @return true if failover is allowed + */ + bool failoverAllowed(); + + /** + * Notification to the Failover method that a connection has been attained. + */ + void attainedConnection(); + + /** + * If there is no current BrokerInfo the null will be returned. + * @return The current BrokerDetail value to use + */ + BrokerInfo GetCurrentBrokerInfo(); + + /** + * Move to the next BrokerInfo if one is available. + * @return the next BrokerDetail or null if there is none. + */ + BrokerInfo getNextBrokerDetails(); + + /** + * Set the currently active broker to be the new value. + * @param broker The new BrokerDetail value + */ + void setBroker(BrokerInfo broker); + + /** + * Set the retries for this method + * @param maxRetries the maximum number of time to retry this Method + */ + void setRetries(int maxRetries); + + /** + * @return The name of this method for display purposes. + */ + String methodName(); + } +} diff --git a/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs b/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs new file mode 100644 index 0000000000..c0e832ce21 --- /dev/null +++ b/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs @@ -0,0 +1,255 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using log4net; + +namespace Qpid.Client.qms.failover +{ + public class FailoverRoundRobin : FailoverMethod + { + private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverRoundRobin)); + + /** The default number of times to cycle through all servers */ + public const int DEFAULT_CYCLE_RETRIES = 0; + /** The default number of times to retry each server */ + public const int DEFAULT_SERVER_RETRIES = 0; + + /** + * The index into the hostDetails array of the broker to which we are connected + */ + private int _currentBrokerIndex = -1; + + /** + * The number of times to retry connecting for each server + */ + private int _serverRetries; + + /** + * The current number of retry attempts made + */ + private int _currentServerRetry; + + /** + * The number of times to cycle through the servers + */ + private int _cycleRetries; + + /** + * The current number of cycles performed. + */ + private int _currentCycleRetries; + + /** + * Array of BrokerDetail used to make connections. + */ + private ConnectionInfo _connectionDetails; + + public FailoverRoundRobin(ConnectionInfo connectionDetails) + { + if (!(connectionDetails.getBrokerCount() > 0)) + { + throw new ArgumentException("At least one broker details must be specified."); + } + + _connectionDetails = connectionDetails; + + //There is no current broker at startup so set it to -1. + _currentBrokerIndex = -1; + + String cycleRetries = _connectionDetails.getFailoverOption(ConnectionUrlConstants.OPTIONS_FAILOVER_CYCLE); + + if (cycleRetries != null) + { + try + { + _cycleRetries = int.Parse(cycleRetries); + } + catch (FormatException) + { + _cycleRetries = DEFAULT_CYCLE_RETRIES; + } + } + + _currentCycleRetries = 0; + + _serverRetries = 0; + _currentServerRetry = -1; + } + + public void reset() + { + _currentBrokerIndex = 0; + _currentCycleRetries = 0; + _currentServerRetry = -1; + } + + public bool failoverAllowed() + { + return ((_currentCycleRetries < _cycleRetries) + || (_currentServerRetry < _serverRetries) + || (_currentBrokerIndex < (_connectionDetails.getBrokerCount() - 1))); + } + + public void attainedConnection() + { + _currentCycleRetries = 0; + _currentServerRetry = -1; + } + + public BrokerInfo GetCurrentBrokerInfo() + { + if (_currentBrokerIndex == -1) + { + return null; + } + + return _connectionDetails.GetBrokerDetails(_currentBrokerIndex); + } + + public BrokerInfo getNextBrokerDetails() + { + if (_currentBrokerIndex == (_connectionDetails.getBrokerCount() - 1)) + { + if (_currentServerRetry < _serverRetries) + { + if (_currentBrokerIndex == -1) + { + _currentBrokerIndex = 0; + + setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + + _logger.Info("First Run using " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + } + else + { + _logger.Info("Retrying " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + } + + _currentServerRetry++; + } + else + { + _currentCycleRetries++; + //failed to connect to first broker + _currentBrokerIndex = 0; + + setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + + // This is zero rather than -1 as we are already retrieving the details. + _currentServerRetry = 0; + } + //else - should force client to stop as max retries has been reached. + } + else + { + if (_currentServerRetry < _serverRetries) + { + if (_currentBrokerIndex == -1) + { + _currentBrokerIndex = 0; + + setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + + _logger.Info("First Run using " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + } + else + { + _logger.Info("Retrying " + _connectionDetails.GetBrokerDetails(_currentBrokerIndex)); + } + _currentServerRetry++; + } + else + { + _currentBrokerIndex++; + + setBroker(_connectionDetails.GetBrokerDetails(_currentBrokerIndex )); + // This is zero rather than -1 as we are already retrieving the details. + _currentServerRetry = 0; + } + } + + return _connectionDetails.GetBrokerDetails(_currentBrokerIndex); + } + + public void setBroker(BrokerInfo broker) + { + _connectionDetails.AddBrokerInfo(broker); + + int index = _connectionDetails.GetAllBrokerInfos().IndexOf(broker); + + String serverRetries = broker.getOption(BrokerDetailsConstants.OPTIONS_RETRY); + + if (serverRetries != null) + { + try + { + _serverRetries = int.Parse(serverRetries); + } + catch (FormatException) + { + _serverRetries = DEFAULT_SERVER_RETRIES; + } + } + + _currentServerRetry = -1; + _currentBrokerIndex = index; + } + + public void setRetries(int maxRetries) + { + _cycleRetries = maxRetries; + } + + public String methodName() + { + return "Cycle Servers"; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append(GetType().Name).Append("\n"); + + sb.Append("Broker count: ").Append(_connectionDetails.getBrokerCount()); + sb.Append("\ncurrent broker index: ").Append(_currentBrokerIndex); + + sb.Append("\nCycle Retries: ").Append(_cycleRetries); + sb.Append("\nCurrent Cycle:").Append(_currentCycleRetries); + sb.Append("\nServer Retries:").Append(_serverRetries); + sb.Append("\nCurrent Retry:").Append(_currentServerRetry); + sb.Append("\n"); + + for(int i=0; i < _connectionDetails.getBrokerCount() ; i++) + { + if (i == _currentBrokerIndex) + { + sb.Append(">"); + } + sb.Append(_connectionDetails.GetBrokerDetails(i)); + sb.Append("\n"); + } + + return sb.ToString(); + } + } +} diff --git a/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs b/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs new file mode 100644 index 0000000000..f077f75fdf --- /dev/null +++ b/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs @@ -0,0 +1,147 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Client.qms.failover +{ + public class FailoverSingleServer : FailoverMethod + { + /** The default number of times to rety a conection to this server */ + public const int DEFAULT_SERVER_RETRIES = 1; + + /** + * The details of the Single Server + */ + private BrokerInfo _brokerDetail; + + /** + * The number of times to retry connecting to the sever + */ + private int _retries; + + /** + * The current number of attempts made to the server + */ + private int _currentRetries; + + + public FailoverSingleServer(ConnectionInfo connectionDetails) + { + if (connectionDetails.getBrokerCount() > 0) + { + setBroker(connectionDetails.GetBrokerDetails(0)); + } + else + { + throw new ArgumentException("BrokerInfo details required for connection."); + } + } + + public FailoverSingleServer(BrokerInfo brokerDetail) + { + setBroker(brokerDetail); + } + + public void reset() + { + _currentRetries = -1; + } + + public bool failoverAllowed() + { + return _currentRetries < _retries; + } + + public void attainedConnection() + { + reset(); + } + + public BrokerInfo GetCurrentBrokerInfo() + { + return _brokerDetail; + } + + public BrokerInfo getNextBrokerDetails() + { + if (_currentRetries == _retries) + { + return null; + } + else + { + if (_currentRetries < _retries) + { + _currentRetries ++; + } + + return _brokerDetail; + } + } + + public void setBroker(BrokerInfo broker) + { + if (broker == null) + { + throw new ArgumentException("BrokerInfo details cannot be null"); + } + _brokerDetail = broker; + + String retries = broker.getOption(BrokerDetailsConstants.OPTIONS_RETRY); + if (retries != null) + { + try + { + _retries = int.Parse(retries); + } + catch (FormatException nfe) + { + _retries = DEFAULT_SERVER_RETRIES; + } + } + else + { + _retries = DEFAULT_SERVER_RETRIES; + } + + reset(); + } + + public void setRetries(int retries) + { + _retries = retries; + } + + public String methodName() + { + return "Single Server"; + } + + public String toString() + { + return "SingleServer:\n"+ + "Max Retries:"+_retries+ + "\nCurrent Retry:"+_currentRetries+ + "\n"+_brokerDetail+"\n"; + } + + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs b/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs new file mode 100644 index 0000000000..70b4940c7b --- /dev/null +++ b/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs @@ -0,0 +1,140 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Buffer; + +namespace Qpid.Codec +{ + public abstract class CumulativeProtocolDecoder : IProtocolDecoder + { + ByteBuffer _remaining; + + /// <summary> + /// Creates a new instance with the 65535 bytes initial capacity of + /// cumulative buffer. + /// Note that capacity is currently fixed as the .NET ByteBuffers does not implement auto-expansion. + /// </summary> + protected CumulativeProtocolDecoder() + { + // Needs to be as large as the largest frame to be decoded. + _remaining = ByteBuffer.Allocate(65535); // FIXME: Probably should not be fixed. + } + + /// <summary> + /// Cumulates content of <tt>in</tt> into internal buffer and forwards + /// decoding request to {@link #doDecode(IoSession, ByteBuffer, ProtocolDecoderOutput)}. + /// <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt> + /// and the cumulative buffer is compacted after decoding ends. + /// </summary> + /// <exception cref="Exception"> + /// if your <tt>doDecode()</tt> returned <tt>true</tt> not consuming the cumulative buffer. + /// </exception> + public void Decode(ByteBuffer input, IProtocolDecoderOutput output) + { + if (_remaining.Position != 0) // If there were remaining undecoded bytes + { + DecodeRemainingAndInput(input, output); + } + else + { + DecodeInput(input, output); + } + } + + private void DecodeInput(ByteBuffer input, IProtocolDecoderOutput output) + { + // Just decode the input buffer and remember any remaining undecoded bytes. + try + { + DecodeAll(input, output); + } + finally + { + if (input.HasRemaining()) + { + _remaining.Put(input); + } + } + } + + private void DecodeRemainingAndInput(ByteBuffer input, IProtocolDecoderOutput output) + { + // Concatenate input buffer with left-over bytes. + _remaining.Put(input); + _remaining.Flip(); + + try + { + DecodeAll(_remaining, output); + } + finally + { + _remaining.Compact(); + } + } + + private void DecodeAll(ByteBuffer buf, IProtocolDecoderOutput output) + { + for (;;) + { + int oldPos = buf.Position; + bool decoded = DoDecode(buf, output); + if (decoded) + { + if (buf.Position == oldPos) + { + throw new Exception( + "doDecode() can't return true when buffer is not consumed."); + } + + if (!buf.HasRemaining()) + { + break; + } + } + else + { + break; + } + } + } + + /// <summary> + /// Implement this method to consume the specified cumulative buffer and + /// decode its content into message(s). + /// </summary> + /// <param name="input">the cumulative buffer</param> + /// <param name="output">decoder output</param> + /// <returns> + /// <tt>true</tt> if and only if there's more to decode in the buffer + /// and you want to have <tt>doDecode</tt> method invoked again. + /// Return <tt>false</tt> if remaining data is not enough to decode, + /// then this method will be invoked again when more data is cumulated. + /// </returns> + /// <exception cref="Exception">If cannot decode</exception> + protected abstract bool DoDecode(ByteBuffer input, IProtocolDecoderOutput output); + + public void Dispose() + { + _remaining = null; + } + } +} diff --git a/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs b/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs new file mode 100644 index 0000000000..8a58eecda4 --- /dev/null +++ b/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs @@ -0,0 +1,385 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using Qpid.Buffer; + +namespace Qpid.Codec.Demux +{ + public class DemuxingProtocolCodecFactory : IProtocolCodecFactory + { + private ArrayList _decoderFactories = new ArrayList(); + private ArrayList _encoderFactories = new ArrayList(); + + public void Register(Type encoderOrDecoderClass) + { + if (encoderOrDecoderClass == null) + { + throw new ArgumentNullException("encoderOrDecoderClass"); + } + + bool registered = false; + if (typeof(IMessageEncoder).IsAssignableFrom(encoderOrDecoderClass)) + { + Register(new DefaultConstructorMessageEncoderFactory(encoderOrDecoderClass)); + registered = true; + } + + if (typeof(IMessageDecoder).IsAssignableFrom(encoderOrDecoderClass)) + { + Register(new DefaultConstructorMessageDecoderFactory(encoderOrDecoderClass)); + registered = true; + } + + if (!registered) + { + throw new ArgumentException("Unregisterable type: " + encoderOrDecoderClass); + } + } + + public void Register(IMessageEncoder encoder) + { + Register(new SingletonMessageEncoderFactory(encoder)); + } + + public void Register(IMessageEncoderFactory factory) + { + if (factory == null) + { + throw new ArgumentNullException("factory"); + } + + _encoderFactories.Add(factory); + } + + public void Register(IMessageDecoder decoder) + { + Register(new SingletonMessageDecoderFactory(decoder)); + } + + public void Register(IMessageDecoderFactory factory) + { + if (factory == null) + { + throw new ArgumentNullException("factory"); + } + _decoderFactories.Add(factory); + } + + public IProtocolEncoder Encoder + { + get + { + return new ProtocolEncoderImpl(this); + } + } + + public IProtocolDecoder Decoder + { + get + { + return new ProtocolDecoderImpl(this); + } + } + + protected void DisposeCodecResources() + { + // Do nothing by default + } + + private class ProtocolEncoderImpl : IProtocolEncoder + { + private readonly Hashtable _encoders = new Hashtable(); + + private DemuxingProtocolCodecFactory _enclosing; + + public ProtocolEncoderImpl(DemuxingProtocolCodecFactory enclosing) + { + _enclosing = enclosing; + ArrayList encoderFactories = enclosing._encoderFactories; + for (int i = encoderFactories.Count - 1; i >= 0; i--) + { + IMessageEncoder encoder = ((IMessageEncoderFactory)encoderFactories[i]).NewEncoder(); + foreach (Type type in encoder.MessageTypes.Keys) + { + _encoders[type] = encoder; + } + } + } + + public void Encode(object message, IProtocolEncoderOutput output) + { + Type type = message.GetType(); + IMessageEncoder encoder = FindEncoder(type); + if (encoder == null) + { + throw new ProtocolEncoderException("Unexpected message type: " + type); + } + + encoder.Encode(message, output); + } + + private IMessageEncoder FindEncoder(Type type) + { + IMessageEncoder encoder = (IMessageEncoder)_encoders[type]; + if (encoder == null) + { + encoder = FindEncoder(type, new Hashtable()); + } + + return encoder; + } + + private IMessageEncoder FindEncoder(Type type, Hashtable triedClasses) + { + IMessageEncoder encoder; + + if (triedClasses.Contains(type)) + { + return null; + } + triedClasses[type] = 1; + + encoder = (IMessageEncoder)_encoders[type]; + if (encoder == null) + { + encoder = FindEncoder(type, triedClasses); + if (encoder != null) + { + return encoder; + } + + Type[] interfaces = type.GetInterfaces(); + for (int i = 0; i < interfaces.Length; i++) + { + encoder = FindEncoder(interfaces[i], triedClasses); + if (encoder != null) + { + return encoder; + } + } + + return null; + } + else + return encoder; + } + + public void Dispose() + { + _enclosing.DisposeCodecResources(); + } + } + + private class ProtocolDecoderImpl : CumulativeProtocolDecoder + { + private readonly IMessageDecoder[] _decoders; + private IMessageDecoder _currentDecoder; + private DemuxingProtocolCodecFactory _enclosing; + + public ProtocolDecoderImpl(DemuxingProtocolCodecFactory enclosing) + { + _enclosing = enclosing; + ArrayList decoderFactories = _enclosing._decoderFactories; + _decoders = new IMessageDecoder[decoderFactories.Count]; + for (int i = decoderFactories.Count - 1; i >= 0; i--) + { + _decoders[i] = ((IMessageDecoderFactory) decoderFactories[i]).NewDecoder(); + } + } + + protected override bool DoDecode(ByteBuffer input, IProtocolDecoderOutput output) + { + MessageDecoderResult result; + if (_currentDecoder == null) + { + IMessageDecoder[] decoders = _decoders; + int undecodables = 0; + + for (int i = decoders.Length - 1; i >= 0; i --) + { + IMessageDecoder decoder = decoders[i]; + int limit = input.Limit; + int pos = input.Position; + + try + { + result = decoder.Decodable(input); + } + finally + { + input.Position = pos; + input.Limit = limit; + } + + if (result == MessageDecoderResult.OK) + { + _currentDecoder = decoder; + break; + } + else if(result == MessageDecoderResult.NOT_OK) + { + undecodables ++; + } + else if (result != MessageDecoderResult.NEED_DATA) + { + throw new Exception("Unexpected decode result (see your decodable()): " + result); + } + } + + if (undecodables == _decoders.Length) + { + // Throw an exception if all decoders cannot decode data. + input.Position = input.Limit; // Skip data + throw new ProtocolDecoderException( + "No appropriate message decoder: " + input.HexDump); + } + + if (_currentDecoder == null) + { + // Decoder is not determined yet (i.e. we need more data) + return false; + } + } + + result = _currentDecoder.Decode(input, output); + if (result == MessageDecoderResult.OK) + { + _currentDecoder = null; + return true; + } + else if (result == MessageDecoderResult.NEED_DATA) + { + return false; + } + else if (result == MessageDecoderResult.NOT_OK) + { + throw new ProtocolDecoderException("Message decoder returned NOT_OK."); + } + else + { + throw new Exception("Unexpected decode result (see your decode()): " + result); + } + } + } + + private class SingletonMessageEncoderFactory : IMessageEncoderFactory + { + private readonly IMessageEncoder _encoder; + + public SingletonMessageEncoderFactory(IMessageEncoder encoder) + { + if (encoder == null) + { + throw new ArgumentNullException("encoder"); + } + _encoder = encoder; + } + + public IMessageEncoder NewEncoder() + { + return _encoder; + } + } + + private class SingletonMessageDecoderFactory : IMessageDecoderFactory + { + private readonly IMessageDecoder _decoder; + + public SingletonMessageDecoderFactory(IMessageDecoder decoder) + { + if (decoder == null) + { + throw new ArgumentNullException("decoder"); + } + _decoder = decoder; + } + + public IMessageDecoder NewDecoder() + { + return _decoder; + } + } + + private class DefaultConstructorMessageEncoderFactory : IMessageEncoderFactory + { + private readonly Type _encoderClass; + + public DefaultConstructorMessageEncoderFactory(Type encoderClass) + { + if (encoderClass == null) + { + throw new ArgumentNullException("encoderClass"); + } + + if(!typeof(IMessageEncoder).IsAssignableFrom(encoderClass)) + { + throw new ArgumentException("encoderClass is not assignable to MessageEncoder"); + } + _encoderClass = encoderClass; + } + + public IMessageEncoder NewEncoder() + { + try + { + return (IMessageEncoder) Activator.CreateInstance(_encoderClass); + } + catch (Exception e) + { + throw new Exception( "Failed to create a new instance of " + _encoderClass, e); + } + } + } + + private class DefaultConstructorMessageDecoderFactory : IMessageDecoderFactory + { + private readonly Type _decoderClass; + + public DefaultConstructorMessageDecoderFactory(Type decoderClass) + { + if (decoderClass == null) + { + throw new ArgumentNullException("decoderClass"); + } + + if(!typeof(IMessageDecoder).IsAssignableFrom(decoderClass)) + { + throw new ArgumentException("decoderClass is not assignable to MessageDecoder"); + } + _decoderClass = decoderClass; + } + + public IMessageDecoder NewDecoder() + { + try + { + return (IMessageDecoder) Activator.CreateInstance(_decoderClass); + } + catch (Exception e) + { + throw new Exception("Failed to create a new instance of " + _decoderClass, e); + } + } + } + } +} + diff --git a/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs b/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs new file mode 100644 index 0000000000..686544c78b --- /dev/null +++ b/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs @@ -0,0 +1,55 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Buffer; + +namespace Qpid.Codec.Demux +{ + public interface IMessageDecoder + { + /// <summary> + /// Checks the specified buffer is decodable by this decoder. + /// </summary> + /// <param name="buffer">The buffer to read data from.</param> + /// <returns> + /// OK if this decoder can decode the specified buffer. + /// NOT_OK if this decoder cannot decode the specified buffer. + /// if more data is required to determine if the + /// specified buffer is decodable ({@link #OK}) or not decodable + /// {@link #NOT_OK}.</returns> + MessageDecoderResult Decodable(ByteBuffer buffer); + + /// <summary> + /// Decodes binary or protocol-specific content into higher-level message objects. + /// MINA invokes {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)} + /// method with read data, and then the decoder implementation puts decoded + /// messages into {@link ProtocolDecoderOutput}. + /// </summary> + /// <returns> + /// {@link #OK} if you finished decoding messages successfully. + /// {@link #NEED_DATA} if you need more data to finish decoding current message. + /// {@link #NOT_OK} if you cannot decode current message due to protocol specification violation. + /// </returns> + /// <exception cref="Exception">if the read data violated protocol specification </exception> + MessageDecoderResult Decode(ByteBuffer buffer, IProtocolDecoderOutput output); + } +} + diff --git a/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs b/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs new file mode 100644 index 0000000000..418b5cf7e4 --- /dev/null +++ b/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs @@ -0,0 +1,31 @@ +/* + * + * 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. + * + */ +namespace Qpid.Codec.Demux +{ + public interface IMessageDecoderFactory + { + /// <summary> + /// Creates a new message decoder. + /// </summary> + IMessageDecoder NewDecoder(); + } +} + diff --git a/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs b/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs new file mode 100644 index 0000000000..7c1d117ad5 --- /dev/null +++ b/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs @@ -0,0 +1,47 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; + +namespace Qpid.Codec.Demux +{ + public interface IMessageEncoder + { + /// <summary> + /// Returns the set of message classes this encoder can encode. + /// </summary> + Hashtable MessageTypes + { + get; + } + + /// <summary> + /// Encodes higher-level message objects into binary or protocol-specific data. + /// MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)} + /// method with message which is popped from the session write queue, and then + /// the encoder implementation puts encoded {@link ByteBuffer}s into + /// {@link ProtocolEncoderOutput}. + /// </summary> + /// <exception cref="Exception">if the message violated protocol specification</exception> + void Encode(Object message, IProtocolEncoderOutput output); + } +} + diff --git a/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs b/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs new file mode 100644 index 0000000000..b8996e1853 --- /dev/null +++ b/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs @@ -0,0 +1,31 @@ +/* + * + * 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. + * + */ +namespace Qpid.Codec.Demux +{ + public interface IMessageEncoderFactory + { + /// <summary> + /// Creates a new message encoder. + /// </summary> + IMessageEncoder NewEncoder(); + } +} + diff --git a/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs b/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs new file mode 100644 index 0000000000..689d305919 --- /dev/null +++ b/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs @@ -0,0 +1,28 @@ +/* + * + * 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. + * + */ +namespace Qpid.Codec.Demux +{ + public enum MessageDecoderResult + { + OK, NOT_OK, NEED_DATA + } +} + diff --git a/dotnet/Qpid.Codec/IProtocolCodecFactory.cs b/dotnet/Qpid.Codec/IProtocolCodecFactory.cs new file mode 100644 index 0000000000..fe4ccc7fde --- /dev/null +++ b/dotnet/Qpid.Codec/IProtocolCodecFactory.cs @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +namespace Qpid.Codec +{ + public interface IProtocolCodecFactory + { + IProtocolEncoder Encoder + { + get; + } + + IProtocolDecoder Decoder + { + get; + } + } +} + diff --git a/dotnet/Qpid.Codec/IProtocolDecoder.cs b/dotnet/Qpid.Codec/IProtocolDecoder.cs new file mode 100644 index 0000000000..54317c3d07 --- /dev/null +++ b/dotnet/Qpid.Codec/IProtocolDecoder.cs @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Buffer; + +namespace Qpid.Codec +{ + public interface IProtocolDecoder : IDisposable + { + /// <summary> + /// Decodes binary or protocol-specific content into higher-level message objects. + /// MINA invokes {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)} + /// method with read data, and then the decoder implementation puts decoded + /// messages into {@link ProtocolDecoderOutput}. + /// </summary> + /// <param name="input"></param> + /// <param name="output"></param> + /// <exception cref="Exception">if the read data violated protocol specification</exception> + void Decode(ByteBuffer input, IProtocolDecoderOutput output); + } +} + diff --git a/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs b/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs new file mode 100644 index 0000000000..5862b36aed --- /dev/null +++ b/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs @@ -0,0 +1,34 @@ +/* + * + * 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. + * + */ +namespace Qpid.Codec +{ + public interface IProtocolDecoderOutput + { + /// <summary> + /// Callback for {@link ProtocolDecoder} to generate decoded messages. + /// {@link ProtocolDecoder} must call {@link #write(Object)} for each + /// decoded messages. + /// </summary> + /// <param name="message">the decoded message</param> + void Write(object message); + } +} + diff --git a/dotnet/Qpid.Codec/IProtocolEncoder.cs b/dotnet/Qpid.Codec/IProtocolEncoder.cs new file mode 100644 index 0000000000..aab803d3d6 --- /dev/null +++ b/dotnet/Qpid.Codec/IProtocolEncoder.cs @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Codec +{ + public interface IProtocolEncoder : IDisposable + { + /// <summary> + /// Encodes higher-level message objects into binary or protocol-specific data. + /// MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)} + /// method with message which is popped from the session write queue, and then + /// the encoder implementation puts encoded {@link ByteBuffer}s into + /// {@link ProtocolEncoderOutput}. + /// </summary> + /// <param name="message"></param> + /// <param name="output"></param> + /// <exception cref="Exception">if the message violated protocol specification</exception> + void Encode(Object message, IProtocolEncoderOutput output); + } +} + diff --git a/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs b/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs new file mode 100644 index 0000000000..12b9d68885 --- /dev/null +++ b/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Codec +{ + public interface IProtocolEncoderOutput + { + /// <summary> + /// Callback for {@link ProtocolEncoder} to generate encoded + /// {@link ByteBuffer}s. {@link ProtocolEncoder} must call + /// {@link #write(ByteBuffer)} for each decoded messages. + /// </summary> + /// <param name="buf">the buffer which contains encoded data</param> + void Write(ByteBuffer buf); + } +} + diff --git a/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs b/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..515e5f2998 --- /dev/null +++ b/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Mina.Codec")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("Mina.Codec")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8bfe84f8-cd88-48f7-b0d2-0010411a14e5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/Qpid.Codec/ProtocolCodecException.cs b/dotnet/Qpid.Codec/ProtocolCodecException.cs new file mode 100644 index 0000000000..797b475f19 --- /dev/null +++ b/dotnet/Qpid.Codec/ProtocolCodecException.cs @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Codec +{ + public class ProtocolCodecException : Exception + { + public ProtocolCodecException() : base() + { + } + + public ProtocolCodecException(string message) : base(message) + { + } + + public ProtocolCodecException(Exception cause) : base("Codec Exception", cause) + { + } + } +} + diff --git a/dotnet/Qpid.Codec/ProtocolDecoderException.cs b/dotnet/Qpid.Codec/ProtocolDecoderException.cs new file mode 100644 index 0000000000..94f3e6a591 --- /dev/null +++ b/dotnet/Qpid.Codec/ProtocolDecoderException.cs @@ -0,0 +1,54 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Codec +{ + public class ProtocolDecoderException : ProtocolCodecException + { + private string _hexdump; + + public ProtocolDecoderException() : base() + { + } + + public ProtocolDecoderException(string message) : base(message) + { + } + + public ProtocolDecoderException(Exception cause) : base(cause) + { + } + + public string HexDump + { + get + { + return _hexdump; + } + set + { + _hexdump = value; + } + } + } +} + diff --git a/dotnet/Qpid.Codec/ProtocolEncoderException.cs b/dotnet/Qpid.Codec/ProtocolEncoderException.cs new file mode 100644 index 0000000000..db589c6c00 --- /dev/null +++ b/dotnet/Qpid.Codec/ProtocolEncoderException.cs @@ -0,0 +1,40 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Codec +{ + public class ProtocolEncoderException : ProtocolCodecException + { + public ProtocolEncoderException() : base() + { + } + + public ProtocolEncoderException(string message) : base(message) + { + } + + public ProtocolEncoderException(Exception cause) : base(cause) + { + } + } +} + diff --git a/dotnet/Qpid.Codec/Qpid.Codec.csproj b/dotnet/Qpid.Codec/Qpid.Codec.csproj new file mode 100644 index 0000000000..581f68c5b4 --- /dev/null +++ b/dotnet/Qpid.Codec/Qpid.Codec.csproj @@ -0,0 +1,73 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Codec</RootNamespace>
+ <AssemblyName>Qpid.Codec</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.0.30714, Culture=neutral, PublicKeyToken=500ffcafb14f92df">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="CumulativeProtocolDecoder.cs" />
+ <Compile Include="Demux\DemuxingProtocolCodecFactory.cs" />
+ <Compile Include="Demux\IMessageDecoder.cs" />
+ <Compile Include="Demux\IMessageDecoderFactory.cs" />
+ <Compile Include="Demux\IMessageEncoder.cs" />
+ <Compile Include="Demux\IMessageEncoderFactory.cs" />
+ <Compile Include="Demux\MessageDecoderResult.cs" />
+ <Compile Include="IProtocolCodecFactory.cs" />
+ <Compile Include="IProtocolDecoder.cs" />
+ <Compile Include="IProtocolDecoderOutput.cs" />
+ <Compile Include="IProtocolEncoder.cs" />
+ <Compile Include="IProtocolEncoderOutput.cs" />
+ <Compile Include="ProtocolCodecException.cs" />
+ <Compile Include="ProtocolDecoderException.cs" />
+ <Compile Include="ProtocolEncoderException.cs" />
+ <Compile Include="Support\SimpleProtocolDecoderOutput.cs" />
+ <Compile Include="Support\SimpleProtocolEncoderOutput.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs b/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs new file mode 100644 index 0000000000..bb5d377ad9 --- /dev/null +++ b/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs @@ -0,0 +1,43 @@ +/* + * + * 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. + * + */ +using System.Collections; + +namespace Qpid.Codec.Support +{ + public class SimpleProtocolDecoderOutput : IProtocolDecoderOutput + { + private readonly Queue _messageQueue = new Queue(); + + public Queue MessageQueue + { + get + { + return _messageQueue; + } + } + + public void Write(object message) + { + _messageQueue.Enqueue(message); + } + } +} + diff --git a/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs b/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs new file mode 100644 index 0000000000..6f4f5cbb28 --- /dev/null +++ b/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs @@ -0,0 +1,44 @@ +/* + * + * 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. + * + */ +using System.Collections; +using Qpid.Buffer; + +namespace Qpid.Codec.Support +{ + public abstract class SimpleProtocolEncoderOutput : IProtocolEncoderOutput + { + private readonly Queue _bufferQueue = new Queue(); + + public Queue BufferQueue + { + get + { + return _bufferQueue; + } + } + + public void Write(ByteBuffer buf) + { + _bufferQueue.Enqueue(buf); + } + } +} + diff --git a/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs b/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9a602e21b6 --- /dev/null +++ b/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.Common.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("Qpid.Common.Tests")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2c0d906c-375d-4b04-8ad0-a22fcb4e7337")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj b/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj new file mode 100644 index 0000000000..f6ad2d814c --- /dev/null +++ b/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj @@ -0,0 +1,58 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F83624B0-762B-4D82-900D-FF4C1B36E36E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Common.Tests</RootNamespace>
+ <AssemblyName>Qpid.Common.Tests</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.2.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Client.Tests\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Qpid\Collections\SimpleDictionary.cs" />
+ <Compile Include="Qpid\Collections\TestLinkedHashtable.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs b/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs new file mode 100644 index 0000000000..cd3f730ab5 --- /dev/null +++ b/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs @@ -0,0 +1,83 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Text; +using NUnit.Framework; + +namespace Qpid.Collections +{ + [TestFixture] + public class TestLinkedHashtable + { + [Test] + public void Test1() + { + LinkedHashtable table = new LinkedHashtable(); + table["Super"] = "Ayr"; + table["Ayr"] = "United"; + table["Fred"] = "Wilma"; + table["Dumbarton"] = "Gubbed"; + dumpDictionary(table); + + Console.WriteLine("\nRemoving XXX (non-existant)"); + table.Remove("XXX"); + dumpDictionary(table); + + Console.WriteLine("\nRemoving Fred"); + table.Remove("Fred"); + dumpDictionary(table); + + Console.WriteLine("\nMoving Dumbarton to head"); + table.MoveToHead("Dumbarton"); + dumpDictionary(table); + } + + private static void dumpDictionary(LinkedHashtable table) + { + foreach (DictionaryEntry o in table) + { + Console.WriteLine(string.Format("Item: key={0} value={1}", o.Key, o.Value)); + } + + Console.WriteLine("keys are " + InspectCollection(table.Keys)); + Console.WriteLine("values are " + InspectCollection(table.Values)); + } + + static string InspectCollection(ICollection collection) + { + StringBuilder sb = null; + foreach (object o in collection) + { + if (sb == null) + { + sb = new StringBuilder(o.ToString()); + } + else + { + sb.Append(", "); + sb.Append(o.ToString()); + } + } + return sb.ToString(); + } + } +} diff --git a/dotnet/Qpid.Common/AMQChannelClosedException.cs b/dotnet/Qpid.Common/AMQChannelClosedException.cs new file mode 100644 index 0000000000..957e3b627d --- /dev/null +++ b/dotnet/Qpid.Common/AMQChannelClosedException.cs @@ -0,0 +1,30 @@ +/* + * + * 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. + * + */ +namespace Qpid +{ + public class AMQChannelClosedException : AMQException + { + public AMQChannelClosedException(int errorCode, string message) + : base(errorCode, message) + { + } + } +} diff --git a/dotnet/Qpid.Common/AMQConnectionClosedException.cs b/dotnet/Qpid.Common/AMQConnectionClosedException.cs new file mode 100644 index 0000000000..06d30e3d0a --- /dev/null +++ b/dotnet/Qpid.Common/AMQConnectionClosedException.cs @@ -0,0 +1,30 @@ +/* + * + * 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. + * + */ +namespace Qpid +{ + public class AMQConnectionClosedException : AMQException + { + public AMQConnectionClosedException(int errorCode, string message) + : base(errorCode, message) + { + } + } +} diff --git a/dotnet/Qpid.Common/AMQDisconnectedException.cs b/dotnet/Qpid.Common/AMQDisconnectedException.cs new file mode 100644 index 0000000000..e7cb2ff590 --- /dev/null +++ b/dotnet/Qpid.Common/AMQDisconnectedException.cs @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ +namespace Qpid +{ + public class AMQDisconnectedException : AMQException + { + public AMQDisconnectedException(int errorCode, string message) + : base(errorCode, message) + { + } + + public AMQDisconnectedException(string message) + : base(message) + { + } + } +} diff --git a/dotnet/Qpid.Common/AMQException.cs b/dotnet/Qpid.Common/AMQException.cs new file mode 100644 index 0000000000..1b2f5a80bf --- /dev/null +++ b/dotnet/Qpid.Common/AMQException.cs @@ -0,0 +1,124 @@ +/* + * + * 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. + * + */ +using System; +using log4net; + +namespace Qpid +{ + /// <summary> + /// The generic AMQ exception. + /// </summary> + public class AMQException : Exception + { + private int _errorCode; + + public AMQException(string message) + : base(message) + { + } + + public AMQException(string message, Exception innerException) + : base(message, innerException) + { + } + + public AMQException(int errorCode, string message) + : base(message) + { + _errorCode = errorCode; + } + + public AMQException(int errorCode, string message, Exception innerException) + : base(message, innerException) + { + _errorCode = errorCode; + } + + /// <summary> + /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will + /// be used to output log information upon construction. This saves having to log separately. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + public AMQException(ILog logger, string message) + : base(message) + { + logger.Error(message); + } + + /// <summary> + /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will + /// be used to output log information upon construction. This saves having to log separately. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="innerException">The root cause</param> + public AMQException(ILog logger, string message, Exception innerException) + : base(message, innerException) + { + logger.Error(message, innerException); + } + + /// <summary> + /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will + /// be used to output log information upon construction. This saves having to log separately. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="errorCode">The AMQ error code. See RFC 006 for details of error codes</param> + public AMQException(ILog logger, int errorCode, string message) + : this(errorCode, message) + { + logger.Error(message); + } + + /// <summary> + /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will + /// be used to output log information upon construction. This saves having to log separately. + /// </summary> + /// <param name="logger">The logger.</param> + /// <param name="message">The message.</param> + /// <param name="errorCode">The AMQ error code. See RFC 006 for details of error codes</param> + /// <param name="innerException">The root cause</param> + public AMQException(ILog logger, int errorCode, string message, Exception innerException) + : this(errorCode, message, innerException) + { + logger.Error(message, innerException); + } + + /// <summary> + /// Gets or sets the error code. See RFC 006 for details of error codes. + /// </summary> + /// <value>The error code.</value> + public int ErrorCode + { + get + { + return _errorCode; + } + set + { + _errorCode = value; + } + } + + } +} diff --git a/dotnet/Qpid.Common/AMQUndeliveredException.cs b/dotnet/Qpid.Common/AMQUndeliveredException.cs new file mode 100644 index 0000000000..1cbc56c0ce --- /dev/null +++ b/dotnet/Qpid.Common/AMQUndeliveredException.cs @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ +namespace Qpid +{ + /// <summary> + /// Thrown when a message has been bounced by the broker, indicating it could not be delivered. + /// </summary> + public class AMQUndeliveredException : AMQException + { + private object _bounced; + + public AMQUndeliveredException(int errorCode, string message, object bounced) + : base(errorCode, message) + { + _bounced = bounced; + } + + public object GetUndeliveredMessage() + { + return _bounced; + } + } +} diff --git a/dotnet/Qpid.Common/AssemblySettings.cs b/dotnet/Qpid.Common/AssemblySettings.cs new file mode 100644 index 0000000000..ee07c88659 --- /dev/null +++ b/dotnet/Qpid.Common/AssemblySettings.cs @@ -0,0 +1,160 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Configuration; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Xml; +using log4net; + +namespace Qpid.Common +{ + /// <summary> + /// + /// Mike Woodring + /// Bear Canyon Consulting LLC + /// http://www.bearcanyon.com + /// + /// AssemblySettings usage: + /// + /// If you know the keys you're after, the following is probably + /// the most convenient: + /// + /// AssemblySettings settings = new AssemblySettings(); + /// string someSetting1 = settings["someKey1"]; + /// string someSetting2 = settings["someKey2"]; + /// + /// If you want to enumerate over the settings (or just as an + /// alternative approach), you can do this too: + /// + /// IDictionary settings = AssemblySettings.GetConfig(); + /// + /// foreach( DictionaryEntry entry in settings ) + /// { + /// // Use entry.Key or entry.Value as desired... + /// } + /// + /// In either of the above two scenarios, the calling assembly + /// (the one that called the constructor or GetConfig) is used + /// to determine what file to parse and what the name of the + /// settings collection element is. For example, if the calling + /// assembly is c:\foo\bar\TestLib.dll, then the configuration file + /// that's parsed is c:\foo\bar\TestLib.dll.config, and the + /// configuration section that's parsed must be named <assemblySettings>. + /// + /// To retrieve the configuration information for an arbitrary assembly, + /// use the overloaded constructor or GetConfig method that takes an + /// Assembly reference as input. + /// + /// If your assembly is being automatically downloaded from a web + /// site by an "href-exe" (an application that's run directly from a link + /// on a web page), then the enclosed web.config shows the mechanism + /// for allowing the AssemblySettings library to download the + /// configuration files you're using for your assemblies (while not + /// allowing web.config itself to be downloaded). + /// + /// If the assembly you are trying to use this with is installed in, and loaded + /// from, the GAC then you'll need to place the config file in the GAC directory where + /// the assembly is installed. On the first release of the CLR, this directory is + /// <windir>\assembly\gac\libName\verNum__pubKeyToken]]>. For example, + /// the assembly "SomeLib, Version=1.2.3.4, Culture=neutral, PublicKeyToken=abcd1234" + /// would be installed to the c:\winnt\assembly\gac\SomeLib\1.2.3.4__abcd1234 diretory + /// (assuming the OS is installed in c:\winnt). For future versions of the CLR, this + /// directory scheme may change, so you'll need to check the <code>CodeBase</code> property + /// of a GAC-loaded assembly in the debugger to determine the correct directory location. + /// + /// </summary> + public class AssemblySettings + { + private static readonly ILog _log = LogManager.GetLogger(typeof(AssemblySettings)); + + private IDictionary settings; + + [MethodImpl(MethodImplOptions.NoInlining)] + public AssemblySettings() + : this(Assembly.GetCallingAssembly()) + { + } + + public AssemblySettings(Assembly asm) + { + settings = GetConfig(asm); + } + + public string this[string key] + { + get + { + string settingValue = null; + + if (settings != null) + { + settingValue = settings[key] as string; + } + + return (settingValue == null ? "" : settingValue); + } + } + + public static IDictionary GetConfig() + { + return GetConfig(Assembly.GetCallingAssembly()); + } + + public static IDictionary GetConfig(Assembly asm) + { + // Open and parse configuration file for specified + // assembly, returning collection to caller for future + // use outside of this class. + string cfgFile = asm.CodeBase + ".config"; + try + { + const string nodeName = "assemblySettings"; + + XmlDocument doc = new XmlDocument(); + doc.Load(new XmlTextReader(cfgFile)); + + XmlNodeList nodes = doc.GetElementsByTagName(nodeName); + + foreach (XmlNode node in nodes) + { + if (node.LocalName == nodeName) + { + DictionarySectionHandler handler = new DictionarySectionHandler(); + return (IDictionary)handler.Create(null, null, node); + } + } + } + catch (FileNotFoundException) + { + _log.Warn("Assembly configuration file not found: " + cfgFile); + } + catch (Exception e) + { + _log.Warn("Failed to load .config file: " + cfgFile, e); + } + + return null; + } + } +} diff --git a/dotnet/Qpid.Common/Collections/BlockingQueue.cs b/dotnet/Qpid.Common/Collections/BlockingQueue.cs new file mode 100644 index 0000000000..7adf6c3af2 --- /dev/null +++ b/dotnet/Qpid.Common/Collections/BlockingQueue.cs @@ -0,0 +1,94 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; + +namespace Qpid.Collections +{ + public abstract class BlockingQueue : Queue + { + /** + * Inserts the specified element into this queue if it is possible to do + * so immediately without violating capacity restrictions, returning + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently + * available. When using a capacity-restricted queue, this method is + * generally preferable to {@link #add}, which can fail to insert an + * element only by throwing an exception. + * + * @param e the element to add + * @return <tt>true</tt> if the element was added to this queue, else + * <tt>false</tt> + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this queue + */ + public abstract bool EnqueueNoThrow(Object e); + + /** + * Inserts the specified element into this queue, waiting if necessary + * for space to become available. + * + * @param e the element to add + * @throws InterruptedException if interrupted while waiting + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null + * @throws IllegalArgumentException if some property of the specified + * element prevents it from being added to this queue + */ + public abstract void EnqueueBlocking(object e); + + /** + * Retrieves and removes the head of this queue, waiting up to the + * specified wait time if necessary for an element to become available. + * + * @param timeout how long to wait before giving up, in units of + * <tt>unit</tt> + * @param unit a <tt>TimeUnit</tt> determining how to interpret the + * <tt>timeout</tt> parameter + * @return the head of this queue, or <tt>null</tt> if the + * specified waiting time elapses before an element is available + * @throws InterruptedException if interrupted while waiting + */ + public abstract object DequeueBlocking(); + + /** + * Returns the number of additional elements that this queue can ideally + * (in the absence of memory or resource constraints) accept without + * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic + * limit. + * + * <p>Note that you <em>cannot</em> always tell if an attempt to insert + * an element will succeed by inspecting <tt>remainingCapacity</tt> + * because it may be the case that another thread is about to + * insert or remove an element. + * + * @return the remaining capacity + */ + public abstract int RemainingCapacity + { + get; + } + } +} + diff --git a/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs b/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs new file mode 100644 index 0000000000..9678464989 --- /dev/null +++ b/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs @@ -0,0 +1,383 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; + +namespace Qpid.Collections +{ + public class LinkedBlockingQueue : BlockingQueue + { + + /* + * A variant of the "two lock queue" algorithm. The putLock gates + * entry to put (and offer), and has an associated condition for + * waiting puts. Similarly for the takeLock. The "count" field + * that they both rely on is maintained as an atomic to avoid + * needing to get both locks in most cases. Also, to minimize need + * for puts to get takeLock and vice-versa, cascading notifies are + * used. When a put notices that it has enabled at least one take, + * it signals taker. That taker in turn signals others if more + * items have been entered since the signal. And symmetrically for + * takes signalling puts. Operations such as remove(Object) and + * iterators acquire both locks. + */ + + /** + * Linked list node class + */ + internal class Node + { + /** The item, volatile to ensure barrier separating write and read */ + internal volatile Object item; + internal Node next; + internal Node(Object x) { item = x; } + } + + /** The capacity bound, or Integer.MAX_VALUE if none */ + private readonly int capacity; + + /** Current number of elements */ + private volatile int count = 0; + + /** Head of linked list */ + private Node head; + + /** Tail of linked list */ + private Node last; + + /** Lock held by take, poll, etc */ + private readonly object takeLock = new Object(); //new SerializableLock(); + + /** Lock held by put, offer, etc */ + private readonly object putLock = new Object();//new SerializableLock(); + + /** + * Signals a waiting take. Called only from put/offer (which do not + * otherwise ordinarily lock takeLock.) + */ + private void SignalNotEmpty() + { + lock (takeLock) + { + Monitor.Pulse(takeLock); + } + } + + /** + * Signals a waiting put. Called only from take/poll. + */ + private void SignalNotFull() + { + lock (putLock) + { + Monitor.Pulse(putLock); + } + } + + /** + * Creates a node and links it at end of queue. + * @param x the item + */ + private void Insert(Object x) + { + last = last.next = new Node(x); + } + + /** + * Removes a node from head of queue, + * @return the node + */ + private Object Extract() + { + Node first = head.next; + head = first; + Object x = first.item; + first.item = null; + return x; + } + + + /** + * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of + * {@link Integer#MAX_VALUE}. + */ + public LinkedBlockingQueue() : this(Int32.MaxValue) + { + } + + /** + * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity. + * + * @param capacity the capacity of this queue + * @throws IllegalArgumentException if <tt>capacity</tt> is not greater + * than zero + */ + public LinkedBlockingQueue(int capacity) + { + if (capacity <= 0) throw new ArgumentException("Capacity must be positive, was passed " + capacity); + this.capacity = capacity; + last = head = new Node(null); + } + + // this doc comment is overridden to remove the reference to collections + // greater in size than Integer.MAX_VALUE + /** + * Returns the number of elements in this queue. + * + * @return the number of elements in this queue + */ + public int Size + { + get + { + return count; + } + } + + // this doc comment is a modified copy of the inherited doc comment, + // without the reference to unlimited queues. + /** + * Returns the number of additional elements that this queue can ideally + * (in the absence of memory or resource constraints) accept without + * blocking. This is always equal to the initial capacity of this queue + * less the current <tt>size</tt> of this queue. + * + * <p>Note that you <em>cannot</em> always tell if an attempt to insert + * an element will succeed by inspecting <tt>remainingCapacity</tt> + * because it may be the case that another thread is about to + * insert or remove an element. + */ + public override int RemainingCapacity + { + get + { + return capacity - count; + } + } + + /** + * Inserts the specified element at the tail of this queue, waiting if + * necessary for space to become available. + * + * @throws InterruptedException {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + */ + public override void EnqueueBlocking(Object e) + { + if (e == null) throw new ArgumentNullException("Object must not be null"); + // Note: convention in all put/take/etc is to preset + // local var holding count negative to indicate failure unless set. + int c = -1; + lock (putLock) + { + /* + * Note that count is used in wait guard even though it is + * not protected by lock. This works because count can + * only decrease at this point (all other puts are shut + * out by lock), and we (or some other waiting put) are + * signalled if it ever changes from + * capacity. Similarly for all other uses of count in + * other wait guards. + */ + while (count == capacity) + { + Monitor.Wait(putLock); + } + + Insert(e); + lock(this) + { + c = count++; + } + if (c + 1 < capacity) + { + Monitor.Pulse(putLock); + } + } + + if (c == 0) + { + SignalNotEmpty(); + } + } + + /** + * Inserts the specified element at the tail of this queue if it is + * possible to do so immediately without exceeding the queue's capacity, + * returning <tt>true</tt> upon success and <tt>false</tt> if this queue + * is full. + * When using a capacity-restricted queue, this method is generally + * preferable to method {@link BlockingQueue#add add}, which can fail to + * insert an element only by throwing an exception. + * + * @throws NullPointerException if the specified element is null + */ + public override bool EnqueueNoThrow(Object e) + { + if (e == null) throw new ArgumentNullException("e must not be null"); + if (count == capacity) + { + return false; + } + int c = -1; + lock (putLock) + { + if (count < capacity) + { + Insert(e); + lock (this) + { + c = count++; + } + if (c + 1 < capacity) + { + Monitor.Pulse(putLock); + } + } + } + if (c == 0) + { + SignalNotEmpty(); + } + return c >= 0; + } + + /** + * Retrieves and removes the head of this queue, waiting if necessary + * until an element becomes available. + * + * @return the head of this queue + * @throws InterruptedException if interrupted while waiting + */ + public override Object DequeueBlocking() + { + Object x; + int c = -1; + lock (takeLock) + { + + while (count == 0) + { + Monitor.Wait(takeLock); + } + + + x = Extract(); + lock (this) { c = count--; } + if (c > 1) + { + Monitor.Pulse(takeLock); + } + } + if (c == capacity) + { + SignalNotFull(); + } + return x; + } + + public Object Poll() + { + if (count == 0) + { + return null; + } + Object x = null; + int c = -1; + lock (takeLock) + { + if (count > 0) + { + x = Extract(); + lock (this) { c = count--; } + if (c > 1) + { + Monitor.Pulse(takeLock); + } + } + } + if (c == capacity) + { + SignalNotFull(); + } + return x; + } + + + public override Object Peek() + { + if (count == 0) + { + return null; + } + lock (takeLock) + { + Node first = head.next; + if (first == null) + { + return null; + } + else + { + return first.item; + } + } + } + + public override String ToString() + { + lock (putLock) + { + lock (takeLock) + { + return base.ToString(); + } + } + } + + /** + * Atomically removes all of the elements from this queue. + * The queue will be empty after this call returns. + */ + public override void Clear() + { + lock (putLock) + { + lock (takeLock) + { + head.next = null; + last = head; + int c; + lock (this) + { + c = count; + count = 0; + } + if (c == capacity) + { + Monitor.PulseAll(putLock); + } + } + } + } + } +} + diff --git a/dotnet/Qpid.Common/Collections/LinkedHashtable.cs b/dotnet/Qpid.Common/Collections/LinkedHashtable.cs new file mode 100644 index 0000000000..55364f1aa1 --- /dev/null +++ b/dotnet/Qpid.Common/Collections/LinkedHashtable.cs @@ -0,0 +1,327 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; + +namespace Qpid.Collections +{ + public class LinkedHashtable : IDictionary + { + /// <summary> + /// Maps from key to LinkedDictionaryEntry + /// </summary> + private Hashtable _indexedValues = new Hashtable(); + + private LinkedDictionaryEntry _head; + + private LinkedDictionaryEntry _tail; + + private class LinkedDictionaryEntry + { + public LinkedDictionaryEntry _previous; + public LinkedDictionaryEntry _next; + internal DictionaryEntry _entry; + + public LinkedDictionaryEntry(object key, object value) + { + _entry = new DictionaryEntry(key, value); + } + } + + public object this[object key] + { + get + { + LinkedDictionaryEntry entry = (LinkedDictionaryEntry)_indexedValues[key]; + if (entry == null) + { + return null; // key not found + } + else + { + return entry._entry.Value; + } + } + + set + { + LinkedDictionaryEntry entry = (LinkedDictionaryEntry)_indexedValues[key]; + if (entry == null) + { + Add(key, value); + } + else + { + entry._entry.Value = value; + } + } + } + + /// <summary> + /// Collect keys in linked order. + /// </summary> + public ICollection Keys + { + get + { + IList result = new ArrayList(); + foreach (DictionaryEntry entry in this) + { + result.Add(entry.Key); + } + return result; + } + } + + /// <summary> + /// Collect values in linked order. + /// </summary> + public ICollection Values + { + get + { + IList result = new ArrayList(); + foreach (DictionaryEntry entry in this) + { + result.Add(entry.Value); + } + return result; + } + } + + public bool IsReadOnly + { + get { return _indexedValues.IsReadOnly; } + } + + public bool IsFixedSize + { + get { return _indexedValues.IsFixedSize; } + } + + public bool Contains(object key) + { + return _indexedValues.Contains(key); + } + + public void Add(object key, object value) + { + if (key == null) throw new ArgumentNullException("key"); + + if (Contains(key)) + { + throw new ArgumentException("LinkedHashtable already contains key. key=" + key); + } + + LinkedDictionaryEntry de = new LinkedDictionaryEntry(key, value); + if (_head == null) + { + _head = de; + _tail = de; + } + else + { + _tail._next = de; + de._previous = _tail; + _tail = de; + } + _indexedValues[key] = de; + } + + public void Clear() + { + _indexedValues.Clear(); + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + return new LHTEnumerator(this); + } + + public void Remove(object key) + { + if (key == null) throw new ArgumentNullException("key"); + + LinkedDictionaryEntry de = (LinkedDictionaryEntry)_indexedValues[key]; + if (de == null) return; // key not found. + LinkedDictionaryEntry prev = de._previous; + if (prev == null) + { + _head = de._next; + } + else + { + prev._next = de._next; + } + + LinkedDictionaryEntry next = de._next; + if (next == null) + { + _tail = de; + } + else + { + next._previous = de._previous; + } + } + + private LinkedDictionaryEntry Head + { + get + { + return _head; + } + } + + private LinkedDictionaryEntry Tail + { + get + { + return _tail; + } + } + + private class LHTEnumerator : IDictionaryEnumerator + { + private LinkedHashtable _container; + + private LinkedDictionaryEntry _current; + + /// <summary> + /// Set once we have navigated off the end of the collection + /// </summary> + private bool _needsReset = false; + + public LHTEnumerator(LinkedHashtable container) + { + _container = container; + } + + public object Current + { + get + { + if (_current == null) + { + throw new Exception("Iterator before first element"); + } + else + { + return _current._entry; + } + } + } + + public object Key + { + get { return _current._entry.Key; } + } + + public object Value + { + get { return _current._entry.Value; } + } + + public DictionaryEntry Entry + { + get + { + return _current._entry; + } + } + + public bool MoveNext() + { + if (_needsReset) + { + return false; + } + else if (_current == null) + { + _current = _container.Head; + } + else + { + _current = _current._next; + } + _needsReset = (_current == null); + return !_needsReset; + } + + public void Reset() + { + _current = null; + _needsReset = false; + } + } + + public void MoveToHead(object key) + { + LinkedDictionaryEntry de = (LinkedDictionaryEntry)_indexedValues[key]; + if (de == null) + { + throw new ArgumentException("Key " + key + " not found"); + } + // if the head is the element then there is nothing to do + if (_head == de) + { + return; + } + de._previous._next = de._next; + if (de._next != null) + { + de._next._previous = de._previous; + } + else + { + _tail = de._previous; + } + de._next = _head; + _head = de; + de._previous = null; + } + + public void CopyTo(Array array, int index) + { + _indexedValues.CopyTo(array, index); + } + + public int Count + { + get { return _indexedValues.Count; } + } + + public object SyncRoot + { + get { return _indexedValues.SyncRoot; } + } + + public bool IsSynchronized + { + get { return _indexedValues.IsSynchronized; } + } + + public IEnumerator GetEnumerator() + { + return new LHTEnumerator(this); + } + } +} diff --git a/dotnet/Qpid.Common/Collections/SynchronousQueue.cs b/dotnet/Qpid.Common/Collections/SynchronousQueue.cs new file mode 100644 index 0000000000..d210ea3b42 --- /dev/null +++ b/dotnet/Qpid.Common/Collections/SynchronousQueue.cs @@ -0,0 +1,376 @@ +/* + * + * 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. + * + */ +using System; +using System.Threading; + +namespace Qpid.Collections +{ + public class SynchronousQueue : BlockingQueue + { + /// <summary> + /// Lock protecting both wait queues + /// </summary> + private readonly object _qlock = new object(); + + /// <summary> + /// Queue holding waiting puts + /// </summary> + private readonly WaitQueue _waitingProducers; + + /// <summary> + /// Queue holding waiting takes + /// </summary> + private readonly WaitQueue _waitingConsumers; + + /** + * Queue to hold waiting puts/takes; specialized to Fifo/Lifo below. + * These queues have all transient fields, but are serializable + * in order to recover fairness settings when deserialized. + */ + internal abstract class WaitQueue + { + /** Creates, adds, and returns node for x. */ + internal abstract Node Enq(Object x); + /** Removes and returns node, or null if empty. */ + internal abstract Node Deq(); + /** Removes a cancelled node to avoid garbage retention. */ + internal abstract void Unlink(Node node); + /** Returns true if a cancelled node might be on queue. */ + internal abstract bool ShouldUnlink(Node node); + } + + /** + * FIFO queue to hold waiting puts/takes. + */ + sealed class FifoWaitQueue : WaitQueue + { + private Node head; + private Node last; + + internal override Node Enq(Object x) + { + Node p = new Node(x); + if (last == null) + { + last = head = p; + } + else + { + last = last.next = p; + } + return p; + } + + internal override Node Deq() + { + Node p = head; + if (p != null) + { + if ((head = p.next) == null) + { + last = null; + } + p.next = null; + } + return p; + } + + internal override bool ShouldUnlink(Node node) + { + return (node == last || node.next != null); + } + + internal override void Unlink(Node node) + { + Node p = head; + Node trail = null; + while (p != null) + { + if (p == node) + { + Node next = p.next; + if (trail == null) + { + head = next; + } + else + { + trail.next = next; + } + if (last == node) + { + last = trail; + } + break; + } + trail = p; + p = p.next; + } + } + } + + /** + * LIFO queue to hold waiting puts/takes. + */ + sealed class LifoWaitQueue : WaitQueue + { + private Node head; + + internal override Node Enq(Object x) + { + return head = new Node(x, head); + } + + internal override Node Deq() + { + Node p = head; + if (p != null) + { + head = p.next; + p.next = null; + } + return p; + } + + internal override bool ShouldUnlink(Node node) + { + // Return false if already dequeued or is bottom node (in which + // case we might retain at most one garbage node) + return (node == head || node.next != null); + } + + internal override void Unlink(Node node) + { + Node p = head; + Node trail = null; + while (p != null) + { + if (p == node) + { + Node next = p.next; + if (trail == null) + head = next; + else + trail.next = next; + break; + } + trail = p; + p = p.next; + } + } + } + + /** + * Nodes each maintain an item and handle waits and signals for + * getting and setting it. The class extends + * AbstractQueuedSynchronizer to manage blocking, using AQS state + * 0 for waiting, 1 for ack, -1 for cancelled. + */ + sealed internal class Node + { + + /** Synchronization state value representing that node acked */ + private const int ACK = 1; + /** Synchronization state value representing that node cancelled */ + private const int CANCEL = -1; + + internal int state = 0; + + /** The item being transferred */ + internal Object item; + /** Next node in wait queue */ + internal Node next; + + /** Creates a node with initial item */ + internal Node(Object x) + { + item = x; + } + + /** Creates a node with initial item and next */ + internal Node(Object x, Node n) + { + item = x; + next = n; + } + + /** + * Takes item and nulls out field (for sake of GC) + * + * PRE: lock owned + */ + private Object Extract() + { + Object x = item; + item = null; + return x; + } + + /** + * Tries to cancel on interrupt; if so rethrowing, + * else setting interrupt state + * + * PRE: lock owned + */ + /*private void checkCancellationOnInterrupt(InterruptedException ie) + throws InterruptedException + { + if (state == 0) { + state = CANCEL; + notify(); + throw ie; + } + Thread.currentThread().interrupt(); + }*/ + + /** + * Fills in the slot created by the consumer and signal consumer to + * continue. + */ + internal bool SetItem(Object x) + { + lock (this) + { + if (state != 0) return false; + item = x; + state = ACK; + Monitor.Pulse(this); + return true; + } + } + + /** + * Removes item from slot created by producer and signal producer + * to continue. + */ + internal Object GetItem() + { + if (state != 0) return null; + state = ACK; + Monitor.Pulse(this); + return Extract(); + } + + /** + * Waits for a consumer to take item placed by producer. + */ + internal void WaitForTake() //throws InterruptedException { + { + while (state == 0) + { + Monitor.Wait(this); + } + } + + /** + * Waits for a producer to put item placed by consumer. + */ + internal object WaitForPut() + { + lock (this) + { + while (state == 0) Monitor.Wait(this); + } + return Extract(); + } + + private bool Attempt(long nanos) + { + if (state != 0) return true; + if (nanos <= 0) { + state = CANCEL; + Monitor.Pulse(this); + return false; + } + + while (true) + { + Monitor.Wait(nanos); + //TimeUnit.NANOSECONDS.timedWait(this, nanos); + if (state != 0) + { + return true; + } + //nanos = deadline - Utils.nanoTime(); + //if (nanos <= 0) + else + { + state = CANCEL; + Monitor.Pulse(this); + return false; + } + } + } + + /** + * Waits for a consumer to take item placed by producer or time out. + */ + internal bool WaitForTake(long nanos) + { + return Attempt(nanos); + } + + /** + * Waits for a producer to put item placed by consumer, or time out. + */ + internal object WaitForPut(long nanos) + { + if (!Attempt(nanos)) + { + return null; + } + else + { + return Extract(); + } + } + } + + public SynchronousQueue(bool strict) + { + // TODO !!!! + } + + public override bool EnqueueNoThrow(object e) + { + throw new NotImplementedException(); + } + + public override void EnqueueBlocking(object e) + { + throw new NotImplementedException(); + } + + public override object DequeueBlocking() + { + throw new NotImplementedException(); + } + + public override int RemainingCapacity + { + get + { + throw new NotImplementedException(); + } + } + } +} + diff --git a/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs b/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs new file mode 100644 index 0000000000..f76ac005e4 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs @@ -0,0 +1,153 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using log4net; +using Qpid.Buffer; +using Qpid.Codec; +using Qpid.Codec.Demux; + +namespace Qpid.Framing +{ + public class AMQDataBlockDecoder : IMessageDecoder + { + private static ILog _logger = LogManager.GetLogger(typeof(AMQDataBlockDecoder)); + + private Hashtable _supportedBodies = new Hashtable(); + + private bool _disabled = false; + + public AMQDataBlockDecoder() + { + _supportedBodies[AMQMethodBody.TYPE] = AMQMethodBodyFactory.GetInstance(); + _supportedBodies[ContentHeaderBody.TYPE] = ContentHeaderBodyFactory.GetInstance(); + _supportedBodies[ContentBody.TYPE] = ContentBodyFactory.GetInstance(); + _supportedBodies[HeartbeatBody.TYPE] = new HeartbeatBodyFactory(); + } + + public MessageDecoderResult Decodable(ByteBuffer input) + { + if (_disabled) + { + return MessageDecoderResult.NOT_OK; + } + // final +1 represents the command end which we know we must require even + // if there is an empty body + if (input.Remaining < 1) + { + return MessageDecoderResult.NEED_DATA; + } + byte type = input.Get(); + + // we have to check this isn't a protocol initiation frame here - we can't tell later on and we end up + // waiting for more data. This could be improved if MINA supported some kind of state awareness when decoding + if ((char)type == 'A') + { + _logger.Error("Received what appears to be a protocol initiation frame"); + return MessageDecoderResult.NOT_OK; + } + // zero, channel, body size and end byte + if (input.Remaining < (1 + 2 + 4 + 1)) + { + return MessageDecoderResult.NEED_DATA; + } + + int channel = input.GetUnsignedShort(); + long bodySize = input.GetUnsignedInt(); + + // bodySize can be zero + if (type <= 0 || channel < 0 || bodySize < 0) + { + _logger.Error(String.Format("Error decoding frame: Type={0}, Channel={1}, BodySize={2}", type, channel, bodySize)); + return MessageDecoderResult.NOT_OK; + } + + if (input.Remaining < (bodySize + 1)) + { + return MessageDecoderResult.NEED_DATA; + } + + if (IsSupportedFrameType(type)) + { + if (_logger.IsDebugEnabled) + { + // we have read 7 bytes so far, so output 7 + bodysize + 1 (for end byte) to get complete data block size + // this logging statement is useful when looking at exactly what size of data is coming in/out + // the broker + _logger.Debug("Able to decode data block of size " + (bodySize + 8)); + } + return MessageDecoderResult.OK; + } + else + { + return MessageDecoderResult.NOT_OK; + } + } + + private bool IsSupportedFrameType(byte frameType) + { + bool result = _supportedBodies.ContainsKey(frameType); + + if (!result) + { + _logger.Warn("AMQDataBlockDecoder does not handle frame type " + frameType); + } + + return result; + } + + protected Object CreateAndPopulateFrame(ByteBuffer input) + { + byte type = input.Get(); + ushort channel = input.GetUnsignedShort(); + uint bodySize = input.GetUnsignedInt(); + + IBodyFactory bodyFactory = (IBodyFactory)_supportedBodies[type]; + if (bodyFactory == null) + { + throw new AMQFrameDecodingException("Unsupported body type: " + type); + } + AMQFrame frame = new AMQFrame(); + + frame.PopulateFromBuffer(input, channel, bodySize, bodyFactory); + + byte marker = input.Get(); + //assert marker == 0xCE; + return frame; + } + + public MessageDecoderResult Decode(ByteBuffer input, IProtocolDecoderOutput output) + { + + output.Write(CreateAndPopulateFrame(input)); + + return MessageDecoderResult.OK; + } + + public bool Disabled + { + set + { + _disabled = value; + } + } + } +} diff --git a/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs b/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs new file mode 100644 index 0000000000..b180e1ac95 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs @@ -0,0 +1,65 @@ +/* + * + * 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. + * + */ +using System.Collections; +using log4net; +using Qpid.Buffer; +using Qpid.Codec; +using Qpid.Codec.Demux; + +namespace Qpid.Framing +{ + public class AMQDataBlockEncoder : IMessageEncoder + { + private static ILog _logger = LogManager.GetLogger(typeof(AMQDataBlockEncoder)); + + private Hashtable _messageTypes; + + public AMQDataBlockEncoder() + { + _messageTypes = new Hashtable(); + _messageTypes[typeof (IEncodableAMQDataBlock)] = 1; + } + + + public Hashtable MessageTypes + { + get + { + return _messageTypes; + } + } + + public void Encode(object message, IProtocolEncoderOutput output) + { + IDataBlock frame = (IDataBlock) message; + int frameSize = (int)frame.Size; // TODO: sort out signed/unsigned + ByteBuffer buffer = ByteBuffer.Allocate(frameSize); + frame.WritePayload(buffer); + + if (_logger.IsDebugEnabled) + { + _logger.Debug("Encoded frame byte-buffer is '" + ByteBufferHexDumper.GetHexDump(buffer) + "'"); + } + buffer.Flip(); + output.Write(buffer); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/AMQFrame.cs b/dotnet/Qpid.Common/Framing/AMQFrame.cs new file mode 100644 index 0000000000..2708c331b3 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQFrame.cs @@ -0,0 +1,107 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class AMQFrame : IDataBlock + { + private ushort _channel; + + private IBody _bodyFrame; + + public AMQFrame() + { + } + + public AMQFrame(ushort channel, IBody bodyFrame) + { + _channel = channel; + _bodyFrame = bodyFrame; + } + + public ushort Channel + { + get + { + return _channel; + } + set + { + _channel = value; + } + } + + public IBody BodyFrame + { + get + { + return _bodyFrame; + } + set + { + _bodyFrame = value; + } + } + + #region IDataBlock Members + + public uint Size + { + get + { + return (uint) (1 + 2 + 4 + _bodyFrame.Size + 1); + } + } + + public void WritePayload(ByteBuffer buffer) + { + buffer.Put(_bodyFrame.BodyType); + // TODO: how does channel get populated + buffer.Put(_channel); + buffer.Put(_bodyFrame.Size); + _bodyFrame.WritePayload(buffer); + buffer.Put((byte) 0xCE); + } + + #endregion + + /// <summary> + /// Populates the frame instance data from the supplied buffer. + /// </summary> + /// <param name="buffer">The buffer.</param> + /// <param name="channel">The channel.</param> + /// <param name="bodySize">Size of the body in bytes</param> + /// <param name="bodyFactory">The body factory.</param> + /// <exception cref="AMQFrameDecodingException">Thrown if the buffer cannot be decoded</exception> + public void PopulateFromBuffer(ByteBuffer buffer, ushort channel, uint bodySize, IBodyFactory bodyFactory) + { + _channel = channel; + _bodyFrame = bodyFactory.CreateBody(buffer); + _bodyFrame.PopulateFromBuffer(buffer, bodySize); + } + + public override string ToString() + { + return "Frame channelId: " + _channel + ", bodyFrame: " + _bodyFrame.ToString(); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs b/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs new file mode 100644 index 0000000000..e7223c9850 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ +using System; +using log4net; + +namespace Qpid.Framing +{ + /// <summary> + /// Thrown when a frame cannot be decoded. This generally indicates a mismatch between the broker and the + /// client. + /// </summary> + public class AMQFrameDecodingException : AMQException + { + public AMQFrameDecodingException(string message) + : base(message) + { + } + + public AMQFrameDecodingException(string message, Exception innerException) + : base(message, innerException) + { + } + + public AMQFrameDecodingException(ILog logger, string message) + : base(logger, message) + { + } + + public AMQFrameDecodingException(ILog logger, string message, Exception innerException) + : base(logger, message, innerException) + { + } + } +} diff --git a/dotnet/Qpid.Common/Framing/AMQMethodBody.cs b/dotnet/Qpid.Common/Framing/AMQMethodBody.cs new file mode 100644 index 0000000000..804e6a4039 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQMethodBody.cs @@ -0,0 +1,93 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public abstract class AMQMethodBody : IBody + { + public const byte TYPE = 1; + + protected abstract uint BodySize + { + get; + } + + protected abstract ushort Clazz + { + get; + } + + protected abstract ushort Method + { + get; + } + + protected abstract void WriteMethodPayload(ByteBuffer buffer); + + public byte BodyType + { + get + { + return TYPE; + } + } + + public uint Size + { + get + { + return (uint) (2 + 2 + BodySize); + } + } + + public void WritePayload(ByteBuffer buffer) + { + buffer.Put(Clazz); + buffer.Put(Method); + WriteMethodPayload(buffer); + } + + /// <summary> + /// Populates the method body by decoding the specified buffer + /// </summary> + /// <param name="buffer">The buffer to decode.</param> + /// <exception cref="AMQFrameDecodingException">If the buffer cannot be decoded</exception> + protected abstract void PopulateMethodBodyFromBuffer(ByteBuffer buffer); + + /// <summary> + /// Populates this instance from a buffer of data. + /// </summary> + /// <param name="buffer">The buffer.</param> + /// <param name="size">The size.</param> + /// <exception cref="AMQFrameDecodingException">If the buffer contains data that cannot be decoded</exception> + public void PopulateFromBuffer(ByteBuffer buffer, uint size) + { + PopulateMethodBodyFromBuffer(buffer); + } + + public override string ToString() + { + return String.Format("{0}{{ Class: {1} Method: {2} }}", GetType().Name, Clazz, Method); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs b/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs new file mode 100644 index 0000000000..5df9720678 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs @@ -0,0 +1,45 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class AMQMethodBodyFactory : IBodyFactory + { + private static readonly AMQMethodBodyFactory _instance = new AMQMethodBodyFactory(); + + public static AMQMethodBodyFactory GetInstance() + { + return _instance; + } + + /// <summary> + /// Creates the body. + /// </summary> + /// <param name="inbuf">The ByteBuffer containing data from the network</param> + /// <returns></returns> + /// <exception>AMQFrameDecodingException</exception> + public IBody CreateBody(ByteBuffer inbuf) + { + return MethodBodyDecoderRegistry.Get(inbuf.GetUnsignedShort(), inbuf.GetUnsignedShort()); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs b/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs new file mode 100644 index 0000000000..7ea509c78a --- /dev/null +++ b/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +namespace Qpid.Framing +{ + public class AMQProtocolHeaderException : AMQException + { + public AMQProtocolHeaderException(string message) : base(message) + { + } + } +} diff --git a/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs b/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs new file mode 100644 index 0000000000..10d22b0e30 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs @@ -0,0 +1,168 @@ +/* + * + * 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. + * + */ +using System; +using log4net; +using Qpid.Buffer; +using Qpid.Messaging; + +namespace Qpid.Framing +{ + public class BasicContentHeaderProperties : IContentHeaderProperties + { + private static readonly ILog _log = LogManager.GetLogger(typeof(BasicContentHeaderProperties)); + + public string ContentType; + + public string Encoding; + + public FieldTable Headers; + + public byte DeliveryMode; + + public byte Priority; + + public string CorrelationId; + + public uint Expiration; + + public string ReplyTo; + + public string MessageId; + + public ulong Timestamp; + + public string Type; + + public string UserId; + + public string AppId; + + public string ClusterId; + + public BasicContentHeaderProperties() + { + } + + public uint PropertyListSize + { + get + { + return (uint)(EncodingUtils.EncodedShortStringLength(ContentType) + + EncodingUtils.EncodedShortStringLength(Encoding) + + EncodingUtils.EncodedFieldTableLength(Headers) + + 1 + 1 + + EncodingUtils.EncodedShortStringLength(CorrelationId) + + EncodingUtils.EncodedShortStringLength(ReplyTo) + + EncodingUtils.EncodedShortStringLength(String.Format("{0:D}", Expiration)) + + EncodingUtils.EncodedShortStringLength(MessageId) + + 8 + + EncodingUtils.EncodedShortStringLength(Type) + + EncodingUtils.EncodedShortStringLength(UserId) + + EncodingUtils.EncodedShortStringLength(AppId) + + EncodingUtils.EncodedShortStringLength(ClusterId)); + + } + } + + public ushort PropertyFlags + { + get + { + int value = 0; + + // for now we just blast in all properties + for (int i = 0; i < 14; i++) + { + value += (1 << (15-i)); + } + return (ushort) value; + } + } + + public void WritePropertyListPayload(ByteBuffer buffer) + { + EncodingUtils.WriteShortStringBytes(buffer, ContentType); + EncodingUtils.WriteShortStringBytes(buffer, Encoding); + EncodingUtils.WriteFieldTableBytes(buffer, Headers); + buffer.Put(DeliveryMode); + buffer.Put(Priority); + EncodingUtils.WriteShortStringBytes(buffer, CorrelationId); + EncodingUtils.WriteShortStringBytes(buffer, ReplyTo); + EncodingUtils.WriteShortStringBytes(buffer, String.Format("{0:D}", Expiration)); + EncodingUtils.WriteShortStringBytes(buffer, MessageId); + buffer.Put(Timestamp); + EncodingUtils.WriteShortStringBytes(buffer, Type); + EncodingUtils.WriteShortStringBytes(buffer, UserId); + EncodingUtils.WriteShortStringBytes(buffer, AppId); + EncodingUtils.WriteShortStringBytes(buffer, ClusterId); + } + + public void PopulatePropertiesFromBuffer(ByteBuffer buffer, ushort propertyFlags) + { + _log.Debug("Property flags: " + propertyFlags); + if ((propertyFlags & (1 << 15)) > 0) + ContentType = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 14)) > 0) + Encoding = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 13)) > 0) + Headers = EncodingUtils.ReadFieldTable(buffer); + if ((propertyFlags & (1 << 12)) > 0) + DeliveryMode = buffer.Get(); + if ((propertyFlags & (1 << 11)) > 0) + Priority = buffer.Get(); + if ((propertyFlags & (1 << 10)) > 0) + CorrelationId = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 9)) > 0) + ReplyTo = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 8)) > 0) + Expiration = UInt32.Parse(EncodingUtils.ReadShortString(buffer)); + if ((propertyFlags & (1 << 7)) > 0) + MessageId = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 6)) > 0) + Timestamp = buffer.GetUnsignedLong(); + if ((propertyFlags & (1 << 5)) > 0) + Type = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 4)) > 0) + UserId = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 3)) > 0) + AppId = EncodingUtils.ReadShortString(buffer); + if ((propertyFlags & (1 << 2)) > 0) + ClusterId = EncodingUtils.ReadShortString(buffer); + } + + public void SetDeliveryMode(DeliveryMode deliveryMode) + { + if (deliveryMode == Messaging.DeliveryMode.NonPersistent) + { + DeliveryMode = 1; + } + else + { + DeliveryMode = 2; + } + } + + public override string ToString() + { + return "Properties: " + ContentType + " " + Encoding + " " + Timestamp + " " + Type; + } + } +} diff --git a/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs b/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs new file mode 100644 index 0000000000..19d12b8039 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs @@ -0,0 +1,85 @@ +/* + * + * 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. + * + */ +using System.Text; +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class CompositeAMQDataBlock : IDataBlock, IEncodableAMQDataBlock + { + private IDataBlock[] _blocks; + + public CompositeAMQDataBlock(IDataBlock[] blocks) + { + _blocks = blocks; + } + + public IDataBlock[] Blocks + { + get + { + return _blocks; + } + } + + public uint Size + { + get + { + uint frameSize = 0; + foreach (IDataBlock block in _blocks) + { + frameSize += block.Size; + } + return frameSize; + } + } + + public void WritePayload(ByteBuffer buffer) + { + foreach (IDataBlock block in _blocks) + { + block.WritePayload(buffer); + } + } + + public override string ToString() + { + if (_blocks == null) + { + return "No blocks contained in composite frame"; + } + else + { + StringBuilder buf = new StringBuilder(GetType().Name); + buf.Append("{"); + //buf.Append("encodedBlock=").Append(_encodedBlock); + for (int i = 0; i < _blocks.Length; i++) + { + buf.Append(" ").Append(i).Append("=[").Append(_blocks[i].ToString()).Append("]"); + } + buf.Append("}"); + return buf.ToString(); + } + } + + } +} diff --git a/dotnet/Qpid.Common/Framing/ContentBody.cs b/dotnet/Qpid.Common/Framing/ContentBody.cs new file mode 100644 index 0000000000..e8bc003f65 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/ContentBody.cs @@ -0,0 +1,80 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class ContentBody : IBody + { + public const byte TYPE = 3; + + /// <summary> + /// + /// </summary> + /// TODO: consider whether this should be a pointer into the ByteBuffer to avoid copying */ + public byte[] Payload; + + #region IBody Members + + public byte BodyType + { + get + { + return TYPE; + } + } + + public uint Size + { + get + { + return (ushort)(Payload == null ? 0 : Payload.Length); + } + } + + public void WritePayload(ByteBuffer buffer) + { + if (Payload != null) + { + buffer.Put(Payload); + } + } + + public void PopulateFromBuffer(ByteBuffer buffer, uint size) + { + if (size > 0) + { + Payload = new byte[size]; + buffer.Get(Payload); + } + } + + #endregion + + public static AMQFrame CreateAMQFrame(ushort channelId, ContentBody body) + { + AMQFrame frame = new AMQFrame(); + frame.Channel = channelId; + frame.BodyFrame = body; + return frame; + } + } +} diff --git a/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs b/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs new file mode 100644 index 0000000000..ec0e89b421 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class ContentBodyFactory : IBodyFactory + { + private static readonly ILog _log = LogManager.GetLogger(typeof(ContentBodyFactory)); + + private static readonly ContentBodyFactory _instance = new ContentBodyFactory(); + + public static ContentBodyFactory GetInstance() + { + return _instance; + } + + private ContentBodyFactory() + { + _log.Debug("Creating content body factory"); + } + + /// <summary> + /// Creates the body. + /// </summary> + /// <param name="inbuf">The ByteBuffer containing data from the network</param> + /// <returns></returns> + /// <exception>AMQFrameDecodingException</exception> + public IBody CreateBody(ByteBuffer inbuf) + { + return new ContentBody(); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs b/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs new file mode 100644 index 0000000000..a3f71c41aa --- /dev/null +++ b/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs @@ -0,0 +1,118 @@ +/* + * + * 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. + * + */ +using System; +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class ContentHeaderBody : IBody + { + public static readonly byte TYPE = 2; + + public ushort ClassId; + + public ushort Weight; + + public ulong BodySize; + + /** must never be null */ + public IContentHeaderProperties Properties; + + public ContentHeaderBody() + { + } + + public ContentHeaderBody(IContentHeaderProperties props, ushort classId) + { + Properties = props; + ClassId = classId; + } + + public ContentHeaderBody(ushort classId, ushort weight, IContentHeaderProperties props, uint bodySize) + : this(props, classId) + { + Weight = weight; + BodySize = bodySize; + } + + #region IBody Members + + public byte BodyType + { + get + { + return TYPE; + } + } + + public uint Size + { + get + { + return (2 + 2 + 8 + 2 + Properties.PropertyListSize); + } + } + + public void WritePayload(ByteBuffer buffer) + { + buffer.Put(ClassId); + buffer.Put(Weight); + buffer.Put(BodySize); + buffer.Put(Properties.PropertyFlags); + Properties.WritePropertyListPayload(buffer); + } + + public void PopulateFromBuffer(ByteBuffer buffer, uint size) + { + ClassId = buffer.GetUnsignedShort(); + Weight = buffer.GetUnsignedShort(); + BodySize = buffer.GetUnsignedLong(); + ushort propertyFlags = buffer.GetUnsignedShort(); + ContentHeaderPropertiesFactory factory = ContentHeaderPropertiesFactory.GetInstance(); + Properties = factory.CreateContentHeaderProperties(ClassId, propertyFlags, buffer); + } + + #endregion + + public static AMQFrame CreateAMQFrame(ushort channelId, ushort classId, ushort weight, BasicContentHeaderProperties properties, + uint bodySize) + { + AMQFrame frame = new AMQFrame(); + frame.Channel = channelId; + frame.BodyFrame = new ContentHeaderBody(classId, weight, properties, bodySize); + return frame; + } + + public static AMQFrame CreateAMQFrame(ushort channelId, ContentHeaderBody body) + { + AMQFrame frame = new AMQFrame(); + frame.Channel = channelId; + frame.BodyFrame = body; + return frame; + } + + public override string ToString() + { + return String.Format("ContentHeaderBody: ClassId {0}, Weight {1}, BodySize {2}, Properties {3}", ClassId, Weight, + BodySize, Properties); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs b/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs new file mode 100644 index 0000000000..27cc5aeb04 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +using log4net; +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class ContentHeaderBodyFactory : IBodyFactory + { + private static readonly ILog _log = LogManager.GetLogger(typeof(ContentHeaderBodyFactory)); + + private static readonly ContentHeaderBodyFactory _instance = new ContentHeaderBodyFactory(); + + public static ContentHeaderBodyFactory GetInstance() + { + return _instance; + } + + private ContentHeaderBodyFactory() + { + _log.Debug("Creating content header body factory"); + } + + #region IBodyFactory Members + + public IBody CreateBody(ByteBuffer inbuf) + { + // all content headers are the same - it is only the properties that differ. + // the content header body further delegates construction of properties + return new ContentHeaderBody(); + } + + #endregion + } +} diff --git a/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs b/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs new file mode 100644 index 0000000000..16a24d6b92 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class ContentHeaderPropertiesFactory + { + + private static readonly ContentHeaderPropertiesFactory _instance = new ContentHeaderPropertiesFactory(); + + public static ContentHeaderPropertiesFactory GetInstance() + { + return _instance; + } + + private ContentHeaderPropertiesFactory() + { + } + + /// <summary> + /// Creates the content header properties from a buffer. + /// </summary> + /// <param name="classId">The class id.</param> + /// <param name="propertyFlags">The property flags.</param> + /// <param name="buffer">The buffer.</param> + /// <returns>a populated properties structure</returns> + /// <exception cref="AMQFrameDecodingException">if the buffer cannot be decoded</exception> + public IContentHeaderProperties CreateContentHeaderProperties(ushort classId, ushort propertyFlags, + ByteBuffer buffer) + { + IContentHeaderProperties properties; + switch (classId) + { + case 60: + properties = new BasicContentHeaderProperties(); + break; + default: + throw new AMQFrameDecodingException("Unsupport content header class id: " + classId); + } + properties.PopulatePropertiesFromBuffer(buffer, propertyFlags); + return properties; + } + } +} diff --git a/dotnet/Qpid.Common/Framing/EncodingUtils.cs b/dotnet/Qpid.Common/Framing/EncodingUtils.cs new file mode 100644 index 0000000000..748f3c9a0c --- /dev/null +++ b/dotnet/Qpid.Common/Framing/EncodingUtils.cs @@ -0,0 +1,251 @@ +/* + * + * 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. + * + */ +using System; +using System.Text; +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class EncodingUtils + { + private static readonly Encoding DEFAULT_ENCODER = Encoding.ASCII; + + public static ushort EncodedShortStringLength(string s) + { + if (s == null) + { + return 1; + } + else + { + return (ushort)(1 + s.Length); + } + } + + public static uint EncodedLongStringLength(string s) + { + if (s == null) + { + return 4; + } + else + { + return (uint)(4 + s.Length); + } + } + + public static int EncodedLongstrLength(byte[] bytes) + { + if (bytes == null) + { + return 4; + } + else + { + return 4 + bytes.Length; + } + } + + public static uint EncodedFieldTableLength(FieldTable table) + { + if (table == null) + { + // size is encoded as 4 octets + return 4; + } + else + { + // size of the table plus 4 octets for the size + return table.EncodedSize + 4; + } + } + + public static void WriteShortStringBytes(ByteBuffer buffer, string s) + { + if (s != null) + { + //try + //{ + //final byte[] encodedString = s.getBytes(STRING_ENCODING); + byte[] encodedString; + lock (DEFAULT_ENCODER) + { + encodedString = DEFAULT_ENCODER.GetBytes(s); + } + // TODO: check length fits in an unsigned byte + buffer.Put((byte) encodedString.Length); + buffer.Put(encodedString); + + } + else + { + // really writing out unsigned byte + buffer.Put((byte) 0); + } + } + + public static void WriteLongStringBytes(ByteBuffer buffer, string s) + { + if (!(s == null || s.Length <= 0xFFFE)) + { + throw new ArgumentException("String too long"); + } + if (s != null) + { + buffer.Put((uint)s.Length); + byte[] encodedString = null; + lock (DEFAULT_ENCODER) + { + encodedString = DEFAULT_ENCODER.GetBytes(s); + } + buffer.Put(encodedString); + } + else + { + buffer.Put((uint) 0); + } + } + + public static void WriteFieldTableBytes(ByteBuffer buffer, FieldTable table) + { + if (table != null) + { + table.WriteToBuffer(buffer); + } + else + { + buffer.Put((uint) 0); + } + } + + public static void WriteBooleans(ByteBuffer buffer, bool[] values) + { + byte packedValue = 0; + for (int i = 0; i < values.Length; i++) + { + if (values[i]) + { + packedValue = (byte) (packedValue | (1 << i)); + } + } + + buffer.Put(packedValue); + } + + public static void WriteLongstr(ByteBuffer buffer, byte[] data) + { + if (data != null) + { + buffer.Put((uint) data.Length); + buffer.Put(data); + } + else + { + buffer.Put((uint) 0); + } + } + + public static bool[] ReadBooleans(ByteBuffer buffer) + { + byte packedValue = buffer.Get(); + bool[] result = new bool[8]; + + for (int i = 0; i < 8; i++) + { + result[i] = ((packedValue & (1 << i)) != 0); + } + return result; + } + + /// <summary> + /// Reads the field table uaing the data in the specified buffer + /// </summary> + /// <param name="buffer">The buffer to read from.</param> + /// <returns>a populated field table</returns> + /// <exception cref="AMQFrameDecodingException">if the buffer does not contain a decodable field table</exception> + public static FieldTable ReadFieldTable(ByteBuffer buffer) + { + uint length = buffer.GetUnsignedInt(); + if (length == 0) + { + return null; + } + else + { + return new FieldTable(buffer, length); + } + } + + /// <summary> + /// Read a short string from the buffer + /// </summary> + /// <param name="buffer">The buffer to read from.</param> + /// <returns>a string</returns> + /// <exception cref="AMQFrameDecodingException">if the buffer does not contain a decodable short string</exception> + public static string ReadShortString(ByteBuffer buffer) + { + byte length = buffer.Get(); + if (length == 0) + { + return null; + } + else + { + lock (DEFAULT_ENCODER) + { + return buffer.GetString(length, DEFAULT_ENCODER); + } + } + } + + public static string ReadLongString(ByteBuffer buffer) + { + uint length = buffer.GetUnsignedInt(); + if (length == 0) + { + return null; + } + else + { + lock (DEFAULT_ENCODER) + { + return buffer.GetString(length, DEFAULT_ENCODER); + } + } + } + + public static byte[] ReadLongstr(ByteBuffer buffer) + { + uint length = buffer.GetUnsignedInt(); + if (length == 0) + { + return null; + } + else + { + byte[] result = new byte[length]; + buffer.Get(result); + return result; + } + } + } + +} diff --git a/dotnet/Qpid.Common/Framing/FieldTable.cs b/dotnet/Qpid.Common/Framing/FieldTable.cs new file mode 100644 index 0000000000..a7abc9d6e5 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/FieldTable.cs @@ -0,0 +1,300 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Text; +using Qpid.Buffer; +using Qpid.Collections; +using Qpid.Messaging; + +namespace Qpid.Framing +{ + /// + /// From the protocol document: + /// field-table = short-integer *field-value-pair + /// field-value-pair = field-name field-value + /// field-name = short-string + /// field-value = 'S' long-string + /// 'I' long-integer + /// 'D' decimal-value + /// 'T' long-integer + /// decimal-value = decimals long-integer + /// decimals = OCTET + public class FieldTable : IFieldTable + { + IDictionary _hash = new LinkedHashtable(); + + private uint _encodedSize = 0; + + public FieldTable() + { + } + + /** + * Construct a new field table. + * @param buffer the buffer from which to read data. The length byte must be read already + * @param length the length of the field table. Must be > 0. + * @throws AMQFrameDecodingException if there is an error decoding the table + */ + public FieldTable(ByteBuffer buffer, uint length) + { + _encodedSize = length; + int sizeRead = 0; + while (sizeRead < _encodedSize) + { + int sizeRemaining = buffer.Remaining; + string key = EncodingUtils.ReadShortString(buffer); + // TODO: use proper charset decoder + char type = (char)buffer.Get(); + object value; + switch (type) + { + case 'S': + value = EncodingUtils.ReadLongString(buffer); + break; + case 'I': + value = buffer.GetUnsignedInt(); + break; + default: + throw new AMQFrameDecodingException("Unsupported field table type: " + type); + } + sizeRead += (sizeRemaining - buffer.Remaining); + + _hash.Add(key, value); + } + } + + public uint EncodedSize + { + get + { + return _encodedSize; + } + } + + public int Count + { + get { return _hash.Count; } + } + + public object this[string key] + { + get + { + CheckKey(key); + return _hash[key]; + } + + set + { + CheckKey(key); + CheckValue(value); + + + object oldValue = _hash[key]; + if (oldValue != null) + { + AdjustEncodingSizeWhenRemoving(key, oldValue); + } + + _hash[key] = value; + AdjustEncodingSizeWhenAdding(key, value); + } + } + + public void WriteToBuffer(ByteBuffer buffer) + { + // Write out the total length, which we have kept up to date as data is added. + buffer.Put(_encodedSize); + WritePayload(buffer); + } + + private void WritePayload(ByteBuffer buffer) + { + foreach (DictionaryEntry lde in _hash) + { + string key = (string) lde.Key; + EncodingUtils.WriteShortStringBytes(buffer, key); + object value = lde.Value; + if (value is byte[]) + { + buffer.Put((byte) 'S'); + EncodingUtils.WriteLongstr(buffer, (byte[]) value); + } + else if (value is string) + { + // TODO: look at using proper charset encoder + buffer.Put((byte) 'S'); + EncodingUtils.WriteLongStringBytes(buffer, (string) value); + } + else if (value is uint) + { + // TODO: look at using proper charset encoder + buffer.Put((byte) 'I'); + buffer.Put((uint) value); + } + else + { + // Should never get here. + throw new InvalidOperationException("Unsupported type in FieldTable: " + value.GetType()); + } + } + } + + public byte[] GetDataAsBytes() + { + ByteBuffer buffer = ByteBuffer.Allocate((int)_encodedSize); + WritePayload(buffer); + byte[] result = new byte[_encodedSize]; + buffer.Flip(); + buffer.Get(result); + //buffer.Release(); + return result; + } + + /// <summary> + /// Adds all the items from one field table in this one. Will overwrite any items in the current table + /// with the same key. + /// </summary> + /// <param name="ft">the source field table</param> + public void AddAll(IFieldTable ft) + { + foreach (DictionaryEntry dictionaryEntry in ft) + { + this[(string)dictionaryEntry.Key] = dictionaryEntry.Value; + } + } + + private void CheckKey(object key) + { + if (key == null) + { + throw new ArgumentException("All keys must be Strings - was passed: null"); + } + else if (!(key is string)) + { + throw new ArgumentException("All keys must be Strings - was passed: " + key.GetType()); + } + } + + private void CheckValue(object value) + { + if (!(value is string || value is uint || value is int || value is long)) + { + throw new ArgumentException("All values must be type string or int or long or uint, was passed: " + + value.GetType()); + } + } + + void AdjustEncodingSizeWhenAdding(object key, object value) + { + _encodedSize += EncodingUtils.EncodedShortStringLength((string) key); + // the extra byte if for the type indicator what is written out + if (value is string) + { + _encodedSize += 1 + EncodingUtils.EncodedLongStringLength((string) value); + } + else if (value is int || value is uint || value is long) + { + _encodedSize += 1 + 4; + } + else + { + // Should never get here since was already checked + throw new Exception("Unsupported value type: " + value.GetType()); + } + } + + private void AdjustEncodingSizeWhenRemoving(object key, object value) + { + _encodedSize -= EncodingUtils.EncodedShortStringLength((string) key); + if (value != null) + { + if (value is string) + { + _encodedSize -= 1 + EncodingUtils.EncodedLongStringLength((string) value); + } + else if (value is int || value is uint || value is long) + { + _encodedSize -= 5; + } + else + { + // Should never get here + throw new Exception("Illegal value type: " + value.GetType()); + } + } + } + + public IEnumerator GetEnumerator() + { + return _hash.GetEnumerator(); + } + + public bool Contains(string s) + { + return _hash.Contains(s); + } + + public void Clear() + { + _hash.Clear(); + _encodedSize = 0; + } + + public void Remove(string key) + { + object value = _hash[key]; + if (value != null) + { + AdjustEncodingSizeWhenRemoving(key, value); + } + _hash.Remove(key); + } + + public IDictionary AsDictionary() + { + return _hash; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder("FieldTable{"); + + bool first = true; + foreach (DictionaryEntry entry in _hash) + { + if (first) + { + first = !first; + } + else + { + sb.Append(", "); + } + sb.Append(entry.Key).Append(" => ").Append(entry.Value); + } + + sb.Append("}"); + return sb.ToString(); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/HeartbeatBody.cs b/dotnet/Qpid.Common/Framing/HeartbeatBody.cs new file mode 100644 index 0000000000..3fdaa7e850 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/HeartbeatBody.cs @@ -0,0 +1,64 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class HeartbeatBody : IBody +{ + public const byte TYPE = 8; + public static AMQFrame FRAME = new HeartbeatBody().ToFrame(); + + public byte BodyType + { + get + { + return TYPE; + } + } + + public uint Size + { + get + { + return 0;//heartbeats we generate have no payload + } + } + + public void WritePayload(ByteBuffer buffer) + { + } + + public void PopulateFromBuffer(ByteBuffer buffer, uint size) + { + if (size > 0) + { + //allow other implementations to have a payload, but ignore it: + buffer.Skip((int) size); + } + } + + public AMQFrame ToFrame() + { + return new AMQFrame(0, this); + } +} +} diff --git a/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs b/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs new file mode 100644 index 0000000000..1e62f26c0d --- /dev/null +++ b/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + public class HeartbeatBodyFactory : IBodyFactory + { + public IBody CreateBody(ByteBuffer input) + { + return new HeartbeatBody(); + } + } +} diff --git a/dotnet/Qpid.Common/Framing/IBody.cs b/dotnet/Qpid.Common/Framing/IBody.cs new file mode 100644 index 0000000000..cc0dbd9b59 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/IBody.cs @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + /// <summary> + /// An IBody is contained within a top level frame. As such, it is not en/decodable on its own but + /// is decoded as a step within a the overall en/decoding process. + /// </summary> + public interface IBody + { + /// <summary> + /// Gets the type. See RFC 006 for the meaning of "type" in this context. + /// </summary> + /// <value>The type.</value> + byte BodyType + { + get; + } + + /// <summary> + /// Get the size of the body + /// </summary> + /// <value>The size in bytes.</value> + uint Size + { + get; + } + + /// <summary> + /// Writes this instance to a buffer. + /// </summary> + /// <param name="buffer">The buffer.</param> + void WritePayload(ByteBuffer buffer); + + /// <summary> + /// Populates this instance from a buffer of data. + /// </summary> + /// <param name="buffer">The buffer.</param> + /// <param name="size">The size.</param> + /// <exception cref="AMQFrameDecodingException">If the buffer contains data that cannot be decoded</exception> + void PopulateFromBuffer(ByteBuffer buffer, uint size); + } +} diff --git a/dotnet/Qpid.Common/Framing/IBodyFactory.cs b/dotnet/Qpid.Common/Framing/IBodyFactory.cs new file mode 100644 index 0000000000..4f6bc7155e --- /dev/null +++ b/dotnet/Qpid.Common/Framing/IBodyFactory.cs @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + /// <summary> + /// Any class that is capable of turning a stream of bytes into an AMQ structure must implement this interface. + /// </summary> + public interface IBodyFactory + { + /// <summary> + /// Creates the body. + /// </summary> + /// <param name="inbuf">The ByteBuffer containing data from the network</param> + /// <returns></returns> + /// <exception>AMQFrameDecodingException</exception> + IBody CreateBody(ByteBuffer inbuf); + } +} diff --git a/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs b/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs new file mode 100644 index 0000000000..df38738f1d --- /dev/null +++ b/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs @@ -0,0 +1,65 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + /// <summary> + /// There will be an implementation of this interface for each content type. All content types have associated + /// header properties and this provides a way to encode and decode them. + /// </summary> + public interface IContentHeaderProperties + { + /// <summary> + /// Writes the property list to the buffer, in a suitably encoded form. + /// </summary> + /// <param name="buffer">The buffer to write to</param> + void WritePropertyListPayload(ByteBuffer buffer); + + /// <summary> + /// Populates the properties from buffer. + /// </summary> + /// <param name="buffer">The buffer to read from.</param> + /// <param name="propertyFlags">The property flags.</param> + /// <exception cref="AMQFrameDecodingException">Thrown when the buffer does not contain valid data</exception> + void PopulatePropertiesFromBuffer(ByteBuffer buffer, ushort propertyFlags); + + /// <summary> + /// Gets the size of the encoded property list in bytes. + /// </summary> + /// <value>The size of the property list in bytes</value> + uint PropertyListSize + { + get; + } + + /// <summary> + /// Gets the property flags. Property flags indicate which properties are set in the list. The + /// position and meaning of each flag is defined in the protocol specification for the particular + /// content type with which these properties are associated. + /// </summary> + /// <value>the flags as an unsigned integer</value> + ushort PropertyFlags + { + get; + } + } +} diff --git a/dotnet/Qpid.Common/Framing/IDataBlock.cs b/dotnet/Qpid.Common/Framing/IDataBlock.cs new file mode 100644 index 0000000000..57b2a8ed37 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/IDataBlock.cs @@ -0,0 +1,47 @@ +/* + * + * 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. + * + */ +using Qpid.Buffer; + +namespace Qpid.Framing +{ + /// <summary> + /// A data block represents something that has a size in bytes and the ability to write itself to a byte + /// buffer (similar to a byte array). It represents "top level" frames in the protocol specification. + /// </summary> + public interface IDataBlock : IEncodableAMQDataBlock + { + /// <summary> + /// Get the size of buffer needed to store the byte representation of this + /// frame. + /// </summary> + /// <returns>size in bytes</returns> + uint Size + { + get; + } + + /// <summary> + /// Writes the datablock to the specified buffer. + /// </summary> + /// <param name="buffer">The buffer to write to. Must be the correct size.</param> + void WritePayload(ByteBuffer buffer); + } +} diff --git a/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs b/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs new file mode 100644 index 0000000000..1d81d5ea82 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs @@ -0,0 +1,31 @@ +/* + * + * 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. + * + */ +namespace Qpid.Framing +{ + + /// <summary> + /// Marker interface to indicate to MINA that a data block should be encoded with the + /// single encoder/decoder that we have defined. + /// </summary> + public interface IEncodableAMQDataBlock + { + } +} diff --git a/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs b/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs new file mode 100644 index 0000000000..44c9dafd97 --- /dev/null +++ b/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs @@ -0,0 +1,157 @@ +/* + * + * 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. + * + */ +using System; +using System.Collections; +using System.Configuration; +using System.Reflection; +using System.Xml; +using log4net; +using Qpid.Buffer; +using Qpid.Codec; +using Qpid.Codec.Demux; +using Qpid.Common; + +namespace Qpid.Framing +{ + public class ProtocolInitiation : IDataBlock, IEncodableAMQDataBlock + { + private static readonly ILog _log = LogManager.GetLogger(typeof(ProtocolInitiation)); + + public char[] Header = new char[]{'A','M','Q','P'}; + + private const byte CURRENT_PROTOCOL_CLASS = 1; + private const int CURRENT_PROTOCOL_INSTANCE = 1; + // FIXME: Needs to be tweakable from GRM.dll.config file. i.e. Major version 7 or 8 + + // FIXME: a configuration item for avoiding Basic.Qos (for OpenAMQ compatibility) + public static int CURRENT_PROTOCOL_VERSION_MAJOR = 8; // FIXME: put back to 7 for OpenAMQ! + private const int CURRENT_PROTOCOL_VERSION_MINOR = 0; + + public byte ProtocolClass = CURRENT_PROTOCOL_CLASS; + public byte ProtocolInstance = CURRENT_PROTOCOL_INSTANCE; + public byte ProtocolMajor = (byte)CURRENT_PROTOCOL_VERSION_MAJOR; + public byte ProtocolMinor = CURRENT_PROTOCOL_VERSION_MINOR; + + static ProtocolInitiation() + { + AssemblySettings settings = new AssemblySettings(); + string openAMQ = settings["OpenAMQ1d4Compatibility"]; + if (openAMQ.Equals("true")) + { + _log.Warn("Starting in OpenAMQ-1.0d4 compatibility mode. ProtocolMajorVersion is 7 and Basic.Qos will not be sent."); + CURRENT_PROTOCOL_VERSION_MAJOR = 7; + } + } + + public uint Size + { + get + { + return 4 + 1 + 1 + 1 + 1; + } + } + + public void WritePayload(ByteBuffer buffer) + { + foreach (char c in Header) + { + buffer.Put((byte) c); + } + buffer.Put(ProtocolClass); + buffer.Put(ProtocolInstance); + buffer.Put(ProtocolMajor); + buffer.Put(ProtocolMinor); + } + + /// <summary> + /// Populates from buffer. + /// </summary> + /// <param name="buffer">The buffer.</param> + public void PopulateFromBuffer(ByteBuffer buffer) + { + throw new AMQException("Method not implemented"); + } + + public class Decoder : IMessageDecoder + { + private bool _disabled = false; + + public MessageDecoderResult Decodable(ByteBuffer inbuf) + { + if (_disabled) + { + return MessageDecoderResult.NOT_OK; + } + if (inbuf.Remaining < 8) + { + return MessageDecoderResult.NEED_DATA; + } + else + { + char[] expected = new char[]{'A', 'M', 'Q', 'P'}; + for (int i = 0; i < 4; i++) + { + if (((char) inbuf.Get()) != expected[i]) + { + return MessageDecoderResult.NOT_OK; + } + } + return MessageDecoderResult.OK; + } + } + + /// <summary> + /// Decodes the specified session. + /// </summary> + /// <param name="session">The session.</param> + /// <param name="inbuf">The inbuf.</param> + /// <param name="outbuf">The outbuf.</param> + /// <returns></returns> + /// <exception cref="ProtocolViolationException">thrown if the frame violates the protocol</exception> + public MessageDecoderResult Decode(ByteBuffer inbuf, IProtocolDecoderOutput output) + { + byte[] header = new byte[4]; + inbuf.Get(header); + ProtocolInitiation pi = new ProtocolInitiation(); + pi.Header = new char[]{'A','M','Q','P'}; + pi.ProtocolClass = inbuf.Get(); + pi.ProtocolInstance = inbuf.Get(); + pi.ProtocolMajor = inbuf.Get(); + pi.ProtocolMinor = inbuf.Get(); + output.Write(pi); + return MessageDecoderResult.OK; + } + + public bool Disabled + { + set + { + _disabled = value; + } + } + } + + public override string ToString() + { + return String.Format("{0}{{Class={1} Instance={2} Major={3} Minor={4}}}", + GetType().Name, ProtocolClass, ProtocolInstance, ProtocolMajor, ProtocolMinor); + } + } +} diff --git a/dotnet/Qpid.Common/Properties/AssemblyInfo.cs b/dotnet/Qpid.Common/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3fea400217 --- /dev/null +++ b/dotnet/Qpid.Common/Properties/AssemblyInfo.cs @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.Common")] +[assembly: AssemblyDescription("Common AMQ Framing Code")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Copyright © J.P. Morgan Chase & Co. 2006")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8dea7c69-1383-4bf7-99e9-e172eba639a2")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("0.5.*")] diff --git a/dotnet/Qpid.Common/Qpid.Common.csproj b/dotnet/Qpid.Common/Qpid.Common.csproj new file mode 100644 index 0000000000..b392b48d83 --- /dev/null +++ b/dotnet/Qpid.Common/Qpid.Common.csproj @@ -0,0 +1,203 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid</RootNamespace>
+ <AssemblyName>Qpid.Common</AssemblyName>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AMQChannelClosedException.cs" />
+ <Compile Include="AMQConnectionClosedException.cs" />
+ <Compile Include="AMQDisconnectedException.cs" />
+ <Compile Include="AMQException.cs" />
+ <Compile Include="AMQUndeliveredException.cs" />
+ <Compile Include="AssemblySettings.cs" />
+ <Compile Include="Collections\LinkedHashtable.cs" />
+ <Compile Include="Framing\AMQDataBlockDecoder.cs" />
+ <Compile Include="Framing\AMQDataBlockEncoder.cs" />
+ <Compile Include="Framing\AMQFrame.cs" />
+ <Compile Include="Framing\AMQMethodBody.cs" />
+ <Compile Include="Framing\AMQMethodBodyFactory.cs" />
+ <Compile Include="Framing\AMQProtocolHeaderException.cs" />
+ <Compile Include="Framing\BasicContentHeaderProperties.cs" />
+ <Compile Include="Framing\CompositeAMQDataBlock.cs" />
+ <Compile Include="Framing\ContentBody.cs" />
+ <Compile Include="Framing\ContentBodyFactory.cs" />
+ <Compile Include="Framing\ContentHeaderBody.cs" />
+ <Compile Include="Framing\ContentHeaderBodyFactory.cs" />
+ <Compile Include="Framing\ContentHeaderPropertiesFactory.cs" />
+ <Compile Include="Framing\EncodingUtils.cs" />
+ <Compile Include="Framing\FieldTable.cs" />
+ <Compile Include="Framing\HeartbeatBody.cs" />
+ <Compile Include="Framing\HeartbeatBodyFactory.cs" />
+ <Compile Include="Framing\IBody.cs" />
+ <Compile Include="Framing\IDataBlock.cs" />
+ <Compile Include="Framing\AMQFrameDecodingException.cs" />
+ <Compile Include="Framing\IEncodableAMQDataBlock.cs" />
+ <Compile Include="Framing\IBodyFactory.cs" />
+ <Compile Include="Framing\IContentHeaderProperties.cs" />
+ <Compile Include="Framing\ProtocolInitiation.cs" />
+ <Compile Include="generated\AccessRequestBody.cs" />
+ <Compile Include="generated\AccessRequestOkBody.cs" />
+ <Compile Include="generated\BasicAckBody.cs" />
+ <Compile Include="generated\BasicCancelBody.cs" />
+ <Compile Include="generated\BasicCancelOkBody.cs" />
+ <Compile Include="generated\BasicConsumeBody.cs" />
+ <Compile Include="generated\BasicConsumeOkBody.cs" />
+ <Compile Include="generated\BasicDeliverBody.cs" />
+ <Compile Include="generated\BasicGetBody.cs" />
+ <Compile Include="generated\BasicGetEmptyBody.cs" />
+ <Compile Include="generated\BasicGetOkBody.cs" />
+ <Compile Include="generated\BasicPublishBody.cs" />
+ <Compile Include="generated\BasicQosBody.cs" />
+ <Compile Include="generated\BasicQosOkBody.cs" />
+ <Compile Include="generated\BasicRecoverBody.cs" />
+ <Compile Include="generated\BasicRejectBody.cs" />
+ <Compile Include="generated\BasicReturnBody.cs" />
+ <Compile Include="generated\ChannelAlertBody.cs" />
+ <Compile Include="generated\ChannelCloseBody.cs" />
+ <Compile Include="generated\ChannelCloseOkBody.cs" />
+ <Compile Include="generated\ChannelFlowBody.cs" />
+ <Compile Include="generated\ChannelFlowOkBody.cs" />
+ <Compile Include="generated\ChannelOpenBody.cs" />
+ <Compile Include="generated\ChannelOpenOkBody.cs" />
+ <Compile Include="generated\ConnectionCloseBody.cs" />
+ <Compile Include="generated\ConnectionCloseOkBody.cs" />
+ <Compile Include="generated\ConnectionOpenBody.cs" />
+ <Compile Include="generated\ConnectionOpenOkBody.cs" />
+ <Compile Include="generated\ConnectionRedirectBody.cs" />
+ <Compile Include="generated\ConnectionSecureBody.cs" />
+ <Compile Include="generated\ConnectionSecureOkBody.cs" />
+ <Compile Include="generated\ConnectionStartBody.cs" />
+ <Compile Include="generated\ConnectionStartOkBody.cs" />
+ <Compile Include="generated\ConnectionTuneBody.cs" />
+ <Compile Include="generated\ConnectionTuneOkBody.cs" />
+ <Compile Include="generated\DtxSelectBody.cs" />
+ <Compile Include="generated\DtxSelectOkBody.cs" />
+ <Compile Include="generated\DtxStartBody.cs" />
+ <Compile Include="generated\DtxStartOkBody.cs" />
+ <Compile Include="generated\ExchangeDeclareBody.cs" />
+ <Compile Include="generated\ExchangeDeclareOkBody.cs" />
+ <Compile Include="generated\ExchangeDeleteBody.cs" />
+ <Compile Include="generated\ExchangeDeleteOkBody.cs" />
+ <Compile Include="generated\FileAckBody.cs" />
+ <Compile Include="generated\FileCancelBody.cs" />
+ <Compile Include="generated\FileCancelOkBody.cs" />
+ <Compile Include="generated\FileConsumeBody.cs" />
+ <Compile Include="generated\FileConsumeOkBody.cs" />
+ <Compile Include="generated\FileDeliverBody.cs" />
+ <Compile Include="generated\FileOpenBody.cs" />
+ <Compile Include="generated\FileOpenOkBody.cs" />
+ <Compile Include="generated\FilePublishBody.cs" />
+ <Compile Include="generated\FileQosBody.cs" />
+ <Compile Include="generated\FileQosOkBody.cs" />
+ <Compile Include="generated\FileRejectBody.cs" />
+ <Compile Include="generated\FileReturnBody.cs" />
+ <Compile Include="generated\FileStageBody.cs" />
+ <Compile Include="generated\MainRegistry.cs" />
+ <Compile Include="generated\MethodBodyDecoderRegistry.cs" />
+ <Compile Include="generated\QueueBindBody.cs" />
+ <Compile Include="generated\QueueBindOkBody.cs" />
+ <Compile Include="generated\QueueDeclareBody.cs" />
+ <Compile Include="generated\QueueDeclareOkBody.cs" />
+ <Compile Include="generated\QueueDeleteBody.cs" />
+ <Compile Include="generated\QueueDeleteOkBody.cs" />
+ <Compile Include="generated\QueuePurgeBody.cs" />
+ <Compile Include="generated\QueuePurgeOkBody.cs" />
+ <Compile Include="generated\StreamCancelBody.cs" />
+ <Compile Include="generated\StreamCancelOkBody.cs" />
+ <Compile Include="generated\StreamConsumeBody.cs" />
+ <Compile Include="generated\StreamConsumeOkBody.cs" />
+ <Compile Include="generated\StreamDeliverBody.cs" />
+ <Compile Include="generated\StreamPublishBody.cs" />
+ <Compile Include="generated\StreamQosBody.cs" />
+ <Compile Include="generated\StreamQosOkBody.cs" />
+ <Compile Include="generated\StreamReturnBody.cs" />
+ <Compile Include="generated\TestContentBody.cs" />
+ <Compile Include="generated\TestContentOkBody.cs" />
+ <Compile Include="generated\TestIntegerBody.cs" />
+ <Compile Include="generated\TestIntegerOkBody.cs" />
+ <Compile Include="generated\TestStringBody.cs" />
+ <Compile Include="generated\TestStringOkBody.cs" />
+ <Compile Include="generated\TestTableBody.cs" />
+ <Compile Include="generated\TestTableOkBody.cs" />
+ <Compile Include="generated\TunnelRequestBody.cs" />
+ <Compile Include="generated\TxCommitBody.cs" />
+ <Compile Include="generated\TxCommitOkBody.cs" />
+ <Compile Include="generated\TxRollbackBody.cs" />
+ <Compile Include="generated\TxRollbackOkBody.cs" />
+ <Compile Include="generated\TxSelectBody.cs" />
+ <Compile Include="generated\TxSelectOkBody.cs" />
+ <Compile Include="Collections\BlockingQueue.cs" />
+ <Compile Include="Collections\LinkedBlockingQueue.cs" />
+ <Compile Include="Collections\SynchronousQueue.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="stylesheets\csharp.xsl" />
+ <Content Include="stylesheets\framing.xsl" />
+ <Content Include="stylesheets\java.xsl" />
+ <Content Include="stylesheets\prepare1.xsl" />
+ <Content Include="stylesheets\prepare2.xsl" />
+ <Content Include="stylesheets\prepare3.xsl" />
+ <Content Include="stylesheets\readme.txt" />
+ <Content Include="stylesheets\registry.xsl" />
+ <Content Include="stylesheets\utils.xsl" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Common/amqp.xml b/dotnet/Qpid.Common/amqp.xml new file mode 100644 index 0000000000..8ad0f17a2c --- /dev/null +++ b/dotnet/Qpid.Common/amqp.xml @@ -0,0 +1,3908 @@ +<?xml version="1.0"?> + +<!-- +Copyright Notice +================ +© Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., +iMatix Corporation, IONA� Technologies, Red Hat, Inc., +TWIST Process Innovations, and 29West Inc. 2006. All rights reserved. + +License +======= +JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix +Corporation, IONA� Technologies, Red Hat, Inc., TWIST Process Innovations, and +29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide, +perpetual, royalty-free, nontransferable, nonexclusive license to +(i) copy, display, and implement the Advanced Messaging Queue Protocol +("AMQP") Specification and (ii) the Licensed Claims that are held by +the Authors, all for the purpose of implementing the Advanced Messaging +Queue Protocol Specification. Your license and any rights under this +Agreement will terminate immediately without notice from +any Author if you bring any claim, suit, demand, or action related to +the Advanced Messaging Queue Protocol Specification against any Author. +Upon termination, you shall destroy all copies of the Advanced Messaging +Queue Protocol Specification in your possession or control. + +As used hereunder, "Licensed Claims" means those claims of a patent or +patent application, throughout the world, excluding design patents and +design registrations, owned or controlled, or that can be sublicensed +without fee and in compliance with the requirements of this +Agreement, by an Author or its affiliates now or at any +future time and which would necessarily be infringed by implementation +of the Advanced Messaging Queue Protocol Specification. A claim is +necessarily infringed hereunder only when it is not possible to avoid +infringing it because there is no plausible non-infringing alternative +for implementing the required portions of the Advanced Messaging Queue +Protocol Specification. Notwithstanding the foregoing, Licensed Claims +shall not include any claims other than as set forth above even if +contained in the same patent as Licensed Claims; or that read solely +on any implementations of any portion of the Advanced Messaging Queue +Protocol Specification that are not required by the Advanced Messaging +Queue Protocol Specification, or that, if licensed, would require a +payment of royalties by the licensor to unaffiliated third parties. +Moreover, Licensed Claims shall not include (i) any enabling technologies +that may be necessary to make or use any Licensed Product but are not +themselves expressly set forth in the Advanced Messaging Queue Protocol +Specification (e.g., semiconductor manufacturing technology, compiler +technology, object oriented technology, networking technology, operating +system technology, and the like); or (ii) the implementation of other +published standards developed elsewhere and merely referred to in the +body of the Advanced Messaging Queue Protocol Specification, or +(iii) any Licensed Product and any combinations thereof the purpose or +function of which is not required for compliance with the Advanced +Messaging Queue Protocol Specification. For purposes of this definition, +the Advanced Messaging Queue Protocol Specification shall be deemed to +include both architectural and interconnection requirements essential +for interoperability and may also include supporting source code artifacts +where such architectural, interconnection requirements and source code +artifacts are expressly identified as being required or documentation to +achieve compliance with the Advanced Messaging Queue Protocol Specification. + +As used hereunder, "Licensed Products" means only those specific portions +of products (hardware, software or combinations thereof) that implement +and are compliant with all relevant portions of the Advanced Messaging +Queue Protocol Specification. + +The following disclaimers, which you hereby also acknowledge as to any +use you may make of the Advanced Messaging Queue Protocol Specification: + +THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS," +AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE +CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE +SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED +MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY +PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY +USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE +PROTOCOL SPECIFICATION. + +The name and trademarks of the Authors may NOT be used in any manner, +including advertising or publicity pertaining to the Advanced Messaging +Queue Protocol Specification or its contents without specific, written +prior permission. Title to copyright in the Advanced Messaging Queue +Protocol Specification will at all times remain with the Authors. + +No other rights are granted by implication, estoppel or otherwise. + +Upon termination of your license or rights under this Agreement, you +shall destroy all copies of the Advanced Messaging Queue Protocol +Specification in your possession or control. + +Trademarks +========== +"JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the +Octagon Symbol are trademarks of JPMorgan Chase & Co. + +IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl. + +IONA, IONA Technologies, and the IONA logos are trademarks of IONA +Technologies PLC and/or its subsidiaries. + +LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered +trademarks of Red Hat, Inc. in the US and other countries. + +Java, all Java-based trademarks and OpenOffice.org are trademarks of +Sun Microsystems, Inc. in the United States, other countries, or both. + +Other company, product, or service names may be trademarks or service +marks of others. + +Links to full AMQP specification: +================================= +http://www.envoytech.org/spec/amq/ +http://www.iona.com/opensource/amqp/ +http://www.redhat.com/solutions/specifications/amqp/ +http://www.twiststandards.org/tiki-index.php?page=AMQ +http://www.imatix.com/amqp + +--> + +<amqp major="8" minor="0" port="5672" comment="AMQ protocol 0.80"> + AMQ Protocol 0.80 +<!-- +====================================================== +== CONSTANTS +====================================================== +--> + <constant name="frame method" value="1"/> + <constant name="frame header" value="2"/> + <constant name="frame body" value="3"/> + <constant name="frame oob method" value="4"/> + <constant name="frame oob header" value="5"/> + <constant name="frame oob body" value="6"/> + <constant name="frame trace" value="7"/> + <constant name="frame heartbeat" value="8"/> + <constant name="frame min size" value="4096"/> + <constant name="frame end" value="206"/> + <constant name="reply success" value="200"> + Indicates that the method completed successfully. This reply code is + reserved for future use - the current protocol design does not use + positive confirmation and reply codes are sent only in case of an + error. +</constant> + <constant name="not delivered" value="310" class="soft error"> + The client asked for a specific message that is no longer available. + The message was delivered to another client, or was purged from the + queue for some other reason. +</constant> + <constant name="content too large" value="311" class="soft error"> + The client attempted to transfer content larger than the server + could accept at the present time. The client may retry at a later + time. +</constant> + <constant name="connection forced" value="320" class="hard error"> + An operator intervened to close the connection for some reason. + The client may retry at some later date. +</constant> + <constant name="invalid path" value="402" class="hard error"> + The client tried to work with an unknown virtual host or cluster. +</constant> + <constant name="access refused" value="403" class="soft error"> + The client attempted to work with a server entity to which it has + no due to security settings. +</constant> + <constant name="not found" value="404" class="soft error"> + The client attempted to work with a server entity that does not exist. +</constant> + <constant name="resource locked" value="405" class="soft error"> + The client attempted to work with a server entity to which it has + no access because another client is working with it. +</constant> + <constant name="frame error" value="501" class="hard error"> + The client sent a malformed frame that the server could not decode. + This strongly implies a programming error in the client. +</constant> + <constant name="syntax error" value="502" class="hard error"> + The client sent a frame that contained illegal values for one or more + fields. This strongly implies a programming error in the client. +</constant> + <constant name="command invalid" value="503" class="hard error"> + The client sent an invalid sequence of frames, attempting to perform + an operation that was considered invalid by the server. This usually + implies a programming error in the client. +</constant> + <constant name="channel error" value="504" class="hard error"> + The client attempted to work with a channel that had not been + correctly opened. This most likely indicates a fault in the client + layer. +</constant> + <constant name="resource error" value="506" class="hard error"> + The server could not complete the method because it lacked sufficient + resources. This may be due to the client creating too many of some + type of entity. +</constant> + <constant name="not allowed" value="530" class="hard error"> + The client tried to work with some entity in a manner that is + prohibited by the server, due to security settings or by some other + criteria. +</constant> + <constant name="not implemented" value="540" class="hard error"> + The client tried to use functionality that is not implemented in the + server. +</constant> + <constant name="internal error" value="541" class="hard error"> + The server could not complete the method because of an internal error. + The server may require intervention by an operator in order to resume + normal operations. +</constant> + <!-- +====================================================== +== DOMAIN TYPES +====================================================== +--> + <domain name="access ticket" type="short"> + access ticket granted by server + <doc> + An access ticket granted by the server for a certain set of access + rights within a specific realm. Access tickets are valid within the + channel where they were created, and expire when the channel closes. + </doc> + <assert check="ne" value="0"/> + </domain> + <domain name="class id" type="short"/> + <domain name="consumer tag" type="shortstr"> + consumer tag + <doc> + Identifier for the consumer, valid within the current connection. + </doc> + <rule implement="MUST"> + The consumer tag is valid only within the channel from which the + consumer was created. I.e. a client MUST NOT create a consumer in + one channel and then use it in another. + </rule> + </domain> + <domain name="delivery tag" type="longlong"> + server-assigned delivery tag + <doc> + The server-assigned and channel-specific delivery tag + </doc> + <rule implement="MUST"> + The delivery tag is valid only within the channel from which the + message was received. I.e. a client MUST NOT receive a message on + one channel and then acknowledge it on another. + </rule> + <rule implement="MUST"> + The server MUST NOT use a zero value for delivery tags. Zero is + reserved for client use, meaning "all messages so far received". + </rule> + </domain> + <domain name="exchange name" type="shortstr"> + exchange name + <doc> + The exchange name is a client-selected string that identifies + the exchange for publish methods. Exchange names may consist + of any mixture of digits, letters, and underscores. Exchange + names are scoped by the virtual host. + </doc> + <assert check="length" value="127"/> + </domain> + <domain name="known hosts" type="shortstr"> +list of known hosts +<doc> +Specifies the list of equivalent or alternative hosts that the server +knows about, which will normally include the current server itself. +Clients can cache this information and use it when reconnecting to a +server after a failure. +</doc> + <rule implement="MAY"> +The server MAY leave this field empty if it knows of no other +hosts than itself. +</rule> + </domain> + <domain name="method id" type="short"/> + <domain name="no ack" type="bit"> + no acknowledgement needed + <doc> + If this field is set the server does not expect acknowledgments + for messages. That is, when a message is delivered to the client + the server automatically and silently acknowledges it on behalf + of the client. This functionality increases performance but at + the cost of reliability. Messages can get lost if a client dies + before it can deliver them to the application. + </doc> + </domain> + <domain name="no local" type="bit"> + do not deliver own messages + <doc> + If the no-local field is set the server will not send messages to + the client that published them. + </doc> + </domain> + <domain name="path" type="shortstr"> + <doc> + Must start with a slash "/" and continue with path names + separated by slashes. A path name consists of any combination + of at least one of [A-Za-z0-9] plus zero or more of [.-_+!=:]. +</doc> + <assert check="notnull"/> + <assert check="syntax" rule="path"/> + <assert check="length" value="127"/> + </domain> + <domain name="peer properties" type="table"> + <doc> +This string provides a set of peer properties, used for +identification, debugging, and general information. +</doc> + <rule implement="SHOULD"> +The properties SHOULD contain these fields: +"product", giving the name of the peer product, "version", giving +the name of the peer version, "platform", giving the name of the +operating system, "copyright", if appropriate, and "information", +giving other general information. +</rule> + </domain> + <domain name="queue name" type="shortstr"> + queue name + <doc> + The queue name identifies the queue within the vhost. Queue + names may consist of any mixture of digits, letters, and + underscores. + </doc> + <assert check="length" value="127"/> + </domain> + <domain name="redelivered" type="bit"> + message is being redelivered + <doc> + This indicates that the message has been previously delivered to + this or another client. + </doc> + <rule implement="SHOULD"> + The server SHOULD try to signal redelivered messages when it can. + When redelivering a message that was not successfully acknowledged, + the server SHOULD deliver it to the original client if possible. + </rule> + <rule implement="MUST"> + The client MUST NOT rely on the redelivered field but MUST take it + as a hint that the message may already have been processed. A + fully robust client must be able to track duplicate received messages + on non-transacted, and locally-transacted channels. + </rule> + </domain> + <domain name="reply code" type="short"> +reply code from server +<doc> + The reply code. The AMQ reply codes are defined in AMQ RFC 011. +</doc> + <assert check="notnull"/> + </domain> + <domain name="reply text" type="shortstr"> +localised reply text +<doc> + The localised reply text. This text can be logged as an aid to + resolving issues. +</doc> + <assert check="notnull"/> + </domain> + <class name="connection" handler="connection" index="10"> + <!-- +====================================================== +== CONNECTION +====================================================== +--> + work with socket connections +<doc> + The connection class provides methods for a client to establish a + network connection to a server, and for both peers to operate the + connection thereafter. +</doc> + <doc name="grammar"> + connection = open-connection *use-connection close-connection + open-connection = C:protocol-header + S:START C:START-OK + *challenge + S:TUNE C:TUNE-OK + C:OPEN S:OPEN-OK | S:REDIRECT + challenge = S:SECURE C:SECURE-OK + use-connection = *channel + close-connection = C:CLOSE S:CLOSE-OK + / S:CLOSE C:CLOSE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="start" synchronous="1" index="10"> + start connection negotiation + <doc> + This method starts the connection negotiation process by telling + the client the protocol version that the server proposes, along + with a list of security mechanisms which the client can use for + authentication. + </doc> + <rule implement="MUST"> + If the client cannot handle the protocol version suggested by the + server it MUST close the socket connection. + </rule> + <rule implement="MUST"> + The server MUST provide a protocol version that is lower than or + equal to that requested by the client in the protocol header. If + the server cannot support the specified protocol it MUST NOT send + this method, but MUST close the socket connection. + </rule> + <chassis name="client" implement="MUST"/> + <response name="start-ok"/> + <field name="version major" type="octet"> + protocol major version + <doc> + The protocol major version that the server agrees to use, which + cannot be higher than the client's major version. + </doc> + </field> + <field name="version minor" type="octet"> + protocol major version + <doc> + The protocol minor version that the server agrees to use, which + cannot be higher than the client's minor version. + </doc> + </field> + <field name="server properties" domain="peer properties"> + server properties + </field> + <field name="mechanisms" type="longstr"> + available security mechanisms + <doc> + A list of the security mechanisms that the server supports, delimited + by spaces. Currently ASL supports these mechanisms: PLAIN. + </doc> + <see name="security mechanisms"/> + <assert check="notnull"/> + </field> + <field name="locales" type="longstr"> + available message locales + <doc> + A list of the message locales that the server supports, delimited + by spaces. The locale defines the language in which the server + will send reply texts. + </doc> + <rule implement="MUST"> + All servers MUST support at least the en_US locale. + </rule> + <assert check="notnull"/> + </field> + </method> + <method name="start-ok" synchronous="1" index="11"> + select security mechanism and locale + <doc> + This method selects a SASL security mechanism. ASL uses SASL + (RFC2222) to negotiate authentication and encryption. + </doc> + <chassis name="server" implement="MUST"/> + <field name="client properties" domain="peer properties"> + client properties + </field> + <field name="mechanism" type="shortstr"> + selected security mechanism + <doc> + A single security mechanisms selected by the client, which must be + one of those specified by the server. + </doc> + <rule implement="SHOULD"> + The client SHOULD authenticate using the highest-level security + profile it can handle from the list provided by the server. + </rule> + <rule implement="MUST"> + The mechanism field MUST contain one of the security mechanisms + proposed by the server in the Start method. If it doesn't, the + server MUST close the socket. + </rule> + <assert check="notnull"/> + </field> + <field name="response" type="longstr"> + security response data + <doc> + A block of opaque data passed to the security mechanism. The contents + of this data are defined by the SASL security mechanism. For the + PLAIN security mechanism this is defined as a field table holding + two fields, LOGIN and PASSWORD. + </doc> + <assert check="notnull"/> + </field> + <field name="locale" type="shortstr"> + selected message locale + <doc> + A single message local selected by the client, which must be one + of those specified by the server. + </doc> + <assert check="notnull"/> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="secure" synchronous="1" index="20"> + security mechanism challenge + <doc> + The SASL protocol works by exchanging challenges and responses until + both peers have received sufficient information to authenticate each + other. This method challenges the client to provide more information. + </doc> + <chassis name="client" implement="MUST"/> + <response name="secure-ok"/> + <field name="challenge" type="longstr"> + security challenge data + <doc> + Challenge information, a block of opaque binary data passed to + the security mechanism. + </doc> + <see name="security mechanisms"/> + </field> + </method> + <method name="secure-ok" synchronous="1" index="21"> + security mechanism response + <doc> + This method attempts to authenticate, passing a block of SASL data + for the security mechanism at the server side. + </doc> + <chassis name="server" implement="MUST"/> + <field name="response" type="longstr"> + security response data + <doc> + A block of opaque data passed to the security mechanism. The contents + of this data are defined by the SASL security mechanism. + </doc> + <assert check="notnull"/> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="tune" synchronous="1" index="30"> + propose connection tuning parameters + <doc> + This method proposes a set of connection configuration values + to the client. The client can accept and/or adjust these. + </doc> + <chassis name="client" implement="MUST"/> + <response name="tune-ok"/> + <field name="channel max" type="short"> + proposed maximum channels + <doc> + The maximum total number of channels that the server allows + per connection. Zero means that the server does not impose a + fixed limit, but the number of allowed channels may be limited + by available server resources. + </doc> + </field> + <field name="frame max" type="long"> + proposed maximum frame size + <doc> + The largest frame size that the server proposes for the + connection. The client can negotiate a lower value. Zero means + that the server does not impose any specific limit but may reject + very large frames if it cannot allocate resources for them. + </doc> + <rule implement="MUST"> + Until the frame-max has been negotiated, both peers MUST accept + frames of up to 4096 octets large. The minimum non-zero value for + the frame-max field is 4096. + </rule> + </field> + <field name="heartbeat" type="short"> + desired heartbeat delay + <doc> + The delay, in seconds, of the connection heartbeat that the server + wants. Zero means the server does not want a heartbeat. + </doc> + </field> + </method> + <method name="tune-ok" synchronous="1" index="31"> + negotiate connection tuning parameters + <doc> + This method sends the client's connection tuning parameters to the + server. Certain fields are negotiated, others provide capability + information. + </doc> + <chassis name="server" implement="MUST"/> + <field name="channel max" type="short"> + negotiated maximum channels + <doc> + The maximum total number of channels that the client will use + per connection. May not be higher than the value specified by + the server. + </doc> + <rule implement="MAY"> + The server MAY ignore the channel-max value or MAY use it for + tuning its resource allocation. + </rule> + <assert check="notnull"/> + <assert check="le" method="tune" field="channel max"/> + </field> + <field name="frame max" type="long"> + negotiated maximum frame size + <doc> + The largest frame size that the client and server will use for + the connection. Zero means that the client does not impose any + specific limit but may reject very large frames if it cannot + allocate resources for them. Note that the frame-max limit + applies principally to content frames, where large contents + can be broken into frames of arbitrary size. + </doc> + <rule implement="MUST"> + Until the frame-max has been negotiated, both peers must accept + frames of up to 4096 octets large. The minimum non-zero value for + the frame-max field is 4096. + </rule> + </field> + <field name="heartbeat" type="short"> + desired heartbeat delay + <doc> + The delay, in seconds, of the connection heartbeat that the client + wants. Zero means the client does not want a heartbeat. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="open" synchronous="1" index="40"> + open connection to virtual host + <doc> + This method opens a connection to a virtual host, which is a + collection of resources, and acts to separate multiple application + domains within a server. + </doc> + <rule implement="MUST"> + The client MUST open the context before doing any work on the + connection. + </rule> + <chassis name="server" implement="MUST"/> + <response name="open-ok"/> + <response name="redirect"/> + <field name="virtual host" domain="path"> + virtual host name + <assert check="regexp" value="^[a-zA-Z0-9/-_]+$"/> + <doc> + The name of the virtual host to work with. + </doc> + <rule implement="MUST"> + If the server supports multiple virtual hosts, it MUST enforce a + full separation of exchanges, queues, and all associated entities + per virtual host. An application, connected to a specific virtual + host, MUST NOT be able to access resources of another virtual host. + </rule> + <rule implement="SHOULD"> + The server SHOULD verify that the client has permission to access + the specified virtual host. + </rule> + <rule implement="MAY"> + The server MAY configure arbitrary limits per virtual host, such + as the number of each type of entity that may be used, per + connection and/or in total. + </rule> + </field> + <field name="capabilities" type="shortstr"> + required capabilities + <doc> + The client may specify a number of capability names, delimited by + spaces. The server can use this string to how to process the + client's connection request. + </doc> + </field> + <field name="insist" type="bit"> + insist on connecting to server + <doc> + In a configuration with multiple load-sharing servers, the server + may respond to a Connection.Open method with a Connection.Redirect. + The insist option tells the server that the client is insisting on + a connection to the specified server. + </doc> + <rule implement="SHOULD"> + When the client uses the insist option, the server SHOULD accept + the client connection unless it is technically unable to do so. + </rule> + </field> + </method> + <method name="open-ok" synchronous="1" index="41"> + signal that the connection is ready + <doc> + This method signals to the client that the connection is ready for + use. + </doc> + <chassis name="client" implement="MUST"/> + <field name="known hosts" domain="known hosts"/> + </method> + <method name="redirect" synchronous="1" index="50"> + asks the client to use a different server + <doc> + This method redirects the client to another server, based on the + requested virtual host and/or capabilities. + </doc> + <rule implement="SHOULD"> + When getting the Connection.Redirect method, the client SHOULD + reconnect to the host specified, and if that host is not present, + to any of the hosts specified in the known-hosts list. + </rule> + <chassis name="client" implement="MAY"/> + <field name="host" type="shortstr"> + server to connect to + <doc> + Specifies the server to connect to. This is an IP address or a + DNS name, optionally followed by a colon and a port number. If + no port number is specified, the client should use the default + port number for the protocol. + </doc> + <assert check="notnull"/> + </field> + <field name="known hosts" domain="known hosts"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="close" synchronous="1" index="60"> + request a connection close + <doc> + This method indicates that the sender wants to close the connection. + This may be due to internal conditions (e.g. a forced shut-down) or + due to an error handling a specific method, i.e. an exception. When + a close is due to an exception, the sender provides the class and + method id of the method which caused the exception. + </doc> + <rule implement="MUST"> + After sending this method any received method except the Close-OK + method MUST be discarded. + </rule> + <rule implement="MAY"> + The peer sending this method MAY use a counter or timeout to + detect failure of the other peer to respond correctly with + the Close-OK method. + </rule> + <rule implement="MUST"> + When a server receives the Close method from a client it MUST + delete all server-side resources associated with the client's + context. A client CANNOT reconnect to a context after sending + or receiving a Close method. + </rule> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="close-ok"/> + <field name="reply code" domain="reply code"/> + <field name="reply text" domain="reply text"/> + <field name="class id" domain="class id"> + failing method class + <doc> + When the close is provoked by a method exception, this is the + class of the method. + </doc> + </field> + <field name="method id" domain="class id"> + failing method ID + <doc> + When the close is provoked by a method exception, this is the + ID of the method. + </doc> + </field> + </method> + <method name="close-ok" synchronous="1" index="61"> + confirm a connection close + <doc> + This method confirms a Connection.Close method and tells the + recipient that it is safe to release resources for the connection + and close the socket. + </doc> + <rule implement="SHOULD"> + A peer that detects a socket closure without having received a + Close-Ok handshake method SHOULD log the error. + </rule> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + </method> + </class> + <class name="channel" handler="channel" index="20"> + <!-- +====================================================== +== CHANNEL +====================================================== +--> + work with channels +<doc> + The channel class provides methods for a client to establish a virtual + connection - a channel - to a server and for both peers to operate the + virtual connection thereafter. +</doc> + <doc name="grammar"> + channel = open-channel *use-channel close-channel + open-channel = C:OPEN S:OPEN-OK + use-channel = C:FLOW S:FLOW-OK + / S:FLOW C:FLOW-OK + / S:ALERT + / functional-class + close-channel = C:CLOSE S:CLOSE-OK + / S:CLOSE C:CLOSE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="open" synchronous="1" index="10"> + open a channel for use + <doc> + This method opens a virtual connection (a channel). + </doc> + <rule implement="MUST"> + This method MUST NOT be called when the channel is already open. + </rule> + <chassis name="server" implement="MUST"/> + <response name="open-ok"/> + <field name="out of band" type="shortstr"> + out-of-band settings + <doc> + Configures out-of-band transfers on this channel. The syntax and + meaning of this field will be formally defined at a later date. + </doc> + <assert check="null"/> + </field> + </method> + <method name="open-ok" synchronous="1" index="11"> + signal that the channel is ready + <doc> + This method signals to the client that the channel is ready for use. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="flow" synchronous="1" index="20"> + enable/disable flow from peer + <doc> + This method asks the peer to pause or restart the flow of content + data. This is a simple flow-control mechanism that a peer can use + to avoid oveflowing its queues or otherwise finding itself receiving + more messages than it can process. Note that this method is not + intended for window control. The peer that receives a request to + stop sending content should finish sending the current content, if + any, and then wait until it receives a Flow restart method. + </doc> + <rule implement="MAY"> + When a new channel is opened, it is active. Some applications + assume that channels are inactive until started. To emulate this + behaviour a client MAY open the channel, then pause it. + </rule> + <rule implement="SHOULD"> + When sending content data in multiple frames, a peer SHOULD monitor + the channel for incoming methods and respond to a Channel.Flow as + rapidly as possible. + </rule> + <rule implement="MAY"> + A peer MAY use the Channel.Flow method to throttle incoming content + data for internal reasons, for example, when exchangeing data over a + slower connection. + </rule> + <rule implement="MAY"> + The peer that requests a Channel.Flow method MAY disconnect and/or + ban a peer that does not respect the request. + </rule> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <response name="flow-ok"/> + <field name="active" type="bit"> + start/stop content frames + <doc> + If 1, the peer starts sending content frames. If 0, the peer + stops sending content frames. + </doc> + </field> + </method> + <method name="flow-ok" index="21"> + confirm a flow method + <doc> + Confirms to the peer that a flow command was received and processed. + </doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <field name="active" type="bit"> + current flow setting + <doc> + Confirms the setting of the processed flow method: 1 means the + peer will start sending or continue to send content frames; 0 + means it will not. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="alert" index="30"> + send a non-fatal warning message + <doc> + This method allows the server to send a non-fatal warning to the + client. This is used for methods that are normally asynchronous + and thus do not have confirmations, and for which the server may + detect errors that need to be reported. Fatal errors are handled + as channel or connection exceptions; non-fatal errors are sent + through this method. + </doc> + <chassis name="client" implement="MUST"/> + <field name="reply code" domain="reply code"/> + <field name="reply text" domain="reply text"/> + <field name="details" type="table"> + detailed information for warning + <doc> + A set of fields that provide more information about the + problem. The meaning of these fields are defined on a + per-reply-code basis (TO BE DEFINED). + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="close" synchronous="1" index="40"> + request a channel close + <doc> + This method indicates that the sender wants to close the channel. + This may be due to internal conditions (e.g. a forced shut-down) or + due to an error handling a specific method, i.e. an exception. When + a close is due to an exception, the sender provides the class and + method id of the method which caused the exception. + </doc> + <rule implement="MUST"> + After sending this method any received method except + Channel.Close-OK MUST be discarded. + </rule> + <rule implement="MAY"> + The peer sending this method MAY use a counter or timeout to detect + failure of the other peer to respond correctly with Channel.Close-OK.. + </rule> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="close-ok"/> + <field name="reply code" domain="reply code"/> + <field name="reply text" domain="reply text"/> + <field name="class id" domain="class id"> + failing method class + <doc> + When the close is provoked by a method exception, this is the + class of the method. + </doc> + </field> + <field name="method id" domain="method id"> + failing method ID + <doc> + When the close is provoked by a method exception, this is the + ID of the method. + </doc> + </field> + </method> + <method name="close-ok" synchronous="1" index="41"> + confirm a channel close + <doc> + This method confirms a Channel.Close method and tells the recipient + that it is safe to release resources for the channel and close the + socket. + </doc> + <rule implement="SHOULD"> + A peer that detects a socket closure without having received a + Channel.Close-Ok handshake method SHOULD log the error. + </rule> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + </method> + </class> + <class name="access" handler="connection" index="30"> + <!-- +====================================================== +== ACCESS CONTROL +====================================================== +--> + work with access tickets +<doc> + The protocol control access to server resources using access tickets. + A client must explicitly request access tickets before doing work. + An access ticket grants a client the right to use a specific set of + resources - called a "realm" - in specific ways. +</doc> + <doc name="grammar"> + access = C:REQUEST S:REQUEST-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="request" synchronous="1" index="10"> + request an access ticket + <doc> + This method requests an access ticket for an access realm. + The server responds by granting the access ticket. If the + client does not have access rights to the requested realm + this causes a connection exception. Access tickets are a + per-channel resource. + </doc> + <rule implement="MUST"> + The realm name MUST start with either "/data" (for application + resources) or "/admin" (for server administration resources). + If the realm starts with any other path, the server MUST raise + a connection exception with reply code 403 (access refused). + </rule> + <rule implement="MUST"> + The server MUST implement the /data realm and MAY implement the + /admin realm. The mapping of resources to realms is not + defined in the protocol - this is a server-side configuration + issue. + </rule> + <chassis name="server" implement="MUST"/> + <response name="request-ok"/> + <field name="realm" domain="path"> + name of requested realm + <rule implement="MUST"> + If the specified realm is not known to the server, the server + must raise a channel exception with reply code 402 (invalid + path). + </rule> + </field> + <field name="exclusive" type="bit"> + request exclusive access + <doc> + Request exclusive access to the realm. If the server cannot grant + this - because there are other active tickets for the realm - it + raises a channel exception. + </doc> + </field> + <field name="passive" type="bit"> + request passive access + <doc> + Request message passive access to the specified access realm. + Passive access lets a client get information about resources in + the realm but not to make any changes to them. + </doc> + </field> + <field name="active" type="bit"> + request active access + <doc> + Request message active access to the specified access realm. + Acvtive access lets a client get create and delete resources in + the realm. + </doc> + </field> + <field name="write" type="bit"> + request write access + <doc> + Request write access to the specified access realm. Write access + lets a client publish messages to all exchanges in the realm. + </doc> + </field> + <field name="read" type="bit"> + request read access + <doc> + Request read access to the specified access realm. Read access + lets a client consume messages from queues in the realm. + </doc> + </field> + </method> + <method name="request-ok" synchronous="1" index="11"> + grant access to server resources + <doc> + This method provides the client with an access ticket. The access + ticket is valid within the current channel and for the lifespan of + the channel. + </doc> + <rule implement="MUST"> + The client MUST NOT use access tickets except within the same + channel as originally granted. + </rule> + <rule implement="MUST"> + The server MUST isolate access tickets per channel and treat an + attempt by a client to mix these as a connection exception. + </rule> + <chassis name="client" implement="MUST"/> + <field name="ticket" domain="access ticket"/> + </method> + </class> + <class name="exchange" handler="channel" index="40"> + <!-- +====================================================== +== EXCHANGES (or "routers", if you prefer) +== (Or matchers, plugins, extensions, agents,... Routing is just one of +== the many fun things an exchange can do.) +====================================================== +--> + work with exchanges +<doc> + Exchanges match and distribute messages across queues. Exchanges can be + configured in the server or created at runtime. +</doc> + <doc name="grammar"> + exchange = C:DECLARE S:DECLARE-OK + / C:DELETE S:DELETE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <rule implement="MUST"> + <test>amq_exchange_19</test> + The server MUST implement the direct and fanout exchange types, and + predeclare the corresponding exchanges named amq.direct and amq.fanout + in each virtual host. The server MUST also predeclare a direct + exchange to act as the default exchange for content Publish methods + and for default queue bindings. +</rule> + <rule implement="SHOULD"> + <test>amq_exchange_20</test> + The server SHOULD implement the topic exchange type, and predeclare + the corresponding exchange named amq.topic in each virtual host. +</rule> + <rule implement="MAY"> + <test>amq_exchange_21</test> + The server MAY implement the system exchange type, and predeclare the + corresponding exchanges named amq.system in each virtual host. If the + client attempts to bind a queue to the system exchange, the server + MUST raise a connection exception with reply code 507 (not allowed). +</rule> + <rule implement="MUST"> + <test>amq_exchange_22</test> + The default exchange MUST be defined as internal, and be inaccessible + to the client except by specifying an empty exchange name in a content + Publish method. That is, the server MUST NOT let clients make explicit + bindings to this exchange. +</rule> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="declare" synchronous="1" index="10"> + declare exchange, create if needed + <doc> + This method creates an exchange if it does not already exist, and if the + exchange exists, verifies that it is of the correct and expected class. + </doc> + <rule implement="SHOULD"> + <test>amq_exchange_23</test> + The server SHOULD support a minimum of 16 exchanges per virtual host + and ideally, impose no limit except as defined by available resources. + </rule> + <chassis name="server" implement="MUST"/> + <response name="declare-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + When a client defines a new exchange, this belongs to the access realm + of the ticket used. All further work done with that exchange must be + done with an access ticket for the same realm. + </doc> + <rule implement="MUST"> + The client MUST provide a valid access ticket giving "active" access + to the realm in which the exchange exists or will be created, or + "passive" access if the if-exists flag is set. + </rule> + </field> + <field name="exchange" domain="exchange name"> + <rule implement="MUST"> + <test>amq_exchange_15</test> + Exchange names starting with "amq." are reserved for predeclared + and standardised exchanges. If the client attempts to create an + exchange starting with "amq.", the server MUST raise a channel + exception with reply code 403 (access refused). + </rule> + <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/> + </field> + <field name="type" type="shortstr"> + exchange type + <doc> + Each exchange belongs to one of a set of exchange types implemented + by the server. The exchange types define the functionality of the + exchange - i.e. how messages are routed through it. It is not valid + or meaningful to attempt to change the type of an existing exchange. + </doc> + <rule implement="MUST"> + <test>amq_exchange_16</test> + If the exchange already exists with a different type, the server + MUST raise a connection exception with a reply code 507 (not allowed). + </rule> + <rule implement="MUST"> + <test>amq_exchange_18</test> + If the server does not support the requested exchange type it MUST + raise a connection exception with a reply code 503 (command invalid). + </rule> + <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/> + </field> + <field name="passive" type="bit"> + do not create exchange + <doc> + If set, the server will not create the exchange. The client can use + this to check whether an exchange exists without modifying the server + state. + </doc> + <rule implement="MUST"> + <test>amq_exchange_05</test> + If set, and the exchange does not already exist, the server MUST + raise a channel exception with reply code 404 (not found). + </rule> + </field> + <field name="durable" type="bit"> + request a durable exchange + <doc> + If set when creating a new exchange, the exchange will be marked as + durable. Durable exchanges remain active when a server restarts. + Non-durable exchanges (transient exchanges) are purged if/when a + server restarts. + </doc> + <rule implement="MUST"> + <test>amq_exchange_24</test> + The server MUST support both durable and transient exchanges. + </rule> + <rule implement="MUST"> + The server MUST ignore the durable field if the exchange already + exists. + </rule> + </field> + <field name="auto delete" type="bit"> + auto-delete when unused + <doc> + If set, the exchange is deleted when all queues have finished + using it. + </doc> + <rule implement="SHOULD"> + <test>amq_exchange_02</test> + The server SHOULD allow for a reasonable delay between the point + when it determines that an exchange is not being used (or no longer + used), and the point when it deletes the exchange. At the least it + must allow a client to create an exchange and then bind a queue to + it, with a small but non-zero delay between these two actions. + </rule> + <rule implement="MUST"> + <test>amq_exchange_25</test> + The server MUST ignore the auto-delete field if the exchange already + exists. + </rule> + </field> + <field name="internal" type="bit"> + create internal exchange + <doc> + If set, the exchange may not be used directly by publishers, but + only when bound to other exchanges. Internal exchanges are used to + construct wiring that is not visible to applications. + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + <field name="arguments" type="table"> + arguments for declaration + <doc> + A set of arguments for the declaration. The syntax and semantics + of these arguments depends on the server implementation. This + field is ignored if passive is 1. + </doc> + </field> + </method> + <method name="declare-ok" synchronous="1" index="11"> + confirms an exchange declaration + <doc> + This method confirms a Declare method and confirms the name of the + exchange, essential for automatically-named exchanges. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="delete" synchronous="1" index="20"> + delete an exchange + <doc> + This method deletes an exchange. When an exchange is deleted all queue + bindings on the exchange are cancelled. + </doc> + <chassis name="server" implement="MUST"/> + <response name="delete-ok"/> + <field name="ticket" domain="access ticket"> + <rule implement="MUST"> + The client MUST provide a valid access ticket giving "active" + access rights to the exchange's access realm. + </rule> + </field> + <field name="exchange" domain="exchange name"> + <rule implement="MUST"> + <test>amq_exchange_11</test> + The exchange MUST exist. Attempting to delete a non-existing exchange + causes a channel exception. + </rule> + <assert check="notnull"/> + </field> + <field name="if unused" type="bit"> + delete only if unused + <doc> + If set, the server will only delete the exchange if it has no queue + bindings. If the exchange has queue bindings the server does not + delete it but raises a channel exception instead. + </doc> + <rule implement="SHOULD"> + <test>amq_exchange_12</test> + If set, the server SHOULD delete the exchange but only if it has + no queue bindings. + </rule> + <rule implement="SHOULD"> + <test>amq_exchange_13</test> + If set, the server SHOULD raise a channel exception if the exchange is in + use. + </rule> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + </method> + <method name="delete-ok" synchronous="1" index="21"> + confirm deletion of an exchange + <doc> + This method confirms the deletion of an exchange. + </doc> + <chassis name="client" implement="MUST"/> + </method> + </class> + <class name="queue" handler="channel" index="50"> + <!-- +====================================================== +== QUEUES +====================================================== +--> + work with queues + +<doc> + Queues store and forward messages. Queues can be configured in the server + or created at runtime. Queues must be attached to at least one exchange + in order to receive messages from publishers. +</doc> + <doc name="grammar"> + queue = C:DECLARE S:DECLARE-OK + / C:BIND S:BIND-OK + / C:PURGE S:PURGE-OK + / C:DELETE S:DELETE-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="MUST"/> + <rule implement="MUST"> + <test>amq_queue_33</test> + A server MUST allow any content class to be sent to any queue, in any + mix, and queue and delivery these content classes independently. Note + that all methods that fetch content off queues are specific to a given + content class. +</rule> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="declare" synchronous="1" index="10"> + declare queue, create if needed + <doc> + This method creates or checks a queue. When creating a new queue + the client can specify various properties that control the durability + of the queue and its contents, and the level of sharing for the queue. + </doc> + <rule implement="MUST"> + <test>amq_queue_34</test> + The server MUST create a default binding for a newly-created queue + to the default exchange, which is an exchange of type 'direct'. + </rule> + <rule implement="SHOULD"> + <test>amq_queue_35</test> + The server SHOULD support a minimum of 256 queues per virtual host + and ideally, impose no limit except as defined by available resources. + </rule> + <chassis name="server" implement="MUST"/> + <response name="declare-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + When a client defines a new queue, this belongs to the access realm + of the ticket used. All further work done with that queue must be + done with an access ticket for the same realm. + </doc> + <doc> + The client provides a valid access ticket giving "active" access + to the realm in which the queue exists or will be created, or + "passive" access if the if-exists flag is set. + </doc> + </field> + <field name="queue" domain="queue name"> + <rule implement="MAY"> + <test>amq_queue_10</test> + The queue name MAY be empty, in which case the server MUST create + a new queue with a unique generated name and return this to the + client in the Declare-Ok method. + </rule> + <rule implement="MUST"> + <test>amq_queue_32</test> + Queue names starting with "amq." are reserved for predeclared and + standardised server queues. If the queue name starts with "amq." + and the passive option is zero, the server MUST raise a connection + exception with reply code 403 (access refused). + </rule> + <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/> + </field> + <field name="passive" type="bit"> + do not create queue + <doc> + If set, the server will not create the queue. The client can use + this to check whether a queue exists without modifying the server + state. + </doc> + <rule implement="MUST"> + <test>amq_queue_05</test> + If set, and the queue does not already exist, the server MUST + respond with a reply code 404 (not found) and raise a channel + exception. + </rule> + </field> + <field name="durable" type="bit"> + request a durable queue + <doc> + If set when creating a new queue, the queue will be marked as + durable. Durable queues remain active when a server restarts. + Non-durable queues (transient queues) are purged if/when a + server restarts. Note that durable queues do not necessarily + hold persistent messages, although it does not make sense to + send persistent messages to a transient queue. + </doc> + <rule implement="MUST"> + <test>amq_queue_03</test> + The server MUST recreate the durable queue after a restart. + </rule> + <rule implement="MUST"> + <test>amq_queue_36</test> + The server MUST support both durable and transient queues. + </rule> + <rule implement="MUST"> + <test>amq_queue_37</test> + The server MUST ignore the durable field if the queue already + exists. + </rule> + </field> + <field name="exclusive" type="bit"> + request an exclusive queue + <doc> + Exclusive queues may only be consumed from by the current connection. + Setting the 'exclusive' flag always implies 'auto-delete'. + </doc> + <rule implement="MUST"> + <test>amq_queue_38</test> + The server MUST support both exclusive (private) and non-exclusive + (shared) queues. + </rule> + <rule implement="MUST"> + <test>amq_queue_04</test> + The server MUST raise a channel exception if 'exclusive' is specified + and the queue already exists and is owned by a different connection. + </rule> + </field> + <field name="auto delete" type="bit"> + auto-delete queue when unused + <doc> + If set, the queue is deleted when all consumers have finished + using it. Last consumer can be cancelled either explicitly or because + its channel is closed. If there was no consumer ever on the queue, it + won't be deleted. + </doc> + <rule implement="SHOULD"> + <test>amq_queue_02</test> + The server SHOULD allow for a reasonable delay between the point + when it determines that a queue is not being used (or no longer + used), and the point when it deletes the queue. At the least it + must allow a client to create a queue and then create a consumer + to read from it, with a small but non-zero delay between these + two actions. The server should equally allow for clients that may + be disconnected prematurely, and wish to re-consume from the same + queue without losing messages. We would recommend a configurable + timeout, with a suitable default value being one minute. + </rule> + <rule implement="MUST"> + <test>amq_queue_31</test> + The server MUST ignore the auto-delete field if the queue already + exists. + </rule> + </field> + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + <field name="arguments" type="table"> + arguments for declaration + <doc> + A set of arguments for the declaration. The syntax and semantics + of these arguments depends on the server implementation. This + field is ignored if passive is 1. + </doc> + </field> + </method> + <method name="declare-ok" synchronous="1" index="11"> + confirms a queue definition + <doc> + This method confirms a Declare method and confirms the name of the + queue, essential for automatically-named queues. + </doc> + <chassis name="client" implement="MUST"/> + <field name="queue" domain="queue name"> + <doc> + Reports the name of the queue. If the server generated a queue + name, this field contains that name. + </doc> + <assert check="notnull"/> + </field> + <field name="message count" type="long"> + number of messages in queue + <doc> + Reports the number of messages in the queue, which will be zero + for newly-created queues. + </doc> + </field> + <field name="consumer count" type="long"> + number of consumers + <doc> + Reports the number of active consumers for the queue. Note that + consumers can suspend activity (Channel.Flow) in which case they + do not appear in this count. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="bind" synchronous="1" index="20"> + bind queue to an exchange + <doc> + This method binds a queue to an exchange. Until a queue is + bound it will not receive any messages. In a classic messaging + model, store-and-forward queues are bound to a dest exchange + and subscription queues are bound to a dest_wild exchange. + </doc> + <rule implement="MUST"> + <test>amq_queue_25</test> + A server MUST allow ignore duplicate bindings - that is, two or + more bind methods for a specific queue, with identical arguments + - without treating these as an error. + </rule> + <rule implement="MUST"> + <test>amq_queue_39</test> + If a bind fails, the server MUST raise a connection exception. + </rule> + <rule implement="MUST"> + <test>amq_queue_12</test> + The server MUST NOT allow a durable queue to bind to a transient + exchange. If the client attempts this the server MUST raise a + channel exception. + </rule> + <rule implement="SHOULD"> + <test>amq_queue_13</test> + Bindings for durable queues are automatically durable and the + server SHOULD restore such bindings after a server restart. + </rule> + <rule implement="MUST"> + <test>amq_queue_17</test> + If the client attempts to an exchange that was declared as internal, + the server MUST raise a connection exception with reply code 530 + (not allowed). + </rule> + <rule implement="SHOULD"> + <test>amq_queue_40</test> + The server SHOULD support at least 4 bindings per queue, and + ideally, impose no limit except as defined by available resources. + </rule> + <chassis name="server" implement="MUST"/> + <response name="bind-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + The client provides a valid access ticket giving "active" + access rights to the queue's access realm. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to bind. If the queue name is + empty, refers to the current queue for the channel, which is + the last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue + name in this method is empty, the server MUST raise a connection + exception with reply code 530 (not allowed). + </doc> + <doc name = "rule" test = "amq_queue_26"> + If the queue does not exist the server MUST raise a channel exception + with reply code 404 (not found). + </doc> + </field> + + <field name="exchange" domain="exchange name"> + The name of the exchange to bind to. + <rule implement="MUST"> + <test>amq_queue_14</test> + If the exchange does not exist the server MUST raise a channel + exception with reply code 404 (not found). + </rule> + </field> + <field name="routing key" type="shortstr"> + message routing key + <doc> + Specifies the routing key for the binding. The routing key is + used for routing messages depending on the exchange configuration. + Not all exchanges use a routing key - refer to the specific + exchange documentation. If the routing key is empty and the queue + name is empty, the routing key will be the current queue for the + channel, which is the last declared queue. + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + + <field name="arguments" type="table"> + arguments for binding + <doc> + A set of arguments for the binding. The syntax and semantics of + these arguments depends on the exchange class. + </doc> + </field> + </method> + <method name="bind-ok" synchronous="1" index="21"> + confirm bind successful + <doc> + This method confirms that the bind was successful. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="purge" synchronous="1" index="30"> + purge a queue + <doc> + This method removes all messages from a queue. It does not cancel + consumers. Purged messages are deleted without any formal "undo" + mechanism. + </doc> + <rule implement="MUST"> + <test>amq_queue_15</test> + A call to purge MUST result in an empty queue. + </rule> + <rule implement="MUST"> + <test>amq_queue_41</test> + On transacted channels the server MUST not purge messages that have + already been sent to a client but not yet acknowledged. + </rule> + <rule implement="MAY"> + <test>amq_queue_42</test> + The server MAY implement a purge queue or log that allows system + administrators to recover accidentally-purged messages. The server + SHOULD NOT keep purged messages in the same storage spaces as the + live messages since the volumes of purged messages may get very + large. + </rule> + <chassis name="server" implement="MUST"/> + <response name="purge-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + The access ticket must be for the access realm that holds the + queue. + </doc> + <rule implement="MUST"> + The client MUST provide a valid access ticket giving "read" access + rights to the queue's access realm. Note that purging a queue is + equivalent to reading all messages and discarding them. + </rule> + </field> + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to purge. If the queue name is + empty, refers to the current queue for the channel, which is + the last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue + name in this method is empty, the server MUST raise a connection + exception with reply code 530 (not allowed). + </doc> + <doc name = "rule" test = "amq_queue_16"> + The queue must exist. Attempting to purge a non-existing queue + causes a channel exception. + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + </method> + <method name="purge-ok" synchronous="1" index="31"> + confirms a queue purge + <doc> + This method confirms the purge of a queue. + </doc> + <chassis name="client" implement="MUST"/> + <field name="message count" type="long"> + number of messages purged + <doc> + Reports the number of messages purged. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="delete" synchronous="1" index="40"> + delete a queue + <doc> + This method deletes a queue. When a queue is deleted any pending + messages are sent to a dead-letter queue if this is defined in the + server configuration, and all consumers on the queue are cancelled. + </doc> + <rule implement="SHOULD"> + <test>amq_queue_43</test> + The server SHOULD use a dead-letter queue to hold messages that + were pending on a deleted queue, and MAY provide facilities for + a system administrator to move these messages back to an active + queue. + </rule> + <chassis name="server" implement="MUST"/> + <response name="delete-ok"/> + <field name="ticket" domain="access ticket"> + <doc> + The client provides a valid access ticket giving "active" + access rights to the queue's access realm. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to delete. If the queue name is + empty, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue + name in this method is empty, the server MUST raise a connection + exception with reply code 530 (not allowed). + </doc> + <doc name = "rule" test = "amq_queue_21"> + The queue must exist. Attempting to delete a non-existing queue + causes a channel exception. + </doc> + </field> + + <field name="if unused" type="bit"> + delete only if unused + <doc> + If set, the server will only delete the queue if it has no + consumers. If the queue has consumers the server does does not + delete it but raises a channel exception instead. + </doc> + <rule implement="MUST"> + <test>amq_queue_29</test> + <test>amq_queue_30</test> + The server MUST respect the if-unused flag when deleting a queue. + </rule> + </field> + <field name="if empty" type="bit"> + delete only if empty + <test>amq_queue_27</test> + <doc> + If set, the server will only delete the queue if it has no + messages. If the queue is not empty the server raises a channel + exception. + </doc> + </field> + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> + </method> + + <method name="delete-ok" synchronous="1" index="41"> + confirm deletion of a queue + <doc> + This method confirms the deletion of a queue. + </doc> + <chassis name="client" implement="MUST"/> + <field name="message count" type="long"> + number of messages purged + <doc> + Reports the number of messages purged. + </doc> + </field> + </method> + </class> + <class name="basic" handler="channel" index="60"> + <!-- +====================================================== +== BASIC MIDDLEWARE +====================================================== +--> + work with basic content +<doc> + The Basic class provides methods that support an industry-standard + messaging model. +</doc> + +<doc name = "grammar"> + basic = C:QOS S:QOS-OK + / C:CONSUME S:CONSUME-OK + / C:CANCEL S:CANCEL-OK + / C:PUBLISH content + / S:RETURN content + / S:DELIVER content + / C:GET ( S:GET-OK content / S:GET-EMPTY ) + / C:ACK + / C:REJECT +</doc> + +<chassis name = "server" implement = "MUST" /> +<chassis name = "client" implement = "MAY" /> + +<doc name = "rule" test = "amq_basic_08"> + The server SHOULD respect the persistent property of basic messages + and SHOULD make a best-effort to hold persistent basic messages on a + reliable storage mechanism. +</doc> +<doc name = "rule" test = "amq_basic_09"> + The server MUST NOT discard a persistent basic message in case of a + queue overflow. The server MAY use the Channel.Flow method to slow + or stop a basic message publisher when necessary. +</doc> +<doc name = "rule" test = "amq_basic_10"> + The server MAY overflow non-persistent basic messages to persistent + storage and MAY discard or dead-letter non-persistent basic messages + on a priority basis if the queue size exceeds some configured limit. +</doc> +<doc name = "rule" test = "amq_basic_11"> + The server MUST implement at least 2 priority levels for basic + messages, where priorities 0-4 and 5-9 are treated as two distinct + levels. The server MAY implement up to 10 priority levels. +</doc> +<doc name = "rule" test = "amq_basic_12"> + The server MUST deliver messages of the same priority in order + irrespective of their individual persistence. +</doc> +<doc name = "rule" test = "amq_basic_13"> + The server MUST support both automatic and explicit acknowledgements + on Basic content. +</doc> + +<!-- These are the properties for a Basic content --> + +<field name = "content type" type = "shortstr"> + MIME content type +</field> +<field name = "content encoding" type = "shortstr"> + MIME content encoding +</field> +<field name = "headers" type = "table"> + Message header field table +</field> +<field name = "delivery mode" type = "octet"> + Non-persistent (1) or persistent (2) +</field> +<field name = "priority" type = "octet"> + The message priority, 0 to 9 +</field> +<field name = "correlation id" type = "shortstr"> + The application correlation identifier +</field> +<field name = "reply to" type = "shortstr"> + The destination to reply to +</field> +<field name = "expiration" type = "shortstr"> + Message expiration specification +</field> +<field name = "message id" type = "shortstr"> + The application message identifier +</field> +<field name = "timestamp" type = "timestamp"> + The message timestamp +</field> +<field name = "type" type = "shortstr"> + The message type name +</field> +<field name = "user id" type = "shortstr"> + The creating user id +</field> +<field name = "app id" type = "shortstr"> + The creating application id +</field> +<field name = "cluster id" type = "shortstr"> + Intra-cluster routing identifier +</field> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "qos" synchronous = "1" index = "10"> + specify quality of service + <doc> + This method requests a specific quality of service. The QoS can + be specified for the current channel or for all channels on the + connection. The particular properties and semantics of a qos method + always depend on the content class semantics. Though the qos method + could in principle apply to both peers, it is currently meaningful + only for the server. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "qos-ok" /> + + <field name = "prefetch size" type = "long"> + prefetch window in octets + <doc> + The client can request that messages be sent in advance so that + when the client finishes processing a message, the following + message is already held locally, rather than needing to be sent + down the channel. Prefetching gives a performance improvement. + This field specifies the prefetch window size in octets. The + server will send a message in advance if it is equal to or + smaller in size than the available prefetch size (and also falls + into other prefetch limits). May be set to zero, meaning "no + specific limit", although other prefetch limits may still apply. + The prefetch-size is ignored if the no-ack option is set. + </doc> + <doc name = "rule" test = "amq_basic_17"> + The server MUST ignore this setting when the client is not + processing any messages - i.e. the prefetch size does not limit + the transfer of single messages to a client, only the sending in + advance of more messages while the client still has one or more + unacknowledged messages. + </doc> + </field> + + <field name = "prefetch count" type = "short"> + prefetch window in messages + <doc> + Specifies a prefetch window in terms of whole messages. This + field may be used in combination with the prefetch-size field; + a message will only be sent in advance if both prefetch windows + (and those at the channel and connection level) allow it. + The prefetch-count is ignored if the no-ack option is set. + </doc> + <doc name = "rule" test = "amq_basic_18"> + The server MAY send less data in advance than allowed by the + client's specified prefetch windows but it MUST NOT send more. + </doc> + </field> + + <field name = "global" type = "bit"> + apply to entire connection + <doc> + By default the QoS settings apply to the current channel only. If + this field is set, they are applied to the entire connection. + </doc> + </field> +</method> + +<method name = "qos-ok" synchronous = "1" index = "11"> + confirm the requested qos + <doc> + This method tells the client that the requested QoS levels could + be handled by the server. The requested QoS applies to all active + consumers until a new QoS is defined. + </doc> + <chassis name = "client" implement = "MUST" /> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "consume" synchronous = "1" index = "20"> + start a queue consumer + <doc> + This method asks the server to start a "consumer", which is a + transient request for messages from a specific queue. Consumers + last as long as the channel they were created on, or until the + client cancels them. + </doc> + <doc name = "rule" test = "amq_basic_01"> + The server SHOULD support at least 16 consumers per queue, unless + the queue was declared as private, and ideally, impose no limit + except as defined by available resources. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "consume-ok" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" access + rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Specifies the identifier for the consumer. The consumer tag is + local to a connection, so two clients can use the same consumer + tags. If this field is empty the server will generate a unique + tag. + </doc> + <doc name = "rule" test = "todo"> + The tag MUST NOT refer to an existing consumer. If the client + attempts to create two consumers with the same non-empty tag + the server MUST raise a connection exception with reply code + 530 (not allowed). + </doc> + </field> + + <field name = "no local" domain = "no local" /> + + <field name = "no ack" domain = "no ack" /> + + <field name = "exclusive" type = "bit"> + request exclusive access + <doc> + Request exclusive consumer access, meaning only this consumer can + access the queue. + </doc> + <doc name = "rule" test = "amq_basic_02"> + If the server cannot grant exclusive access to the queue when asked, + - because there are other consumers active - it MUST raise a channel + exception with return code 403 (access refused). + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "consume-ok" synchronous = "1" index = "21"> + confirm a new consumer + <doc> + The server provides the client with a consumer tag, which is used + by the client for methods called on the consumer at a later stage. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Holds the consumer tag specified by the client or provided by + the server. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "cancel" synchronous = "1" index = "30"> + end a queue consumer + <doc test = "amq_basic_04"> + This method cancels a consumer. This does not affect already + delivered messages, but it does mean the server will not send any + more messages for that consumer. The client may receive an + abitrary number of messages in between sending the cancel method + and receiving the cancel-ok reply. + </doc> + <doc name = "rule" test = "todo"> + If the queue no longer exists when the client sends a cancel command, + or the consumer has been cancelled for other reasons, this command + has no effect. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "cancel-ok" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "cancel-ok" synchronous = "1" index = "31"> + confirm a cancelled consumer + <doc> + This method confirms that the cancellation was completed. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "publish" content = "1" index = "40"> + publish a message + <doc> + This method publishes a message to a specific exchange. The message + will be routed to queues as defined by the exchange configuration + and distributed to any active consumers when the transaction, if any, + is committed. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "write" + access rights to the access realm for the exchange. + </doc> + </field> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange to publish to. The exchange + name can be empty, meaning the default exchange. If the exchange + name is specified, and that exchange does not exist, the server + will raise a channel exception. + </doc> + <doc name = "rule" test = "amq_basic_06"> + The server MUST accept a blank exchange name to mean the default + exchange. + </doc> + <doc name = "rule" test = "amq_basic_14"> + If the exchange was declared as an internal exchange, the server + MUST raise a channel exception with a reply code 403 (access + refused). + </doc> + <doc name = "rule" test = "amq_basic_15"> + The exchange MAY refuse basic content in which case it MUST raise + a channel exception with reply code 540 (not implemented). + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + + <field name = "mandatory" type = "bit"> + indicate mandatory routing + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue. If this flag is set, the server will return an + unroutable message with a Return method. If this flag is zero, the + server silently drops the message. + </doc> + <doc name = "rule" test = "amq_basic_07"> + The server SHOULD implement the mandatory flag. + </doc> + </field> + + <field name = "immediate" type = "bit"> + request immediate delivery + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue consumer immediately. If this flag is set, the + server will return an undeliverable message with a Return method. + If this flag is zero, the server will queue the message, but with + no guarantee that it will ever be consumed. + </doc> + <doc name = "rule" test = "amq_basic_16"> + The server SHOULD implement the immediate flag. + </doc> + </field> +</method> + +<method name = "return" content = "1" index = "50"> + return a failed message + <doc> + This method returns an undeliverable message that was published + with the "immediate" flag set, or an unroutable message published + with the "mandatory" flag set. The reply code and text provide + information about the reason that the message was undeliverable. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "reply code" domain = "reply code" /> + <field name = "reply text" domain = "reply text" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "deliver" content = "1" index = "60"> + notify the client of a consumer message + <doc> + This method delivers a message to the client, via a consumer. In + the asynchronous message delivery model, the client starts a + consumer using the Consume method, then the server responds with + Deliver methods as and when messages arrive for that consumer. + </doc> + <doc name = "rule" test = "amq_basic_19"> + The server SHOULD track the number of times a message has been + delivered to clients and when a message is redelivered a certain + number of times - e.g. 5 times - without being acknowledged, the + server SHOULD consider the message to be unprocessable (possibly + causing client applications to abort), and move the message to a + dead letter queue. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "redelivered" domain = "redelivered" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "get" synchronous = "1" index = "70"> + direct access to a queue + <doc> + This method provides a direct access to the messages in a queue + using a synchronous dialogue that is designed for specific types of + application where synchronous functionality is more important than + performance. + </doc> + <response name = "get-ok" /> + <response name = "get-empty" /> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" + access rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "no ack" domain = "no ack" /> +</method> + +<method name = "get-ok" synchronous = "1" content = "1" index = "71"> + provide client with a message + <doc> + This method delivers a message to the client following a get + method. A message delivered by 'get-ok' must be acknowledged + unless the no-ack option was set in the get method. + </doc> + <chassis name = "client" implement = "MAY" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "redelivered" domain = "redelivered" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was originally + published to. If empty, the message was published to the default + exchange. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> + + <field name = "message count" type = "long" > + number of messages pending + <doc> + This field reports the number of messages pending on the queue, + excluding the message being delivered. Note that this figure is + indicative, not reliable, and can change arbitrarily as messages + are added to the queue and removed by other clients. + </doc> + </field> +</method> + + +<method name = "get-empty" synchronous = "1" index = "72"> + indicate no messages available + <doc> + This method tells the client that the queue has no messages + available for the client. + </doc> + <chassis name = "client" implement = "MAY" /> + + <field name = "cluster id" type = "shortstr"> + Cluster id + <doc> + For use by cluster applications, should not be used by + client applications. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "ack" index = "80"> + acknowledge one or more messages + <doc> + This method acknowledges one or more messages delivered via the + Deliver or Get-Ok methods. The client can ask to confirm a + single message or a set of messages up to and including a specific + message. + </doc> + <chassis name = "server" implement = "MUST" /> + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "multiple" type = "bit"> + acknowledge multiple messages + <doc> + If set to 1, the delivery tag is treated as "up to and including", + so that the client can acknowledge multiple messages with a single + method. If set to zero, the delivery tag refers to a single + message. If the multiple field is 1, and the delivery tag is zero, + tells the server to acknowledge all outstanding mesages. + </doc> + <doc name = "rule" test = "amq_basic_20"> + The server MUST validate that a non-zero delivery-tag refers to an + delivered message, and raise a channel exception if this is not the + case. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "reject" index = "90"> + reject an incoming message + <doc> + This method allows a client to reject a message. It can be used to + interrupt and cancel large incoming messages, or return untreatable + messages to their original queue. + </doc> + <doc name = "rule" test = "amq_basic_21"> + The server SHOULD be capable of accepting and process the Reject + method while sending message content with a Deliver or Get-Ok + method. I.e. the server should read and process incoming methods + while sending output frames. To cancel a partially-send content, + the server sends a content body frame of size 1 (i.e. with no data + except the frame-end octet). + </doc> + <doc name = "rule" test = "amq_basic_22"> + The server SHOULD interpret this method as meaning that the client + is unable to process the message at this time. + </doc> + <doc name = "rule"> + A client MUST NOT use this method as a means of selecting messages + to process. A rejected message MAY be discarded or dead-lettered, + not necessarily passed to another client. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be discarded. If this bit + is 1, the server will attempt to requeue the message. + </doc> + <doc name = "rule" test = "amq_basic_23"> + The server MUST NOT deliver the message to the same client within + the context of the current channel. The recommended strategy is + to attempt to deliver the message to an alternative consumer, and + if that is not possible, to move the message to a dead-letter + queue. The server MAY use more sophisticated tracking to hold + the message on the queue and redeliver it to the same client at + a later stage. + </doc> + </field> +</method> + +<method name = "recover" index = "100"> + redeliver unacknowledged messages. This method is only allowed on non-transacted channels. + <doc> + This method asks the broker to redeliver all unacknowledged messages on a + specifieid channel. Zero or more messages may be redelivered. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be redelivered to the original recipient. If this bit + is 1, the server will attempt to requeue the message, potentially then delivering it to an + alternative subscriber. + </doc> + </field> + + <doc name="rule"> + The server MUST set the redelivered flag on all messages that are resent. + </doc> + <doc name="rule"> + The server MUST raise a channel exception if this is called on a transacted channel. + </doc> +</method> + + +</class> + + + <class name="file" handler="channel" index="70"> + <!-- +====================================================== +== FILE TRANSFER +====================================================== +--> + work with file content +<doc> + The file class provides methods that support reliable file transfer. + File messages have a specific set of properties that are required for + interoperability with file transfer applications. File messages and + acknowledgements are subject to channel transactions. Note that the + file class does not provide message browsing methods; these are not + compatible with the staging model. Applications that need browsable + file transfer should use Basic content and the Basic class. +</doc> + +<doc name = "grammar"> + file = C:QOS S:QOS-OK + / C:CONSUME S:CONSUME-OK + / C:CANCEL S:CANCEL-OK + / C:OPEN S:OPEN-OK C:STAGE content + / S:OPEN C:OPEN-OK S:STAGE content + / C:PUBLISH + / S:DELIVER + / S:RETURN + / C:ACK + / C:REJECT +</doc> + +<chassis name = "server" implement = "MAY" /> +<chassis name = "client" implement = "MAY" /> + +<doc name = "rule"> + The server MUST make a best-effort to hold file messages on a + reliable storage mechanism. +</doc> +<doc name = "rule"> + The server MUST NOT discard a file message in case of a queue + overflow. The server MUST use the Channel.Flow method to slow or stop + a file message publisher when necessary. +</doc> +<doc name = "rule"> + The server MUST implement at least 2 priority levels for file + messages, where priorities 0-4 and 5-9 are treated as two distinct + levels. The server MAY implement up to 10 priority levels. +</doc> +<doc name = "rule"> + The server MUST support both automatic and explicit acknowledgements + on file content. +</doc> + +<!-- These are the properties for a File content --> + +<field name = "content type" type = "shortstr"> + MIME content type +</field> +<field name = "content encoding" type = "shortstr"> + MIME content encoding +</field> +<field name = "headers" type = "table"> + Message header field table +</field> +<field name = "priority" type = "octet"> + The message priority, 0 to 9 +</field> +<field name = "reply to" type = "shortstr"> + The destination to reply to +</field> +<field name = "message id" type = "shortstr"> + The application message identifier +</field> +<field name = "filename" type = "shortstr"> + The message filename +</field> +<field name = "timestamp" type = "timestamp"> + The message timestamp +</field> +<field name = "cluster id" type = "shortstr"> + Intra-cluster routing identifier +</field> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "qos" synchronous = "1" index = "10"> + specify quality of service + <doc> + This method requests a specific quality of service. The QoS can + be specified for the current channel or for all channels on the + connection. The particular properties and semantics of a qos method + always depend on the content class semantics. Though the qos method + could in principle apply to both peers, it is currently meaningful + only for the server. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "qos-ok" /> + + <field name = "prefetch size" type = "long"> + prefetch window in octets + <doc> + The client can request that messages be sent in advance so that + when the client finishes processing a message, the following + message is already held locally, rather than needing to be sent + down the channel. Prefetching gives a performance improvement. + This field specifies the prefetch window size in octets. May be + set to zero, meaning "no specific limit". Note that other + prefetch limits may still apply. The prefetch-size is ignored + if the no-ack option is set. + </doc> + </field> + + <field name = "prefetch count" type = "short"> + prefetch window in messages + <doc> + Specifies a prefetch window in terms of whole messages. This + is compatible with some file API implementations. This field + may be used in combination with the prefetch-size field; a + message will only be sent in advance if both prefetch windows + (and those at the channel and connection level) allow it. + The prefetch-count is ignored if the no-ack option is set. + </doc> + <doc name = "rule"> + The server MAY send less data in advance than allowed by the + client's specified prefetch windows but it MUST NOT send more. + </doc> + </field> + + <field name = "global" type = "bit"> + apply to entire connection + <doc> + By default the QoS settings apply to the current channel only. If + this field is set, they are applied to the entire connection. + </doc> + </field> +</method> + +<method name = "qos-ok" synchronous = "1" index = "11"> + confirm the requested qos + <doc> + This method tells the client that the requested QoS levels could + be handled by the server. The requested QoS applies to all active + consumers until a new QoS is defined. + </doc> + <chassis name = "client" implement = "MUST" /> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "consume" synchronous = "1" index = "20"> + start a queue consumer + <doc> + This method asks the server to start a "consumer", which is a + transient request for messages from a specific queue. Consumers + last as long as the channel they were created on, or until the + client cancels them. + </doc> + <doc name = "rule"> + The server SHOULD support at least 16 consumers per queue, unless + the queue was declared as private, and ideally, impose no limit + except as defined by available resources. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "consume-ok" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" access + rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Specifies the identifier for the consumer. The consumer tag is + local to a connection, so two clients can use the same consumer + tags. If this field is empty the server will generate a unique + tag. + </doc> + <doc name = "rule" test = "todo"> + The tag MUST NOT refer to an existing consumer. If the client + attempts to create two consumers with the same non-empty tag + the server MUST raise a connection exception with reply code + 530 (not allowed). + </doc> + </field> + + <field name = "no local" domain = "no local" /> + + <field name = "no ack" domain = "no ack" /> + + <field name = "exclusive" type = "bit"> + request exclusive access + <doc> + Request exclusive consumer access, meaning only this consumer can + access the queue. + </doc> + <doc name = "rule" test = "amq_file_00"> + If the server cannot grant exclusive access to the queue when asked, + - because there are other consumers active - it MUST raise a channel + exception with return code 405 (resource locked). + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "consume-ok" synchronous = "1" index = "21"> + confirm a new consumer + <doc> + This method provides the client with a consumer tag which it MUST + use in methods that work with the consumer. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Holds the consumer tag specified by the client or provided by + the server. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "cancel" synchronous = "1" index = "30"> + end a queue consumer + <doc> + This method cancels a consumer. This does not affect already + delivered messages, but it does mean the server will not send any + more messages for that consumer. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "cancel-ok" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "cancel-ok" synchronous = "1" index = "31"> + confirm a cancelled consumer + <doc> + This method confirms that the cancellation was completed. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "open" synchronous = "1" index = "40"> + request to start staging + <doc> + This method requests permission to start staging a message. Staging + means sending the message into a temporary area at the recipient end + and then delivering the message by referring to this temporary area. + Staging is how the protocol handles partial file transfers - if a + message is partially staged and the connection breaks, the next time + the sender starts to stage it, it can restart from where it left off. + </doc> + <response name = "open-ok" /> + <chassis name = "server" implement = "MUST" /> + <chassis name = "client" implement = "MUST" /> + + <field name = "identifier" type = "shortstr"> + staging identifier + <doc> + This is the staging identifier. This is an arbitrary string chosen + by the sender. For staging to work correctly the sender must use + the same staging identifier when staging the same message a second + time after recovery from a failure. A good choice for the staging + identifier would be the SHA1 hash of the message properties data + (including the original filename, revised time, etc.). + </doc> + </field> + + <field name = "content size" type = "longlong"> + message content size + <doc> + The size of the content in octets. The recipient may use this + information to allocate or check available space in advance, to + avoid "disk full" errors during staging of very large messages. + </doc> + <doc name = "rule"> + The sender MUST accurately fill the content-size field. + Zero-length content is permitted. + </doc> + </field> +</method> + +<method name = "open-ok" synchronous = "1" index = "41"> + confirm staging ready + <doc> + This method confirms that the recipient is ready to accept staged + data. If the message was already partially-staged at a previous + time the recipient will report the number of octets already staged. + </doc> + <response name = "stage" /> + <chassis name = "server" implement = "MUST" /> + <chassis name = "client" implement = "MUST" /> + + <field name = "staged size" type = "longlong"> + already staged amount + <doc> + The amount of previously-staged content in octets. For a new + message this will be zero. + </doc> + <doc name = "rule"> + The sender MUST start sending data from this octet offset in the + message, counting from zero. + </doc> + <doc name = "rule"> + The recipient MAY decide how long to hold partially-staged content + and MAY implement staging by always discarding partially-staged + content. However if it uses the file content type it MUST support + the staging methods. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "stage" content = "1" index = "50"> + stage message content + <doc> + This method stages the message, sending the message content to the + recipient from the octet offset specified in the Open-Ok method. + </doc> + <chassis name = "server" implement = "MUST" /> + <chassis name = "client" implement = "MUST" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "publish" index = "60"> + publish a message + <doc> + This method publishes a staged file message to a specific exchange. + The file message will be routed to queues as defined by the exchange + configuration and distributed to any active consumers when the + transaction, if any, is committed. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "write" + access rights to the access realm for the exchange. + </doc> + </field> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange to publish to. The exchange + name can be empty, meaning the default exchange. If the exchange + name is specified, and that exchange does not exist, the server + will raise a channel exception. + </doc> + <doc name = "rule"> + The server MUST accept a blank exchange name to mean the default + exchange. + </doc> + <doc name = "rule"> + If the exchange was declared as an internal exchange, the server + MUST respond with a reply code 403 (access refused) and raise a + channel exception. + </doc> + <doc name = "rule"> + The exchange MAY refuse file content in which case it MUST respond + with a reply code 540 (not implemented) and raise a channel + exception. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + + <field name = "mandatory" type = "bit"> + indicate mandatory routing + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue. If this flag is set, the server will return an + unroutable message with a Return method. If this flag is zero, the + server silently drops the message. + </doc> + <doc name = "rule" test = "amq_file_00"> + The server SHOULD implement the mandatory flag. + </doc> + </field> + + <field name = "immediate" type = "bit"> + request immediate delivery + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue consumer immediately. If this flag is set, the + server will return an undeliverable message with a Return method. + If this flag is zero, the server will queue the message, but with + no guarantee that it will ever be consumed. + </doc> + <doc name = "rule" test = "amq_file_00"> + The server SHOULD implement the immediate flag. + </doc> + </field> + + <field name = "identifier" type = "shortstr"> + staging identifier + <doc> + This is the staging identifier of the message to publish. The + message must have been staged. Note that a client can send the + Publish method asynchronously without waiting for staging to + finish. + </doc> + </field> +</method> + +<method name = "return" content = "1" index = "70"> + return a failed message + <doc> + This method returns an undeliverable message that was published + with the "immediate" flag set, or an unroutable message published + with the "mandatory" flag set. The reply code and text provide + information about the reason that the message was undeliverable. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "reply code" domain = "reply code" /> + <field name = "reply text" domain = "reply text" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "deliver" index = "80"> + notify the client of a consumer message + <doc> + This method delivers a staged file message to the client, via a + consumer. In the asynchronous message delivery model, the client + starts a consumer using the Consume method, then the server + responds with Deliver methods as and when messages arrive for + that consumer. + </doc> + <doc name = "rule"> + The server SHOULD track the number of times a message has been + delivered to clients and when a message is redelivered a certain + number of times - e.g. 5 times - without being acknowledged, the + server SHOULD consider the message to be unprocessable (possibly + causing client applications to abort), and move the message to a + dead letter queue. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "redelivered" domain = "redelivered" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was originally + published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> + + <field name = "identifier" type = "shortstr"> + staging identifier + <doc> + This is the staging identifier of the message to deliver. The + message must have been staged. Note that a server can send the + Deliver method asynchronously without waiting for staging to + finish. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "ack" index = "90"> + acknowledge one or more messages + <doc> + This method acknowledges one or more messages delivered via the + Deliver method. The client can ask to confirm a single message or + a set of messages up to and including a specific message. + </doc> + <chassis name = "server" implement = "MUST" /> + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "multiple" type = "bit"> + acknowledge multiple messages + <doc> + If set to 1, the delivery tag is treated as "up to and including", + so that the client can acknowledge multiple messages with a single + method. If set to zero, the delivery tag refers to a single + message. If the multiple field is 1, and the delivery tag is zero, + tells the server to acknowledge all outstanding mesages. + </doc> + <doc name = "rule"> + The server MUST validate that a non-zero delivery-tag refers to an + delivered message, and raise a channel exception if this is not the + case. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "reject" index = "100"> + reject an incoming message + <doc> + This method allows a client to reject a message. It can be used to + return untreatable messages to their original queue. Note that file + content is staged before delivery, so the client will not use this + method to interrupt delivery of a large message. + </doc> + <doc name = "rule"> + The server SHOULD interpret this method as meaning that the client + is unable to process the message at this time. + </doc> + <doc name = "rule"> + A client MUST NOT use this method as a means of selecting messages + to process. A rejected message MAY be discarded or dead-lettered, + not necessarily passed to another client. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be discarded. If this bit + is 1, the server will attempt to requeue the message. + </doc> + <doc name = "rule"> + The server MUST NOT deliver the message to the same client within + the context of the current channel. The recommended strategy is + to attempt to deliver the message to an alternative consumer, and + if that is not possible, to move the message to a dead-letter + queue. The server MAY use more sophisticated tracking to hold + the message on the queue and redeliver it to the same client at + a later stage. + </doc> + </field> +</method> + +</class> + + <class name="stream" handler="channel" index="80"> + <!-- +====================================================== +== STREAMING +====================================================== +--> + work with streaming content + +<doc> + The stream class provides methods that support multimedia streaming. + The stream class uses the following semantics: one message is one + packet of data; delivery is unacknowleged and unreliable; the consumer + can specify quality of service parameters that the server can try to + adhere to; lower-priority messages may be discarded in favour of high + priority messages. +</doc> + +<doc name = "grammar"> + stream = C:QOS S:QOS-OK + / C:CONSUME S:CONSUME-OK + / C:CANCEL S:CANCEL-OK + / C:PUBLISH content + / S:RETURN + / S:DELIVER content +</doc> + +<chassis name = "server" implement = "MAY" /> +<chassis name = "client" implement = "MAY" /> + +<doc name = "rule"> + The server SHOULD discard stream messages on a priority basis if + the queue size exceeds some configured limit. +</doc> +<doc name = "rule"> + The server MUST implement at least 2 priority levels for stream + messages, where priorities 0-4 and 5-9 are treated as two distinct + levels. The server MAY implement up to 10 priority levels. +</doc> +<doc name = "rule"> + The server MUST implement automatic acknowledgements on stream + content. That is, as soon as a message is delivered to a client + via a Deliver method, the server must remove it from the queue. +</doc> + + +<!-- These are the properties for a Stream content --> + +<field name = "content type" type = "shortstr"> + MIME content type +</field> +<field name = "content encoding" type = "shortstr"> + MIME content encoding +</field> +<field name = "headers" type = "table"> + Message header field table +</field> +<field name = "priority" type = "octet"> + The message priority, 0 to 9 +</field> +<field name = "timestamp" type = "timestamp"> + The message timestamp +</field> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "qos" synchronous = "1" index = "10"> + specify quality of service + <doc> + This method requests a specific quality of service. The QoS can + be specified for the current channel or for all channels on the + connection. The particular properties and semantics of a qos method + always depend on the content class semantics. Though the qos method + could in principle apply to both peers, it is currently meaningful + only for the server. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "qos-ok" /> + + <field name = "prefetch size" type = "long"> + prefetch window in octets + <doc> + The client can request that messages be sent in advance so that + when the client finishes processing a message, the following + message is already held locally, rather than needing to be sent + down the channel. Prefetching gives a performance improvement. + This field specifies the prefetch window size in octets. May be + set to zero, meaning "no specific limit". Note that other + prefetch limits may still apply. + </doc> + </field> + + <field name = "prefetch count" type = "short"> + prefetch window in messages + <doc> + Specifies a prefetch window in terms of whole messages. This + field may be used in combination with the prefetch-size field; + a message will only be sent in advance if both prefetch windows + (and those at the channel and connection level) allow it. + </doc> + </field> + + <field name = "consume rate" type = "long"> + transfer rate in octets/second + <doc> + Specifies a desired transfer rate in octets per second. This is + usually determined by the application that uses the streaming + data. A value of zero means "no limit", i.e. as rapidly as + possible. + </doc> + <doc name = "rule"> + The server MAY ignore the prefetch values and consume rates, + depending on the type of stream and the ability of the server + to queue and/or reply it. The server MAY drop low-priority + messages in favour of high-priority messages. + </doc> + </field> + + <field name = "global" type = "bit"> + apply to entire connection + <doc> + By default the QoS settings apply to the current channel only. If + this field is set, they are applied to the entire connection. + </doc> + </field> +</method> + +<method name = "qos-ok" synchronous = "1" index = "11"> + confirm the requested qos + <doc> + This method tells the client that the requested QoS levels could + be handled by the server. The requested QoS applies to all active + consumers until a new QoS is defined. + </doc> + <chassis name = "client" implement = "MUST" /> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "consume" synchronous = "1" index = "20"> + start a queue consumer + <doc> + This method asks the server to start a "consumer", which is a + transient request for messages from a specific queue. Consumers + last as long as the channel they were created on, or until the + client cancels them. + </doc> + <doc name = "rule"> + The server SHOULD support at least 16 consumers per queue, unless + the queue was declared as private, and ideally, impose no limit + except as defined by available resources. + </doc> + <doc name = "rule"> + Streaming applications SHOULD use different channels to select + different streaming resolutions. AMQP makes no provision for + filtering and/or transforming streams except on the basis of + priority-based selective delivery of individual messages. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "consume-ok" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "read" access + rights to the realm for the queue. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue to consume from. If the queue name + is null, refers to the current queue for the channel, which is the + last declared queue. + </doc> + <doc name = "rule"> + If the client did not previously declare a queue, and the queue name + in this method is empty, the server MUST raise a connection exception + with reply code 530 (not allowed). + </doc> + </field> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Specifies the identifier for the consumer. The consumer tag is + local to a connection, so two clients can use the same consumer + tags. If this field is empty the server will generate a unique + tag. + </doc> + <doc name = "rule" test = "todo"> + The tag MUST NOT refer to an existing consumer. If the client + attempts to create two consumers with the same non-empty tag + the server MUST raise a connection exception with reply code + 530 (not allowed). + </doc> + </field> + + <field name = "no local" domain = "no local" /> + + <field name = "exclusive" type = "bit"> + request exclusive access + <doc> + Request exclusive consumer access, meaning only this consumer can + access the queue. + </doc> + <doc name = "rule" test = "amq_file_00"> + If the server cannot grant exclusive access to the queue when asked, + - because there are other consumers active - it MUST raise a channel + exception with return code 405 (resource locked). + </doc> + </field> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + + +<method name = "consume-ok" synchronous = "1" index = "21"> + confirm a new consumer + <doc> + This method provides the client with a consumer tag which it may + use in methods that work with the consumer. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag"> + <doc> + Holds the consumer tag specified by the client or provided by + the server. + </doc> + </field> +</method> + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "cancel" synchronous = "1" index = "30"> + end a queue consumer + <doc> + This method cancels a consumer. Since message delivery is + asynchronous the client may continue to receive messages for + a short while after canceling a consumer. It may process or + discard these as appropriate. + </doc> + <chassis name = "server" implement = "MUST" /> + <response name = "cancel-ok" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "nowait" type = "bit"> + do not send a reply method + <doc> + If set, the server will not respond to the method. The client should + not wait for a reply method. If the server could not complete the + method it will raise a channel or connection exception. + </doc> + </field> +</method> + +<method name = "cancel-ok" synchronous = "1" index = "31"> + confirm a cancelled consumer + <doc> + This method confirms that the cancellation was completed. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "publish" content = "1" index = "40"> + publish a message + <doc> + This method publishes a message to a specific exchange. The message + will be routed to queues as defined by the exchange configuration + and distributed to any active consumers as appropriate. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "ticket" domain = "access ticket"> + <doc name = "rule"> + The client MUST provide a valid access ticket giving "write" + access rights to the access realm for the exchange. + </doc> + </field> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange to publish to. The exchange + name can be empty, meaning the default exchange. If the exchange + name is specified, and that exchange does not exist, the server + will raise a channel exception. + </doc> + <doc name = "rule"> + The server MUST accept a blank exchange name to mean the default + exchange. + </doc> + <doc name = "rule"> + If the exchange was declared as an internal exchange, the server + MUST respond with a reply code 403 (access refused) and raise a + channel exception. + </doc> + <doc name = "rule"> + The exchange MAY refuse stream content in which case it MUST + respond with a reply code 540 (not implemented) and raise a + channel exception. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + + <field name = "mandatory" type = "bit"> + indicate mandatory routing + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue. If this flag is set, the server will return an + unroutable message with a Return method. If this flag is zero, the + server silently drops the message. + </doc> + <doc name = "rule" test = "amq_stream_00"> + The server SHOULD implement the mandatory flag. + </doc> + </field> + + <field name = "immediate" type = "bit"> + request immediate delivery + <doc> + This flag tells the server how to react if the message cannot be + routed to a queue consumer immediately. If this flag is set, the + server will return an undeliverable message with a Return method. + If this flag is zero, the server will queue the message, but with + no guarantee that it will ever be consumed. + </doc> + <doc name = "rule" test = "amq_stream_00"> + The server SHOULD implement the immediate flag. + </doc> + </field> +</method> + +<method name = "return" content = "1" index = "50"> + return a failed message + <doc> + This method returns an undeliverable message that was published + with the "immediate" flag set, or an unroutable message published + with the "mandatory" flag set. The reply code and text provide + information about the reason that the message was undeliverable. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "reply code" domain = "reply code" /> + <field name = "reply text" domain = "reply text" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was + originally published to. + </doc> + </field> + + <field name = "routing key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key name specified when the message was + published. + </doc> + </field> +</method> + + +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + +<method name = "deliver" content = "1" index = "60"> + notify the client of a consumer message + <doc> + This method delivers a message to the client, via a consumer. In + the asynchronous message delivery model, the client starts a + consumer using the Consume method, then the server responds with + Deliver methods as and when messages arrive for that consumer. + </doc> + <chassis name = "client" implement = "MUST" /> + + <field name = "consumer tag" domain = "consumer tag" /> + + <field name = "delivery tag" domain = "delivery tag" /> + + <field name = "exchange" domain = "exchange name"> + <doc> + Specifies the name of the exchange that the message was originally + published to. + </doc> + </field> + + <field name = "queue" domain = "queue name"> + <doc> + Specifies the name of the queue that the message came from. Note + that a single channel can start many consumers on different + queues. + </doc> + <assert check = "notnull" /> + </field> +</method> + </class> + + <class name="tx" handler="channel" index="90"> + <!-- +====================================================== +== TRANSACTIONS +====================================================== +--> + work with standard transactions + +<doc> + Standard transactions provide so-called "1.5 phase commit". We can + ensure that work is never lost, but there is a chance of confirmations + being lost, so that messages may be resent. Applications that use + standard transactions must be able to detect and ignore duplicate + messages. +</doc> + <rule implement="SHOULD"> + An client using standard transactions SHOULD be able to track all + messages received within a reasonable period, and thus detect and + reject duplicates of the same message. It SHOULD NOT pass these to + the application layer. +</rule> + <doc name="grammar"> + tx = C:SELECT S:SELECT-OK + / C:COMMIT S:COMMIT-OK + / C:ROLLBACK S:ROLLBACK-OK +</doc> + <chassis name="server" implement="SHOULD"/> + <chassis name="client" implement="MAY"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="select" synchronous="1" index="10"> +select standard transaction mode + <doc> + This method sets the channel to use standard transactions. The + client must use this method at least once on a channel before + using the Commit or Rollback methods. + </doc> + <chassis name="server" implement="MUST"/> + <response name="select-ok"/> + </method> + <method name="select-ok" synchronous="1" index="11"> +confirm transaction mode + <doc> + This method confirms to the client that the channel was successfully + set to use standard transactions. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="commit" synchronous="1" index="20"> +commit the current transaction + <doc> + This method commits all messages published and acknowledged in + the current transaction. A new transaction starts immediately + after a commit. + </doc> + <chassis name="server" implement="MUST"/> + <response name="commit-ok"/> + </method> + <method name="commit-ok" synchronous="1" index="21"> +confirm a successful commit + <doc> + This method confirms to the client that the commit succeeded. + Note that if a commit fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="rollback" synchronous="1" index="30"> +abandon the current transaction + <doc> + This method abandons all messages published and acknowledged in + the current transaction. A new transaction starts immediately + after a rollback. + </doc> + <chassis name="server" implement="MUST"/> + <response name="rollback-ok"/> + </method> + <method name="rollback-ok" synchronous="1" index="31"> +confirm a successful rollback + <doc> + This method confirms to the client that the rollback succeeded. + Note that if an rollback fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + </class> + <class name="dtx" handler="channel" index="100"> + <!-- +====================================================== +== DISTRIBUTED TRANSACTIONS +====================================================== +--> + work with distributed transactions + +<doc> + Distributed transactions provide so-called "2-phase commit". The + AMQP distributed transaction model supports the X-Open XA + architecture and other distributed transaction implementations. + The Dtx class assumes that the server has a private communications + channel (not AMQP) to a distributed transaction coordinator. +</doc> + <doc name="grammar"> + dtx = C:SELECT S:SELECT-OK + C:START S:START-OK +</doc> + <chassis name="server" implement="MAY"/> + <chassis name="client" implement="MAY"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="select" synchronous="1" index="10"> +select standard transaction mode + <doc> + This method sets the channel to use distributed transactions. The + client must use this method at least once on a channel before + using the Start method. + </doc> + <chassis name="server" implement="MUST"/> + <response name="select-ok"/> + </method> + <method name="select-ok" synchronous="1" index="11"> +confirm transaction mode + <doc> + This method confirms to the client that the channel was successfully + set to use distributed transactions. + </doc> + <chassis name="client" implement="MUST"/> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="start" synchronous="1" index="20"> + start a new distributed transaction + <doc> + This method starts a new distributed transaction. This must be + the first method on a new channel that uses the distributed + transaction mode, before any methods that publish or consume + messages. + </doc> + <chassis name="server" implement="MAY"/> + <response name="start-ok"/> + <field name="dtx identifier" type="shortstr"> + transaction identifier + <doc> + The distributed transaction key. This identifies the transaction + so that the AMQP server can coordinate with the distributed + transaction coordinator. + </doc> + <assert check="notnull"/> + </field> + </method> + <method name="start-ok" synchronous="1" index="21"> + confirm the start of a new distributed transaction + <doc> + This method confirms to the client that the transaction started. + Note that if a start fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + </class> + <class name="tunnel" handler="tunnel" index="110"> + <!-- +====================================================== +== TUNNEL +====================================================== +--> + methods for protocol tunneling. + +<doc> + The tunnel methods are used to send blocks of binary data - which + can be serialised AMQP methods or other protocol frames - between + AMQP peers. +</doc> + <doc name="grammar"> + tunnel = C:REQUEST + / S:REQUEST +</doc> + <chassis name="server" implement="MAY"/> + <chassis name="client" implement="MAY"/> + <field name="headers" type="table"> + Message header field table +</field> + <field name="proxy name" type="shortstr"> + The identity of the tunnelling proxy +</field> + <field name="data name" type="shortstr"> + The name or type of the message being tunnelled +</field> + <field name="durable" type="octet"> + The message durability indicator +</field> + <field name="broadcast" type="octet"> + The message broadcast mode +</field> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="request" content="1" index="10"> + sends a tunnelled method + <doc> + This method tunnels a block of binary data, which can be an + encoded AMQP method or other data. The binary data is sent + as the content for the Tunnel.Request method. + </doc> + <chassis name="server" implement="MUST"/> + <field name="meta data" type="table"> + meta data for the tunnelled block + <doc> + This field table holds arbitrary meta-data that the sender needs + to pass to the recipient. + </doc> + </field> + </method> + </class> + <class name="test" handler="channel" index="120"> + <!-- +====================================================== +== TEST - CHECK FUNCTIONAL CAPABILITIES OF AN IMPLEMENTATION +====================================================== +--> + test functional primitives of the implementation + +<doc> + The test class provides methods for a peer to test the basic + operational correctness of another peer. The test methods are + intended to ensure that all peers respect at least the basic + elements of the protocol, such as frame and content organisation + and field types. We assume that a specially-designed peer, a + "monitor client" would perform such tests. +</doc> + <doc name="grammar"> + test = C:INTEGER S:INTEGER-OK + / S:INTEGER C:INTEGER-OK + / C:STRING S:STRING-OK + / S:STRING C:STRING-OK + / C:TABLE S:TABLE-OK + / S:TABLE C:TABLE-OK + / C:CONTENT S:CONTENT-OK + / S:CONTENT C:CONTENT-OK +</doc> + <chassis name="server" implement="MUST"/> + <chassis name="client" implement="SHOULD"/> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="integer" synchronous="1" index="10"> + test integer handling + <doc> + This method tests the peer's capability to correctly marshal integer + data. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="integer-ok"/> + <field name="integer 1" type="octet"> + octet test value + <doc> + An octet integer test value. + </doc> + </field> + <field name="integer 2" type="short"> + short test value + <doc> + A short integer test value. + </doc> + </field> + <field name="integer 3" type="long"> + long test value + <doc> + A long integer test value. + </doc> + </field> + <field name="integer 4" type="longlong"> + long-long test value + <doc> + A long long integer test value. + </doc> + </field> + <field name="operation" type="octet"> + operation to test + <doc> + The client must execute this operation on the provided integer + test fields and return the result. + </doc> + <assert check="enum"> + <value name="add">return sum of test values</value> + <value name="min">return lowest of test values</value> + <value name="max">return highest of test values</value> + </assert> + </field> + </method> + <method name="integer-ok" synchronous="1" index="11"> + report integer test result + <doc> + This method reports the result of an Integer method. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="result" type="longlong"> + result value + <doc> + The result of the tested operation. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="string" synchronous="1" index="20"> + test string handling + <doc> + This method tests the peer's capability to correctly marshal string + data. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="string-ok"/> + <field name="string 1" type="shortstr"> + short string test value + <doc> + An short string test value. + </doc> + </field> + <field name="string 2" type="longstr"> + long string test value + <doc> + A long string test value. + </doc> + </field> + <field name="operation" type="octet"> + operation to test + <doc> + The client must execute this operation on the provided string + test fields and return the result. + </doc> + <assert check="enum"> + <value name="add">return concatentation of test strings</value> + <value name="min">return shortest of test strings</value> + <value name="max">return longest of test strings</value> + </assert> + </field> + </method> + <method name="string-ok" synchronous="1" index="21"> + report string test result + <doc> + This method reports the result of a String method. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="result" type="longstr"> + result value + <doc> + The result of the tested operation. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="table" synchronous="1" index="30"> + test field table handling + <doc> + This method tests the peer's capability to correctly marshal field + table data. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="table-ok"/> + <field name="table" type="table"> + field table of test values + <doc> + A field table of test values. + </doc> + </field> + <field name="integer op" type="octet"> + operation to test on integers + <doc> + The client must execute this operation on the provided field + table integer values and return the result. + </doc> + <assert check="enum"> + <value name="add">return sum of numeric field values</value> + <value name="min">return min of numeric field values</value> + <value name="max">return max of numeric field values</value> + </assert> + </field> + <field name="string op" type="octet"> + operation to test on strings + <doc> + The client must execute this operation on the provided field + table string values and return the result. + </doc> + <assert check="enum"> + <value name="add">return concatenation of string field values</value> + <value name="min">return shortest of string field values</value> + <value name="max">return longest of string field values</value> + </assert> + </field> + </method> + <method name="table-ok" synchronous="1" index="31"> + report table test result + <doc> + This method reports the result of a Table method. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="integer result" type="longlong"> + integer result value + <doc> + The result of the tested integer operation. + </doc> + </field> + <field name="string result" type="longstr"> + string result value + <doc> + The result of the tested string operation. + </doc> + </field> + </method> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <method name="content" synchronous="1" content="1" index="40"> + test content handling + <doc> + This method tests the peer's capability to correctly marshal content. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <response name="content-ok"/> + </method> + <method name="content-ok" synchronous="1" content="1" index="41"> + report content test result + <doc> + This method reports the result of a Content method. It contains the + content checksum and echoes the original content as provided. + </doc> + <chassis name="client" implement="MUST"/> + <chassis name="server" implement="MUST"/> + <field name="content checksum" type="long"> + content hash + <doc> + The 32-bit checksum of the content, calculated by adding the + content into a 32-bit accumulator. + </doc> + </field> + </method> + </class> +</amqp> diff --git a/dotnet/Qpid.Common/build.xml b/dotnet/Qpid.Common/build.xml new file mode 100644 index 0000000000..fa3dd50338 --- /dev/null +++ b/dotnet/Qpid.Common/build.xml @@ -0,0 +1,64 @@ +<project name="AMQ Dot Net Framing Layer" default="generate"> + <property name="amq.home" value="../../.."/> + <path id="amq.home.path"> + <pathelement location="${amq.home}"/> + </path> + + <pathconvert targetos="unix" property="amq.home.fixed" refid="amq.home.path"/> + +<!-- + <property name="amq.asl" value="${amq.home.fixed}/amqp.org/specs/amqp.xml"/> +--> + <property name="amq.asl" value="amqp.xml"/> + + <property name="stylesheet" value="stylesheets/framing.xsl"/> + <property name="registry_stylesheet" value="stylesheets/registry.xsl"/> + <property name="registry_template" value="resources/registry.template"/> + <property name="saxon.jar" value="lib/saxon/saxon8.jar"/> + <property name="generated.src" value="generated"/> + <property name="static.src" value="src"/> + <property name="resources" value="resources"/> + <property name="base.lib" value="lib"/> + + <path id="project.classpath"> + <fileset dir="${base.lib}"> + <include name="**/*.jar"/> + </fileset> + </path> + + <target name="prepare"> + <mkdir dir="classes"/> + </target> + + <target name="regenerate" depends="clean, generate" description="generates code"> + </target> + + <target name="check-generate"> + <uptodate property="generateNotRequired" targetfile="${generated.src}/results.out" srcfile="${amq.asl}"/> + </target> + + <target name="generate" depends="check-generate" unless="${generateNotRequired}" description="generates code"> + <mkdir dir="${generated.src}"/> + <java jar="${saxon.jar}" fork="true"> + <arg value="-o"/> + <arg value="${generated.src}/results.out"/> + <arg value="${amq.asl}"/> + <arg value="${stylesheet}"/> + <arg value="asl_base=${asl.base}"/> + <arg value="registry_name=MainRegistry"/> + </java> + <java jar="${saxon.jar}" fork="true"> + <arg value="-o"/> + <arg value="${generated.src}/registry.out"/> + <arg value="${registry_template}"/> + <arg value="${registry_stylesheet}"/> + </java> + </target> + + <target name="clean" depends="prepare" description="deletes any products of the compile and generate tasks"> + <delete> + <fileset dir="classes" includes="**/*"/> + <fileset dir="${generated.src}" includes="**/*"/> + </delete> + </target> +</project> diff --git a/dotnet/Qpid.Common/default.build b/dotnet/Qpid.Common/default.build new file mode 100644 index 0000000000..5e4a063a06 --- /dev/null +++ b/dotnet/Qpid.Common/default.build @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<project name="XMS.AMQ.Common" default="build"> + <property name="nant.settings.currentframework" value="net-1.0" /> + <property name="basename" value="XMSCommon"/> + <property name="debug" value="true"/> + <property name="CommonCollectionsDir" value="../CommonCollections"/> + <property name="MINADir" value="../minadotnet"/> + + <if test="${debug}"> + <property name="targetdir" value="bin/${nant.settings.currentframework}/Debug"/> + </if> + <ifnot test="${debug}"> + <property name="targetdir" value="bin/${nant.settings.currentframework}/Release"/> + </ifnot> + + <target name="clean"> + <delete> + <fileset> + <include name="${targetdir}/${basename}.dll"/> + <include name="${targetdir}/${basename}.pdb"/> + </fileset> + </delete> + </target> + + <target name="init"> + <mkdir dir="${targetdir}"/> + </target> + + <target name="build" depends="init"> + <csc target="library" output="${targetdir}/${basename}.dll" debug="${debug}"> + <sources> + <include name="**/*.cs"/> + <exclude name="Properties/Settings.Designer.cs" /> + </sources> + <references> + <lib> + <include name="${CommonCollectionsDir}/${targetdir}" /> + <include name="${MINADir}/${targetdir}" /> + <include name="lib/**" /> + </lib> + <include name="CommonCollections.dll" /> + <include name="log4net.dll" /> + <include name="MINA.dll" /> + <include name="IBM.XMS.dll" /> + </references> + </csc> + </target> +</project>
\ No newline at end of file diff --git a/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt b/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/dotnet/Qpid.Common/lib/log4net/log4net.dll b/dotnet/Qpid.Common/lib/log4net/log4net.dll Binary files differnew file mode 100644 index 0000000000..995816f27b --- /dev/null +++ b/dotnet/Qpid.Common/lib/log4net/log4net.dll diff --git a/dotnet/Qpid.Common/lib/log4net/log4net.xml b/dotnet/Qpid.Common/lib/log4net/log4net.xml new file mode 100644 index 0000000000..b8fd000170 --- /dev/null +++ b/dotnet/Qpid.Common/lib/log4net/log4net.xml @@ -0,0 +1,28655 @@ +<?xml version="1.0"?> +<doc> + <assembly> + <name>log4net</name> + </assembly> + <members> + <member name="T:log4net.Appender.AdoNetAppender"> + <summary> + Appender that logs to a database. + </summary> + <remarks> + <para> + <see cref="T:log4net.Appender.AdoNetAppender"/> appends logging events to a table within a + database. The appender can be configured to specify the connection + string by setting the <see cref="P:log4net.Appender.AdoNetAppender.ConnectionString"/> property. + The connection type (provider) can be specified by setting the <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> + property. For more information on database connection strings for + your specific database see <a href="http://www.connectionstrings.com/">http://www.connectionstrings.com/</a>. + </para> + <para> + Records are written into the database either using a prepared + statement or a stored procedure. The <see cref="P:log4net.Appender.AdoNetAppender.CommandType"/> property + is set to <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>) to specify a prepared statement + or to <see cref="F:System.Data.CommandType.StoredProcedure"/> (<c>System.Data.CommandType.StoredProcedure</c>) to specify a stored + procedure. + </para> + <para> + The prepared statement text or the name of the stored procedure + must be set in the <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> property. + </para> + <para> + The prepared statement or stored procedure can take a number + of parameters. Parameters are added using the <see cref="M:log4net.Appender.AdoNetAppender.AddParameter(log4net.Appender.AdoNetAppenderParameter)"/> + method. This adds a single <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> to the + ordered list of parameters. The <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> + type may be subclassed if required to provide database specific + functionality. The <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> specifies + the parameter name, database type, size, and how the value should + be generated using a <see cref="T:log4net.Layout.ILayout"/>. + </para> + </remarks> + <example> + An example of a SQL Server table that could be logged to: + <code lang="SQL"> + CREATE TABLE [dbo].[Log] ( + [ID] [int] IDENTITY (1, 1) NOT NULL , + [Date] [datetime] NOT NULL , + [Thread] [varchar] (255) NOT NULL , + [Level] [varchar] (20) NOT NULL , + [Logger] [varchar] (255) NOT NULL , + [Message] [varchar] (4000) NOT NULL + ) ON [PRIMARY] + </code> + </example> + <example> + An example configuration to log to the above table: + <code lang="XML" escaped="true"> + <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender"> + <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> + <connectionString value="data source=SQLSVR;initial catalog=test_log4net;integrated security=false;persist security info=True;User ID=sa;Password=sa"/> + <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)"/> + <parameter> + <parameterName value="@log_date"/> + <dbType value="DateTime"/> + <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}"/> + </parameter> + <parameter> + <parameterName value="@thread"/> + <dbType value="String"/> + <size value="255"/> + <layout type="log4net.Layout.PatternLayout" value="%thread"/> + </parameter> + <parameter> + <parameterName value="@log_level"/> + <dbType value="String"/> + <size value="50"/> + <layout type="log4net.Layout.PatternLayout" value="%level"/> + </parameter> + <parameter> + <parameterName value="@logger"/> + <dbType value="String"/> + <size value="255"/> + <layout type="log4net.Layout.PatternLayout" value="%logger"/> + </parameter> + <parameter> + <parameterName value="@message"/> + <dbType value="String"/> + <size value="4000"/> + <layout type="log4net.Layout.PatternLayout" value="%message"/> + </parameter> + </appender> + </code> + </example> + <author>Julian Biddle</author> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Lance Nehring</author> + </member> + <member name="T:log4net.Appender.BufferingAppenderSkeleton"> + <summary> + Abstract base class implementation of <see cref="T:log4net.Appender.IAppender"/> that + buffers events in a fixed size buffer. + </summary> + <remarks> + <para> + This base class should be used by appenders that need to buffer a + number of events before logging them. For example the <see cref="T:log4net.Appender.AdoNetAppender"/> + buffers events and then submits the entire contents of the buffer to + the underlying database in one go. + </para> + <para> + Subclasses should override the <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/> + method to deliver the buffered events. + </para> + <para>The BufferingAppenderSkeleton maintains a fixed size cyclic + buffer of events. The size of the buffer is set using + the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> property. + </para> + <para>A <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> is used to inspect + each event as it arrives in the appender. If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> + triggers, then the current buffer is sent immediately + (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>). Otherwise the event + is stored in the buffer. For example, an evaluator can be used to + deliver the events immediately when an ERROR event arrives. + </para> + <para> + The buffering appender can be configured in a <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode. + By default the appender is NOT lossy. When the buffer is full all + the buffered events are sent with <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>. + If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> property is set to <c>true</c> then the + buffer will not be sent when it is full, and new events arriving + in the appender will overwrite the oldest event in the buffer. + In lossy mode the buffer will only be sent when the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> + triggers. This can be useful behavior when you need to know about + ERROR events but not about events with a lower level, configure an + evaluator that will trigger when an ERROR event arrives, the whole + buffer will be sent which gives a history of events leading up to + the ERROR event. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Appender.AppenderSkeleton"> + <summary> + Abstract base class implementation of <see cref="T:log4net.Appender.IAppender"/>. + </summary> + <remarks> + <para> + This class provides the code for common functionality, such + as support for threshold filtering and support for general filters. + </para> + <para> + Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore + they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method + be called after the appenders properties have been configured. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Appender.IAppender"> + <summary> + Implement this interface for your own strategies for printing log statements. + </summary> + <remarks> + <para> + Implementors should consider extending the <see cref="T:log4net.Appender.AppenderSkeleton"/> + class which provides a default implementation of this interface. + </para> + <para> + Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore + they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method + be called after the appenders properties have been configured. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.IAppender.Close"> + <summary> + Closes the appender and releases resources. + </summary> + <remarks> + <para> + Releases any resources allocated within the appender such as file handles, + network connections, etc. + </para> + <para> + It is a programming error to append to a closed appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"> + <summary> + Log the logging event in Appender specific way. + </summary> + <param name="loggingEvent">The event to log</param> + <remarks> + <para> + This method is called to log a message into this appender. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.IAppender.Name"> + <summary> + Gets or sets the name of this appender. + </summary> + <value>The name of the appender.</value> + <remarks> + <para>The name uniquely identifies the appender.</para> + </remarks> + </member> + <member name="T:log4net.Appender.IBulkAppender"> + <summary> + Interface for appenders that support bulk logging. + </summary> + <remarks> + <para> + This interface extends the <see cref="T:log4net.Appender.IAppender"/> interface to + support bulk logging of <see cref="T:log4net.Core.LoggingEvent"/> objects. Appenders + should only implement this interface if they can bulk log efficiently. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.IBulkAppender.DoAppend(log4net.Core.LoggingEvent[])"> + <summary> + Log the array of logging events in Appender specific way. + </summary> + <param name="loggingEvents">The events to log</param> + <remarks> + <para> + This method is called to log an array of events into this appender. + </para> + </remarks> + </member> + <member name="T:log4net.Core.IOptionHandler"> + <summary> + Interface used to delay activate a configured object. + </summary> + <remarks> + <para> + This allows an object to defer activation of its options until all + options have been set. This is required for components which have + related options that remain ambiguous until all are set. + </para> + <para> + If a component implements this interface then the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method + must be called by the container after its all the configured properties have been set + and before the component can be used. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Core.IOptionHandler.ActivateOptions"> + <summary> + Activate the options that were previously set with calls to properties. + </summary> + <remarks> + <para> + This allows an object to defer activation of its options until all + options have been set. This is required for components which have + related options that remain ambiguous until all are set. + </para> + <para> + If a component implements this interface then this method must be called + after its properties have been set before the component can be used. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.c_renderBufferSize"> + <summary> + Initial buffer size + </summary> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.c_renderBufferMaxCapacity"> + <summary> + Maximum buffer size before it is recycled + </summary> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para>Empty default constructor</para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.Finalize"> + <summary> + Finalizes this appender by calling the implementation's + <see cref="M:log4net.Appender.AppenderSkeleton.Close"/> method. + </summary> + <remarks> + <para> + If this appender has not been closed then the <c>Finalize</c> method + will call <see cref="M:log4net.Appender.AppenderSkeleton.Close"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.ActivateOptions"> + <summary> + Initialize the appender based on the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.AppenderSkeleton.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="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.Close"> + <summary> + Closes the appender and release resources. + </summary> + <remarks> + <para> + Release any resources allocated within the appender such as file handles, + network connections, etc. + </para> + <para> + It is a programming error to append to a closed appender. + </para> + <para> + This method cannot be overridden by subclasses. This method + delegates the closing of the appender to the <see cref="M:log4net.Appender.AppenderSkeleton.OnClose"/> + method which must be overridden in the subclass. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"> + <summary> + Performs threshold checks and invokes filters before + delegating actual logging to the subclasses specific + <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + This method cannot be overridden by derived classes. A + derived class should override the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method + which is called by this method. + </para> + <para> + The implementation of this method is as follows: + </para> + <para> + <list type="bullet"> + <item> + <description> + Checks that the severity of the <paramref name="loggingEvent"/> + is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this + appender.</description> + </item> + <item> + <description> + Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the + <paramref name="loggingEvent"/>. + </description> + </item> + <item> + <description> + Calls <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> and checks that + it returns <c>true</c>.</description> + </item> + </list> + </para> + <para> + If all of the above steps succeed then the <paramref name="loggingEvent"/> + will be passed to the abstract <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"> + <summary> + Performs threshold checks and invokes filters before + delegating actual logging to the subclasses specific + <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method. + </summary> + <param name="loggingEvents">The array of events to log.</param> + <remarks> + <para> + This method cannot be overridden by derived classes. A + derived class should override the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method + which is called by this method. + </para> + <para> + The implementation of this method is as follows: + </para> + <para> + <list type="bullet"> + <item> + <description> + Checks that the severity of the <paramref name="loggingEvent"/> + is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this + appender.</description> + </item> + <item> + <description> + Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the + <paramref name="loggingEvent"/>. + </description> + </item> + <item> + <description> + Calls <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> and checks that + it returns <c>true</c>.</description> + </item> + </list> + </para> + <para> + If all of the above steps succeed then the <paramref name="loggingEvents"/> + will be passed to the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.FilterEvent(log4net.Core.LoggingEvent)"> + <summary> + Test if the logging event should we output by this appender + </summary> + <param name="loggingEvent">the event to test</param> + <returns><c>true</c> if the event should be output, <c>false</c> if the event should be ignored</returns> + <remarks> + <para> + This method checks the logging event against the threshold level set + on this appender and also against the filters specified on this + appender. + </para> + <para> + The implementation of this method is as follows: + </para> + <para> + <list type="bullet"> + <item> + <description> + Checks that the severity of the <paramref name="loggingEvent"/> + is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this + appender.</description> + </item> + <item> + <description> + Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the + <paramref name="loggingEvent"/>. + </description> + </item> + </list> + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.AddFilter(log4net.Filter.IFilter)"> + <summary> + Adds a filter to the end of the filter chain. + </summary> + <param name="filter">the filter to add to this appender</param> + <remarks> + <para> + The Filters are organized in a linked list. + </para> + <para> + Setting this property causes the new filter to be pushed onto the + back of the filter chain. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.ClearFilters"> + <summary> + Clears the filter list for this appender. + </summary> + <remarks> + <para> + Clears the filter list for this appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.IsAsSevereAsThreshold(log4net.Core.Level)"> + <summary> + Checks if the message level is below this appender's threshold. + </summary> + <param name="level"><see cref="T:log4net.Core.Level"/> to test against.</param> + <remarks> + <para> + If there is no threshold set, then the return value is always <c>true</c>. + </para> + </remarks> + <returns> + <c>true</c> if the <paramref name="level"/> meets the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> + requirements of this appender. + </returns> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.OnClose"> + <summary> + Is called when the appender is closed. Derived classes should override + this method if resources need to be released. + </summary> + <remarks> + <para> + Releases any resources allocated within the appender such as file handles, + network connections, etc. + </para> + <para> + It is a programming error to append to a closed appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"> + <summary> + Subclasses of <see cref="T:log4net.Appender.AppenderSkeleton"/> should implement this method + to perform actual logging. + </summary> + <param name="loggingEvent">The event to append.</param> + <remarks> + <para> + A subclass must implement this method to perform + logging of the <paramref name="loggingEvent"/>. + </para> + <para>This method will be called by <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> + if all the conditions listed for that method are met. + </para> + <para> + To restrict the logging of events in the appender + override the <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> method. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"> + <summary> + Append a bulk array of logging events. + </summary> + <param name="loggingEvents">the array of logging events</param> + <remarks> + <para> + This base class implementation calls the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> + method for each element in the bulk array. + </para> + <para> + A sub class that can better process a bulk array of events should + override this method in addition to <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"> + <summary> + Called before <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> as a precondition. + </summary> + <remarks> + <para> + This method is called by <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> + before the call to the abstract <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method. + </para> + <para> + This method can be overridden in a subclass to extend the checks + made before the event is passed to the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method. + </para> + <para> + A subclass should ensure that they delegate this call to + this base class if it is overridden. + </para> + </remarks> + <returns><c>true</c> if the call to <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> should proceed.</returns> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"> + <summary> + Renders the <see cref="T:log4net.Core.LoggingEvent"/> to a string. + </summary> + <param name="loggingEvent">The event to render.</param> + <returns>The event rendered as a string.</returns> + <remarks> + <para> + Helper method to render a <see cref="T:log4net.Core.LoggingEvent"/> to + a string. This appender must have a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> + set to render the <paramref name="loggingEvent"/> to + a string. + </para> + <para>If there is exception data in the logging event and + the layout does not process the exception, this method + will append the exception text to the rendered string. + </para> + <para> + Where possible use the alternative version of this method + <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(System.IO.TextWriter,log4net.Core.LoggingEvent)"/>. + That method streams the rendering onto an existing Writer + which can give better performance if the caller already has + a <see cref="T:System.IO.TextWriter"/> open and ready for writing. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Renders the <see cref="T:log4net.Core.LoggingEvent"/> to a string. + </summary> + <param name="loggingEvent">The event to render.</param> + <param name="writer">The TextWriter to write the formatted event to</param> + <remarks> + <para> + Helper method to render a <see cref="T:log4net.Core.LoggingEvent"/> to + a string. This appender must have a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> + set to render the <paramref name="loggingEvent"/> to + a string. + </para> + <para>If there is exception data in the logging event and + the layout does not process the exception, this method + will append the exception text to the rendered string. + </para> + <para> + Use this method in preference to <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"/> + where possible. If, however, the caller needs to render the event + to a string then <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"/> does + provide an efficient mechanism for doing so. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_layout"> + <summary> + The layout of this appender. + </summary> + <remarks> + See <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> for more information. + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_name"> + <summary> + The name of this appender. + </summary> + <remarks> + See <see cref="P:log4net.Appender.AppenderSkeleton.Name"/> for more information. + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_threshold"> + <summary> + The level threshold of this appender. + </summary> + <remarks> + <para> + There is no level threshold filtering by default. + </para> + <para> + See <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> for more information. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_errorHandler"> + <summary> + It is assumed and enforced that errorHandler is never null. + </summary> + <remarks> + <para> + It is assumed and enforced that errorHandler is never null. + </para> + <para> + See <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/> for more information. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_headFilter"> + <summary> + The first filter in the filter chain. + </summary> + <remarks> + <para> + Set to <c>null</c> initially. + </para> + <para> + See <see cref="T:log4net.Filter.IFilter"/> for more information. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_tailFilter"> + <summary> + The last filter in the filter chain. + </summary> + <remarks> + See <see cref="T:log4net.Filter.IFilter"/> for more information. + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_closed"> + <summary> + Flag indicating if this appender is closed. + </summary> + <remarks> + See <see cref="M:log4net.Appender.AppenderSkeleton.Close"/> for more information. + </remarks> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_recursiveGuard"> + <summary> + The guard prevents an appender from repeatedly calling its own DoAppend method + </summary> + </member> + <member name="F:log4net.Appender.AppenderSkeleton.m_renderWriter"> + <summary> + StringWriter used to render events + </summary> + </member> + <member name="P:log4net.Appender.AppenderSkeleton.Threshold"> + <summary> + Gets or sets the threshold <see cref="T:log4net.Core.Level"/> of this appender. + </summary> + <value> + The threshold <see cref="T:log4net.Core.Level"/> of the appender. + </value> + <remarks> + <para> + All log events with lower level than the threshold level are ignored + by the appender. + </para> + <para> + In configuration files this option is specified by setting the + value of the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> option to a level + string, such as "DEBUG", "INFO" and so on. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AppenderSkeleton.ErrorHandler"> + <summary> + Gets or sets the <see cref="T:log4net.Core.IErrorHandler"/> for this appender. + </summary> + <value>The <see cref="T:log4net.Core.IErrorHandler"/> of the appender</value> + <remarks> + <para> + The <see cref="T:log4net.Appender.AppenderSkeleton"/> provides a default + implementation for the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/> property. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AppenderSkeleton.FilterHead"> + <summary> + The filter chain. + </summary> + <value>The head of the filter chain filter chain.</value> + <remarks> + <para> + Returns the head Filter. The Filters are organized in a linked list + and so all Filters on this Appender are available through the result. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AppenderSkeleton.Layout"> + <summary> + Gets or sets the <see cref="T:log4net.Layout.ILayout"/> for this appender. + </summary> + <value>The layout of the appender.</value> + <remarks> + <para> + See <see cref="P:log4net.Appender.AppenderSkeleton.RequiresLayout"/> for more information. + </para> + </remarks> + <seealso cref="P:log4net.Appender.AppenderSkeleton.RequiresLayout"/> + </member> + <member name="P:log4net.Appender.AppenderSkeleton.Name"> + <summary> + Gets or sets the name of this appender. + </summary> + <value>The name of the appender.</value> + <remarks> + <para> + The name uniquely identifies the appender. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AppenderSkeleton.RequiresLayout"> + <summary> + Tests if this appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set. + </summary> + <remarks> + <para> + In the rather exceptional case, where the appender + implementation admits a layout but can also work without it, + then the appender should return <c>true</c>. + </para> + <para> + This default implementation always returns <c>true</c>. + </para> + </remarks> + <returns> + <c>true</c> if the appender requires a layout object, otherwise <c>false</c>. + </returns> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.DEFAULT_BUFFER_SIZE"> + <summary> + The default buffer size. + </summary> + <remarks> + The default size of the cyclic buffer used to store events. + This is set to 512 by default. + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> class. + </summary> + <remarks> + <para> + Protected default constructor to allow subclassing. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.#ctor(System.Boolean)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> class. + </summary> + <param name="eventMustBeFixed">the events passed through this appender must be + fixed by the time that they arrive in the derived class' <c>SendBuffer</c> method.</param> + <remarks> + <para> + Protected constructor to allow subclassing. + </para> + <para> + The <paramref name="eventMustBeFixed"/> should be set if the subclass + expects the events delivered to be fixed even if the + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is set to zero, i.e. when no buffering occurs. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.Flush"> + <summary> + Flush the currently buffered events + </summary> + <remarks> + <para> + Flushes any events that have been buffered. + </para> + <para> + If the appender is buffering in <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode then the contents + of the buffer will NOT be flushed to the appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.Flush(System.Boolean)"> + <summary> + Flush the currently buffered events + </summary> + <param name="flushLossyBuffer">set to <c>true</c> to flush the buffer of lossy events</param> + <remarks> + <para> + Flushes events that have been buffered. If <paramref name="flushLossyBuffer"/> is + <c>false</c> then events will only be flushed if this buffer is non-lossy mode. + </para> + <para> + If the appender is buffering in <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode then the contents + of the buffer will only be flushed if <paramref name="flushLossyBuffer"/> is <c>true</c>. + In this case the contents of the buffer will be tested against the + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.LossyEvaluator"/> and if triggering will be output. All other buffered + events will be discarded. + </para> + <para> + If <paramref name="flushLossyBuffer"/> is <c>true</c> then the buffer will always + be emptied by calling this method. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"> + <summary> + Initialize the appender based on the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.BufferingAppenderSkeleton.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="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.OnClose"> + <summary> + Close this appender instance. + </summary> + <remarks> + <para> + Close this appender instance. If this appender is marked + as not <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> then the remaining events in + the buffer must be sent when the appender is closed. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">the event to log</param> + <remarks> + <para> + Stores the <paramref name="loggingEvent"/> in the cyclic buffer. + </para> + <para> + The buffer will be sent (i.e. passed to the <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/> + method) if one of the following conditions is met: + </para> + <list type="bullet"> + <item> + <description>The cyclic buffer is full and this appender is + marked as not lossy (see <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/>)</description> + </item> + <item> + <description>An <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> is set and + it is triggered for the <paramref name="loggingEvent"/> + specified.</description> + </item> + </list> + <para> + Before the event is stored in the buffer it is fixed + (see <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"/>) to ensure that + any data referenced by the event will be valid when the buffer + is processed. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.SendFromBuffer(log4net.Core.LoggingEvent,log4net.Util.CyclicBuffer)"> + <summary> + Sends the contents of the buffer. + </summary> + <param name="firstLoggingEvent">The first logging event.</param> + <param name="buffer">The buffer containing the events that need to be send.</param> + <remarks> + <para> + The subclass must override <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"> + <summary> + Sends the events. + </summary> + <param name="events">The events that need to be send.</param> + <remarks> + <para> + The subclass must override this method to process the buffered events. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_bufferSize"> + <summary> + The size of the cyclic buffer used to hold the logging events. + </summary> + <remarks> + Set to <see cref="F:log4net.Appender.BufferingAppenderSkeleton.DEFAULT_BUFFER_SIZE"/> by default. + </remarks> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_cb"> + <summary> + The cyclic buffer used to store the logging events. + </summary> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_evaluator"> + <summary> + The triggering event evaluator that causes the buffer to be sent immediately. + </summary> + <remarks> + The object that is used to determine if an event causes the entire + buffer to be sent immediately. This field can be <c>null</c>, which + indicates that event triggering is not to be done. The evaluator + can be set using the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> property. If this appender + has the <see cref="F:log4net.Appender.BufferingAppenderSkeleton.m_lossy"/> (<see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> property) set to + <c>true</c> then an <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be set. + </remarks> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_lossy"> + <summary> + Indicates if the appender should overwrite events in the cyclic buffer + when it becomes full, or if the buffer should be flushed when the + buffer is full. + </summary> + <remarks> + If this field is set to <c>true</c> then an <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must + be set. + </remarks> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_lossyEvaluator"> + <summary> + The triggering event evaluator filters discarded events. + </summary> + <remarks> + The object that is used to determine if an event that is discarded should + really be discarded or if it should be sent to the appenders. + This field can be <c>null</c>, which indicates that all discarded events will + be discarded. + </remarks> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_fixFlags"> + <summary> + Value indicating which fields in the event should be fixed + </summary> + <remarks> + By default all fields are fixed + </remarks> + </member> + <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_eventMustBeFixed"> + <summary> + The events delivered to the subclass must be fixed. + </summary> + </member> + <member name="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"> + <summary> + Gets or sets a value that indicates whether the appender is lossy. + </summary> + <value> + <c>true</c> if the appender is lossy, otherwise <c>false</c>. The default is <c>false</c>. + </value> + <remarks> + <para> + This appender uses a buffer to store logging events before + delivering them. A triggering event causes the whole buffer + to be send to the remote sink. If the buffer overruns before + a triggering event then logging events could be lost. Set + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> to <c>false</c> to prevent logging events + from being lost. + </para> + <para>If <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> is set to <c>true</c> then an + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be specified.</para> + </remarks> + </member> + <member name="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"> + <summary> + Gets or sets the size of the cyclic buffer used to hold the + logging events. + </summary> + <value> + The size of the cyclic buffer used to hold the logging events. + </value> + <remarks> + <para> + The <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option takes a positive integer + representing the maximum number of logging events to collect in + a cyclic buffer. When the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is reached, + oldest events are deleted as new events are added to the + buffer. By default the size of the cyclic buffer is 512 events. + </para> + <para> + If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is set to a value less than + or equal to 1 then no buffering will occur. The logging event + will be delivered synchronously (depending on the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> + and <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> properties). Otherwise the event will + be buffered. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"> + <summary> + Gets or sets the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> that causes the + buffer to be sent immediately. + </summary> + <value> + The <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> that causes the buffer to be + sent immediately. + </value> + <remarks> + <para> + The evaluator will be called for each event that is appended to this + appender. If the evaluator triggers then the current buffer will + immediately be sent (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>). + </para> + <para>If <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> is set to <c>true</c> then an + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be specified.</para> + </remarks> + </member> + <member name="P:log4net.Appender.BufferingAppenderSkeleton.LossyEvaluator"> + <summary> + Gets or sets the value of the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> to use. + </summary> + <value> + The value of the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> to use. + </value> + <remarks> + <para> + The evaluator will be called for each event that is discarded from this + appender. If the evaluator triggers then the current buffer will immediately + be sent (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>). + </para> + </remarks> + </member> + <member name="P:log4net.Appender.BufferingAppenderSkeleton.OnlyFixPartialEventData"> + <summary> + Gets or sets a value indicating if only part of the logging event data + should be fixed. + </summary> + <value> + <c>true</c> if the appender should only fix part of the logging event + data, otherwise <c>false</c>. The default is <c>false</c>. + </value> + <remarks> + <para> + Setting this property to <c>true</c> will cause only part of the + event data to be fixed and serialized. This will improve performance. + </para> + <para> + See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"/> for more information. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.BufferingAppenderSkeleton.Fix"> + <summary> + Gets or sets a the fields that will be fixed in the event + </summary> + <value> + The event fields that will be fixed before the event is buffered + </value> + <remarks> + <para> + The logging event needs to have certain thread specific values + captured before it can be buffered. See <see cref="P:log4net.Core.LoggingEvent.Fix"/> + for details. + </para> + </remarks> + <seealso cref="P:log4net.Core.LoggingEvent.Fix"/> + </member> + <member name="M:log4net.Appender.AdoNetAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.AdoNetAppender"/> class. + </summary> + <remarks> + Public default constructor to initialize a new instance of this class. + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.AdoNetAppender.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="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppender.OnClose"> + <summary> + Override the parent method to close the database + </summary> + <remarks> + <para> + Closes the database command and database connection. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppender.SendBuffer(log4net.Core.LoggingEvent[])"> + <summary> + Inserts the events into the database. + </summary> + <param name="events">The events to insert into the database.</param> + <remarks> + <para> + Insert all the events specified in the <paramref name="events"/> + array into the database. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppender.AddParameter(log4net.Appender.AdoNetAppenderParameter)"> + <summary> + Adds a parameter to the command. + </summary> + <param name="parameter">The parameter to add to the command.</param> + <remarks> + <para> + Adds a parameter to the ordered list of command parameters. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppender.SendBuffer(System.Data.IDbTransaction,log4net.Core.LoggingEvent[])"> + <summary> + Writes the events to the database using the transaction specified. + </summary> + <param name="dbTran">The transaction that the events will be executed under.</param> + <param name="events">The array of events to insert into the database.</param> + <remarks> + <para> + The transaction argument can be <c>null</c> if the appender has been + configured not to use transactions. See <see cref="P:log4net.Appender.AdoNetAppender.UseTransactions"/> + property for more information. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppender.GetLogStatement(log4net.Core.LoggingEvent)"> + <summary> + Formats the log message into database statement text. + </summary> + <param name="logEvent">The event being logged.</param> + <remarks> + This method can be overridden by subclasses to provide + more control over the format of the database statement. + </remarks> + <returns> + Text that can be passed to a <see cref="T:System.Data.IDbCommand"/>. + </returns> + </member> + <member name="M:log4net.Appender.AdoNetAppender.InitializeDatabaseConnection"> + <summary> + Connects to the database. + </summary> + </member> + <member name="M:log4net.Appender.AdoNetAppender.ResolveConnectionType"> + <summary> + Retrieves the class type of the ADO.NET provider. + </summary> + <remarks> + <para> + Gets the Type of the ADO.NET provider to use to connect to the + database. This method resolves the type specified in the + <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> property. + </para> + <para> + Subclasses can override this method to return a different type + if necessary. + </para> + </remarks> + <returns>The <see cref="T:System.Type"/> of the ADO.NET provider</returns> + </member> + <member name="M:log4net.Appender.AdoNetAppender.InitializeDatabaseCommand"> + <summary> + Prepares the database command and initialize the parameters. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_usePreparedCommand"> + <summary> + Flag to indicate if we are using a command object + </summary> + <remarks> + <para> + Set to <c>true</c> when the appender is to use a prepared + statement or stored procedure to insert into the database. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_parameters"> + <summary> + The list of <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> objects. + </summary> + <remarks> + <para> + The list of <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> objects. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_securityContext"> + <summary> + The security context to use for privileged calls + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_dbConnection"> + <summary> + The <see cref="T:System.Data.IDbConnection"/> that will be used + to insert logging events into a database. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_dbCommand"> + <summary> + The database command. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_connectionString"> + <summary> + Database connection string. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_connectionType"> + <summary> + String type name of the <see cref="T:System.Data.IDbConnection"/> type name. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_commandText"> + <summary> + The text of the command. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_commandType"> + <summary> + The command type. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_useTransactions"> + <summary> + Indicates whether to use transactions when writing to the database. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppender.m_reconnectOnError"> + <summary> + Indicates whether to use transactions when writing to the database. + </summary> + </member> + <member name="P:log4net.Appender.AdoNetAppender.ConnectionString"> + <summary> + Gets or sets the database connection string that is used to connect to + the database. + </summary> + <value> + The database connection string used to connect to the database. + </value> + <remarks> + <para> + The connections string is specific to the connection type. + See <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> for more information. + </para> + </remarks> + <example>Connection string for MS Access via ODBC: + <code>"DSN=MS Access Database;UID=admin;PWD=;SystemDB=C:\data\System.mdw;SafeTransactions = 0;FIL=MS Access;DriverID = 25;DBQ=C:\data\train33.mdb"</code> + </example> + <example>Another connection string for MS Access via ODBC: + <code>"Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\Work\cvs_root\log4net-1.2\access.mdb;UID=;PWD=;"</code> + </example> + <example>Connection string for MS Access via OLE DB: + <code>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Work\cvs_root\log4net-1.2\access.mdb;User Id=;Password=;"</code> + </example> + </member> + <member name="P:log4net.Appender.AdoNetAppender.ConnectionType"> + <summary> + Gets or sets the type name of the <see cref="T:System.Data.IDbConnection"/> connection + that should be created. + </summary> + <value> + The type name of the <see cref="T:System.Data.IDbConnection"/> connection. + </value> + <remarks> + <para> + The type name of the ADO.NET provider to use. + </para> + <para> + The default is to use the OLE DB provider. + </para> + </remarks> + <example>Use the OLE DB Provider. This is the default value. + <code>System.Data.OleDb.OleDbConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code> + </example> + <example>Use the MS SQL Server Provider. + <code>System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code> + </example> + <example>Use the ODBC Provider. + <code>Microsoft.Data.Odbc.OdbcConnection,Microsoft.Data.Odbc,version=1.0.3300.0,publicKeyToken=b77a5c561934e089,culture=neutral</code> + This is an optional package that you can download from + <a href="http://msdn.microsoft.com/downloads">http://msdn.microsoft.com/downloads</a> + search for <b>ODBC .NET Data Provider</b>. + </example> + <example>Use the Oracle Provider. + <code>System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code> + This is an optional package that you can download from + <a href="http://msdn.microsoft.com/downloads">http://msdn.microsoft.com/downloads</a> + search for <b>.NET Managed Provider for Oracle</b>. + </example> + </member> + <member name="P:log4net.Appender.AdoNetAppender.CommandText"> + <summary> + Gets or sets the command text that is used to insert logging events + into the database. + </summary> + <value> + The command text used to insert logging events into the database. + </value> + <remarks> + <para> + Either the text of the prepared statement or the + name of the stored procedure to execute to write into + the database. + </para> + <para> + The <see cref="P:log4net.Appender.AdoNetAppender.CommandType"/> property determines if + this text is a prepared statement or a stored procedure. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AdoNetAppender.CommandType"> + <summary> + Gets or sets the command type to execute. + </summary> + <value> + The command type to execute. + </value> + <remarks> + <para> + This value may be either <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>) to specify + that the <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> is a prepared statement to execute, + or <see cref="F:System.Data.CommandType.StoredProcedure"/> (<c>System.Data.CommandType.StoredProcedure</c>) to specify that the + <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> property is the name of a stored procedure + to execute. + </para> + <para> + The default value is <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>). + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AdoNetAppender.UseTransactions"> + <summary> + Should transactions be used to insert logging events in the database. + </summary> + <value> + <c>true</c> if transactions should be used to insert logging events in + the database, otherwise <c>false</c>. The default value is <c>true</c>. + </value> + <remarks> + <para> + Gets or sets a value that indicates whether transactions should be used + to insert logging events in the database. + </para> + <para> + When set a single transaction will be used to insert the buffered events + into the database. Otherwise each event will be inserted without using + an explicit transaction. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AdoNetAppender.SecurityContext"> + <summary> + Gets or sets the <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> used to call the NetSend method. + </summary> + <value> + The <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> used to call the NetSend method. + </value> + <remarks> + <para> + Unless a <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> specified here for this appender + the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the + security context to use. The default behavior is to use the security context + of the current thread. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AdoNetAppender.ReconnectOnError"> + <summary> + Should this appender try to reconnect to the database on error. + </summary> + <value> + <c>true</c> if the appender should try to reconnect to the database after an + error has occurred, otherwise <c>false</c>. The default value is <c>false</c>, + i.e. not to try to reconnect. + </value> + <remarks> + <para> + The default behaviour is for the appender not to try to reconnect to the + database if an error occurs. Subsequent logging events are discarded. + </para> + <para> + To force the appender to attempt to reconnect to the database set this + property to <c>true</c>. + </para> + <note> + When the appender attempts to connect to the database there may be a + delay of up to the connection timeout specified in the connection string. + This delay will block the calling application's thread. + Until the connection can be reestablished this potential delay may occur multiple times. + </note> + </remarks> + </member> + <member name="P:log4net.Appender.AdoNetAppender.Connection"> + <summary> + Gets or sets the underlying <see cref="T:System.Data.IDbConnection"/>. + </summary> + <value> + The underlying <see cref="T:System.Data.IDbConnection"/>. + </value> + <remarks> + <see cref="T:log4net.Appender.AdoNetAppender"/> creates a <see cref="T:System.Data.IDbConnection"/> to insert + logging events into a database. Classes deriving from <see cref="T:log4net.Appender.AdoNetAppender"/> + can use this property to get or set this <see cref="T:System.Data.IDbConnection"/>. Use the + underlying <see cref="T:System.Data.IDbConnection"/> returned from <see cref="P:log4net.Appender.AdoNetAppender.Connection"/> if + you require access beyond that which <see cref="T:log4net.Appender.AdoNetAppender"/> provides. + </remarks> + </member> + <member name="T:log4net.Appender.AdoNetAppenderParameter"> + <summary> + Parameter type used by the <see cref="T:log4net.Appender.AdoNetAppender"/>. + </summary> + <remarks> + <para> + This class provides the basic database parameter properties + as defined by the <see cref="T:System.Data.IDbDataParameter"/> interface. + </para> + <para>This type can be subclassed to provide database specific + functionality. The two methods that are called externally are + <see cref="M:log4net.Appender.AdoNetAppenderParameter.Prepare(System.Data.IDbCommand)"/> and <see cref="M:log4net.Appender.AdoNetAppenderParameter.FormatValue(System.Data.IDbCommand,log4net.Core.LoggingEvent)"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppenderParameter.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> class. + </summary> + <remarks> + Default constructor for the AdoNetAppenderParameter class. + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppenderParameter.Prepare(System.Data.IDbCommand)"> + <summary> + Prepare the specified database command object. + </summary> + <param name="command">The command to prepare.</param> + <remarks> + <para> + Prepares the database command object by adding + this parameter to its collection of parameters. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AdoNetAppenderParameter.FormatValue(System.Data.IDbCommand,log4net.Core.LoggingEvent)"> + <summary> + Renders the logging event and set the parameter value in the command. + </summary> + <param name="command">The command containing the parameter.</param> + <param name="loggingEvent">The event to be rendered.</param> + <remarks> + <para> + Renders the logging event using this parameters layout + object. Sets the value of the parameter on the command object. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_parameterName"> + <summary> + The name of this parameter. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_dbType"> + <summary> + The database type for this parameter. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_inferType"> + <summary> + Flag to infer type rather than use the DbType + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_precision"> + <summary> + The precision for this parameter. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_scale"> + <summary> + The scale for this parameter. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_size"> + <summary> + The size for this parameter. + </summary> + </member> + <member name="F:log4net.Appender.AdoNetAppenderParameter.m_layout"> + <summary> + The <see cref="T:log4net.Layout.IRawLayout"/> to use to render the + logging event into an object for this parameter. + </summary> + </member> + <member name="P:log4net.Appender.AdoNetAppenderParameter.ParameterName"> + <summary> + Gets or sets the name of this parameter. + </summary> + <value> + The name of this parameter. + </value> + <remarks> + <para> + The name of this parameter. The parameter name + must match up to a named parameter to the SQL stored procedure + or prepared statement. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AdoNetAppenderParameter.DbType"> + <summary> + Gets or sets the database type for this parameter. + </summary> + <value> + The database type for this parameter. + </value> + <remarks> + <para> + The database type for this parameter. This property should + be set to the database type from the <see cref="P:log4net.Appender.AdoNetAppenderParameter.DbType"/> + enumeration. See <see cref="P:System.Data.IDataParameter.DbType"/>. + </para> + <para> + This property is optional. If not specified the ADO.NET provider + will attempt to infer the type from the value. + </para> + </remarks> + <seealso cref="P:System.Data.IDataParameter.DbType"/> + </member> + <member name="P:log4net.Appender.AdoNetAppenderParameter.Precision"> + <summary> + Gets or sets the precision for this parameter. + </summary> + <value> + The precision for this parameter. + </value> + <remarks> + <para> + The maximum number of digits used to represent the Value. + </para> + <para> + This property is optional. If not specified the ADO.NET provider + will attempt to infer the precision from the value. + </para> + </remarks> + <seealso cref="P:System.Data.IDbDataParameter.Precision"/> + </member> + <member name="P:log4net.Appender.AdoNetAppenderParameter.Scale"> + <summary> + Gets or sets the scale for this parameter. + </summary> + <value> + The scale for this parameter. + </value> + <remarks> + <para> + The number of decimal places to which Value is resolved. + </para> + <para> + This property is optional. If not specified the ADO.NET provider + will attempt to infer the scale from the value. + </para> + </remarks> + <seealso cref="P:System.Data.IDbDataParameter.Scale"/> + </member> + <member name="P:log4net.Appender.AdoNetAppenderParameter.Size"> + <summary> + Gets or sets the size for this parameter. + </summary> + <value> + The size for this parameter. + </value> + <remarks> + <para> + The maximum size, in bytes, of the data within the column. + </para> + <para> + This property is optional. If not specified the ADO.NET provider + will attempt to infer the size from the value. + </para> + </remarks> + <seealso cref="P:System.Data.IDbDataParameter.Size"/> + </member> + <member name="P:log4net.Appender.AdoNetAppenderParameter.Layout"> + <summary> + Gets or sets the <see cref="T:log4net.Layout.IRawLayout"/> to use to + render the logging event into an object for this + parameter. + </summary> + <value> + The <see cref="T:log4net.Layout.IRawLayout"/> used to render the + logging event into an object for this parameter. + </value> + <remarks> + <para> + The <see cref="T:log4net.Layout.IRawLayout"/> that renders the value for this + parameter. + </para> + <para> + The <see cref="T:log4net.Layout.RawLayoutConverter"/> can be used to adapt + any <see cref="T:log4net.Layout.ILayout"/> into a <see cref="T:log4net.Layout.IRawLayout"/> + for use in the property. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.AnsiColorTerminalAppender"> + <summary> + Appends logging events to the terminal using ANSI color escape sequences. + </summary> + <remarks> + <para> + AnsiColorTerminalAppender appends log events to the standard output stream + or the error output stream using a layout specified by the + user. It also allows the color of a specific level of message to be set. + </para> + <note> + This appender expects the terminal to understand the VT100 control set + in order to interpret the color codes. If the terminal or console does not + understand the control codes the behavior is not defined. + </note> + <para> + By default, all output is written to the console's standard output stream. + The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> property can be set to direct the output to the + error stream. + </para> + <para> + NOTE: This appender writes each message to the <c>System.Console.Out</c> or + <c>System.Console.Error</c> that is set at the time the event is appended. + Therefore it is possible to programmatically redirect the output of this appender + (for example NUnit does this to capture program output). While this is the desired + behavior of this appender it may have security implications in your application. + </para> + <para> + When configuring the ANSI colored terminal appender, a mapping should be + specified to map a logging level to a color. For example: + </para> + <code lang="XML" escaped="true"> + <mapping> + <level value="ERROR"/> + <foreColor value="White"/> + <backColor value="Red"/> + <attributes value="Bright,Underscore"/> + </mapping> + <mapping> + <level value="DEBUG"/> + <backColor value="Green"/> + </mapping> + </code> + <para> + The Level is the standard log4net logging level and ForeColor and BackColor can be any + of the following values: + <list type="bullet"> + <item><term>Blue</term><description></description></item> + <item><term>Green</term><description></description></item> + <item><term>Red</term><description></description></item> + <item><term>White</term><description></description></item> + <item><term>Yellow</term><description></description></item> + <item><term>Purple</term><description></description></item> + <item><term>Cyan</term><description></description></item> + </list> + These color values cannot be combined together to make new colors. + </para> + <para> + The attributes can be any combination of the following: + <list type="bullet"> + <item><term>Bright</term><description>foreground is brighter</description></item> + <item><term>Dim</term><description>foreground is dimmer</description></item> + <item><term>Underscore</term><description>message is underlined</description></item> + <item><term>Blink</term><description>foreground is blinking (does not work on all terminals)</description></item> + <item><term>Reverse</term><description>foreground and background are reversed</description></item> + <item><term>Hidden</term><description>output is hidden</description></item> + <item><term>Strikethrough</term><description>message has a line through it</description></item> + </list> + While any of these attributes may be combined together not all combinations + work well together, for example setting both <i>Bright</i> and <i>Dim</i> attributes makes + no sense. + </para> + </remarks> + <author>Patrick Wagstrom</author> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.ConsoleOut"> + <summary> + The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console + standard output stream. + </summary> + <remarks> + <para> + The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console + standard output stream. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.ConsoleError"> + <summary> + The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console + standard error output stream. + </summary> + <remarks> + <para> + The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console + standard error output stream. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.PostEventCodes"> + <summary> + Ansi code to reset terminal + </summary> + </member> + <member name="M:log4net.Appender.AnsiColorTerminalAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.AnsiColorTerminalAppender"/> class. + </summary> + <remarks> + The instance of the <see cref="T:log4net.Appender.AnsiColorTerminalAppender"/> class is set up to write + to the standard output stream. + </remarks> + </member> + <member name="M:log4net.Appender.AnsiColorTerminalAppender.AddMapping(log4net.Appender.AnsiColorTerminalAppender.LevelColors)"> + <summary> + Add a mapping of level to color + </summary> + <param name="mapping">The mapping to add</param> + <remarks> + <para> + Add a <see cref="T:log4net.Appender.AnsiColorTerminalAppender.LevelColors"/> mapping to this appender. + Each mapping defines the foreground and background colours + for a level. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AnsiColorTerminalAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the event to the console. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AnsiColorTerminalAppender.ActivateOptions"> + <summary> + Initialize the options for this appender + </summary> + <remarks> + <para> + Initialize the level to color mappings set on this appender. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.m_writeToErrorStream"> + <summary> + Flag to write output to the error stream rather than the standard output stream + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.m_levelMapping"> + <summary> + Mapping from level object to color value + </summary> + </member> + <member name="P:log4net.Appender.AnsiColorTerminalAppender.Target"> + <summary> + Target is the value of the console output stream. + </summary> + <value> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </value> + <remarks> + <para> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AnsiColorTerminalAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes"> + <summary> + The enum of possible display attributes + </summary> + <remarks> + <para> + The following flags can be combined together to + form the ANSI color attributes. + </para> + </remarks> + <seealso cref="T:log4net.Appender.AnsiColorTerminalAppender"/> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Bright"> + <summary> + text is bright + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Dim"> + <summary> + text is dim + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Underscore"> + <summary> + text is underlined + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Blink"> + <summary> + text is blinking + </summary> + <remarks> + Not all terminals support this attribute + </remarks> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Reverse"> + <summary> + text and background colors are reversed + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Hidden"> + <summary> + text is hidden + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Strikethrough"> + <summary> + text is displayed with a strikethrough + </summary> + </member> + <member name="T:log4net.Appender.AnsiColorTerminalAppender.AnsiColor"> + <summary> + The enum of possible foreground or background color values for + use with the color mapping method + </summary> + <remarks> + <para> + The output can be in one for the following ANSI colors. + </para> + </remarks> + <seealso cref="T:log4net.Appender.AnsiColorTerminalAppender"/> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Black"> + <summary> + color is black + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Red"> + <summary> + color is red + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Green"> + <summary> + color is green + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Yellow"> + <summary> + color is yellow + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Blue"> + <summary> + color is blue + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Magenta"> + <summary> + color is magenta + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Cyan"> + <summary> + color is cyan + </summary> + </member> + <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.White"> + <summary> + color is white + </summary> + </member> + <member name="T:log4net.Appender.AnsiColorTerminalAppender.LevelColors"> + <summary> + A class to act as a mapping between the level that a logging call is made at and + the color it should be displayed as. + </summary> + <remarks> + <para> + Defines the mapping between a level and the color it should be displayed in. + </para> + </remarks> + </member> + <member name="T:log4net.Util.LevelMappingEntry"> + <summary> + An entry in the <see cref="T:log4net.Util.LevelMapping"/> + </summary> + <remarks> + <para> + This is an abstract base class for types that are stored in the + <see cref="T:log4net.Util.LevelMapping"/> object. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.LevelMappingEntry.#ctor"> + <summary> + Default protected constructor + </summary> + <remarks> + <para> + Default protected constructor + </para> + </remarks> + </member> + <member name="M:log4net.Util.LevelMappingEntry.ActivateOptions"> + <summary> + Initialize any options defined on this entry + </summary> + <remarks> + <para> + Should be overridden by any classes that need to initialise based on their options + </para> + </remarks> + </member> + <member name="P:log4net.Util.LevelMappingEntry.Level"> + <summary> + The level that is the key for this mapping + </summary> + <value> + The <see cref="P:log4net.Util.LevelMappingEntry.Level"/> that is the key for this mapping + </value> + <remarks> + <para> + Get or set the <see cref="P:log4net.Util.LevelMappingEntry.Level"/> that is the key for this + mapping subclass. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ActivateOptions"> + <summary> + Initialize the options for the object + </summary> + <remarks> + <para> + Combine the <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"/> together + and append the attributes. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"> + <summary> + The mapped foreground color for the specified level + </summary> + <remarks> + <para> + Required property. + The mapped foreground color for the specified level + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"> + <summary> + The mapped background color for the specified level + </summary> + <remarks> + <para> + Required property. + The mapped background color for the specified level + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.Attributes"> + <summary> + The color attributes for the specified level + </summary> + <remarks> + <para> + Required property. + The color attributes for the specified level + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.CombinedColor"> + <summary> + The combined <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"/>, <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"/> and + <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.Attributes"/> suitable for setting the ansi terminal color. + </summary> + </member> + <member name="T:log4net.Appender.AppenderCollection"> + <summary> + A strongly-typed collection of <see cref="T:log4net.Appender.IAppender"/> objects. + </summary> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.AppenderCollection.ReadOnly(log4net.Appender.AppenderCollection)"> + <summary> + Creates a read-only wrapper for a <c>AppenderCollection</c> instance. + </summary> + <param name="list">list to create a readonly wrapper arround</param> + <returns> + An <c>AppenderCollection</c> wrapper that is read-only. + </returns> + </member> + <member name="F:log4net.Appender.AppenderCollection.EmptyCollection"> + <summary> + An empty readonly static AppenderCollection + </summary> + </member> + <member name="M:log4net.Appender.AppenderCollection.#ctor"> + <summary> + Initializes a new instance of the <c>AppenderCollection</c> class + that is empty and has the default initial capacity. + </summary> + </member> + <member name="M:log4net.Appender.AppenderCollection.#ctor(System.Int32)"> + <summary> + Initializes a new instance of the <c>AppenderCollection</c> class + that has the specified initial capacity. + </summary> + <param name="capacity"> + The number of elements that the new <c>AppenderCollection</c> is initially capable of storing. + </param> + </member> + <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.AppenderCollection)"> + <summary> + Initializes a new instance of the <c>AppenderCollection</c> class + that contains elements copied from the specified <c>AppenderCollection</c>. + </summary> + <param name="c">The <c>AppenderCollection</c> whose elements are copied to the new collection.</param> + </member> + <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.IAppender[])"> + <summary> + Initializes a new instance of the <c>AppenderCollection</c> class + that contains elements copied from the specified <see cref="T:log4net.Appender.IAppender"/> array. + </summary> + <param name="a">The <see cref="T:log4net.Appender.IAppender"/> array whose elements are copied to the new list.</param> + </member> + <member name="M:log4net.Appender.AppenderCollection.#ctor(System.Collections.ICollection)"> + <summary> + Initializes a new instance of the <c>AppenderCollection</c> class + that contains elements copied from the specified <see cref="T:log4net.Appender.IAppender"/> collection. + </summary> + <param name="col">The <see cref="T:log4net.Appender.IAppender"/> collection whose elements are copied to the new list.</param> + </member> + <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.AppenderCollection.Tag)"> + <summary> + Allow subclasses to avoid our default constructors + </summary> + <param name="tag"></param> + <exclude/> + </member> + <member name="M:log4net.Appender.AppenderCollection.CopyTo(log4net.Appender.IAppender[])"> + <summary> + Copies the entire <c>AppenderCollection</c> to a one-dimensional + <see cref="T:log4net.Appender.IAppender"/> array. + </summary> + <param name="array">The one-dimensional <see cref="T:log4net.Appender.IAppender"/> array to copy to.</param> + </member> + <member name="M:log4net.Appender.AppenderCollection.CopyTo(log4net.Appender.IAppender[],System.Int32)"> + <summary> + Copies the entire <c>AppenderCollection</c> to a one-dimensional + <see cref="T:log4net.Appender.IAppender"/> array, starting at the specified index of the target array. + </summary> + <param name="array">The one-dimensional <see cref="T:log4net.Appender.IAppender"/> array to copy to.</param> + <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param> + </member> + <member name="M:log4net.Appender.AppenderCollection.Add(log4net.Appender.IAppender)"> + <summary> + Adds a <see cref="T:log4net.Appender.IAppender"/> to the end of the <c>AppenderCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to be added to the end of the <c>AppenderCollection</c>.</param> + <returns>The index at which the value has been added.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.Clear"> + <summary> + Removes all elements from the <c>AppenderCollection</c>. + </summary> + </member> + <member name="M:log4net.Appender.AppenderCollection.Clone"> + <summary> + Creates a shallow copy of the <see cref="T:log4net.Appender.AppenderCollection"/>. + </summary> + <returns>A new <see cref="T:log4net.Appender.AppenderCollection"/> with a shallow copy of the collection data.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.Contains(log4net.Appender.IAppender)"> + <summary> + Determines whether a given <see cref="T:log4net.Appender.IAppender"/> is in the <c>AppenderCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to check for.</param> + <returns><c>true</c> if <paramref name="item"/> is found in the <c>AppenderCollection</c>; otherwise, <c>false</c>.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.IndexOf(log4net.Appender.IAppender)"> + <summary> + Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Appender.IAppender"/> + in the <c>AppenderCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to locate in the <c>AppenderCollection</c>.</param> + <returns> + The zero-based index of the first occurrence of <paramref name="item"/> + in the entire <c>AppenderCollection</c>, if found; otherwise, -1. + </returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.Insert(System.Int32,log4net.Appender.IAppender)"> + <summary> + Inserts an element into the <c>AppenderCollection</c> at the specified index. + </summary> + <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param> + <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to insert.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Appender.AppenderCollection.Remove(log4net.Appender.IAppender)"> + <summary> + Removes the first occurrence of a specific <see cref="T:log4net.Appender.IAppender"/> from the <c>AppenderCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to remove from the <c>AppenderCollection</c>.</param> + <exception cref="T:System.ArgumentException"> + The specified <see cref="T:log4net.Appender.IAppender"/> was not found in the <c>AppenderCollection</c>. + </exception> + </member> + <member name="M:log4net.Appender.AppenderCollection.RemoveAt(System.Int32)"> + <summary> + Removes the element at the specified index of the <c>AppenderCollection</c>. + </summary> + <param name="index">The zero-based index of the element to remove.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Appender.AppenderCollection.GetEnumerator"> + <summary> + Returns an enumerator that can iterate through the <c>AppenderCollection</c>. + </summary> + <returns>An <see cref="T:log4net.Appender.AppenderCollection.Enumerator"/> for the entire <c>AppenderCollection</c>.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.AddRange(log4net.Appender.AppenderCollection)"> + <summary> + Adds the elements of another <c>AppenderCollection</c> to the current <c>AppenderCollection</c>. + </summary> + <param name="x">The <c>AppenderCollection</c> whose elements should be added to the end of the current <c>AppenderCollection</c>.</param> + <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.AddRange(log4net.Appender.IAppender[])"> + <summary> + Adds the elements of a <see cref="T:log4net.Appender.IAppender"/> array to the current <c>AppenderCollection</c>. + </summary> + <param name="x">The <see cref="T:log4net.Appender.IAppender"/> array whose elements should be added to the end of the <c>AppenderCollection</c>.</param> + <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.AddRange(System.Collections.ICollection)"> + <summary> + Adds the elements of a <see cref="T:log4net.Appender.IAppender"/> collection to the current <c>AppenderCollection</c>. + </summary> + <param name="col">The <see cref="T:log4net.Appender.IAppender"/> collection whose elements should be added to the end of the <c>AppenderCollection</c>.</param> + <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.TrimToSize"> + <summary> + Sets the capacity to the actual number of elements. + </summary> + </member> + <member name="M:log4net.Appender.AppenderCollection.ToArray"> + <summary> + Return the collection elements as an array + </summary> + <returns>the array</returns> + </member> + <member name="M:log4net.Appender.AppenderCollection.ValidateIndex(System.Int32)"> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Appender.AppenderCollection.ValidateIndex(System.Int32,System.Boolean)"> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para> + </exception> + </member> + <member name="P:log4net.Appender.AppenderCollection.Count"> + <summary> + Gets the number of elements actually contained in the <c>AppenderCollection</c>. + </summary> + </member> + <member name="P:log4net.Appender.AppenderCollection.IsSynchronized"> + <summary> + Gets a value indicating whether access to the collection is synchronized (thread-safe). + </summary> + <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns> + </member> + <member name="P:log4net.Appender.AppenderCollection.SyncRoot"> + <summary> + Gets an object that can be used to synchronize access to the collection. + </summary> + </member> + <member name="P:log4net.Appender.AppenderCollection.Item(System.Int32)"> + <summary> + Gets or sets the <see cref="T:log4net.Appender.IAppender"/> at the specified index. + </summary> + <param name="index">The zero-based index of the element to get or set.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para> + </exception> + </member> + <member name="P:log4net.Appender.AppenderCollection.IsFixedSize"> + <summary> + Gets a value indicating whether the collection has a fixed size. + </summary> + <value>true if the collection has a fixed size; otherwise, false. The default is false</value> + </member> + <member name="P:log4net.Appender.AppenderCollection.IsReadOnly"> + <summary> + Gets a value indicating whether the IList is read-only. + </summary> + <value>true if the collection is read-only; otherwise, false. The default is false</value> + </member> + <member name="P:log4net.Appender.AppenderCollection.Capacity"> + <summary> + Gets or sets the number of elements the <c>AppenderCollection</c> can contain. + </summary> + </member> + <member name="T:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator"> + <summary> + Supports type-safe iteration over a <see cref="T:log4net.Appender.AppenderCollection"/>. + </summary> + <exclude/> + </member> + <member name="M:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.MoveNext"> + <summary> + Advances the enumerator to the next element in the collection. + </summary> + <returns> + <c>true</c> if the enumerator was successfully advanced to the next element; + <c>false</c> if the enumerator has passed the end of the collection. + </returns> + <exception cref="T:System.InvalidOperationException"> + The collection was modified after the enumerator was created. + </exception> + </member> + <member name="M:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.Reset"> + <summary> + Sets the enumerator to its initial position, before the first element in the collection. + </summary> + </member> + <member name="P:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.Current"> + <summary> + Gets the current element in the collection. + </summary> + </member> + <member name="T:log4net.Appender.AppenderCollection.Tag"> + <summary> + Type visible only to our subclasses + Used to access protected constructor + </summary> + <exclude/> + </member> + <member name="F:log4net.Appender.AppenderCollection.Tag.Default"> + <summary> + A value + </summary> + </member> + <member name="T:log4net.Appender.AppenderCollection.Enumerator"> + <summary> + Supports simple iteration over a <see cref="T:log4net.Appender.AppenderCollection"/>. + </summary> + <exclude/> + </member> + <member name="M:log4net.Appender.AppenderCollection.Enumerator.#ctor(log4net.Appender.AppenderCollection)"> + <summary> + Initializes a new instance of the <c>Enumerator</c> class. + </summary> + <param name="tc"></param> + </member> + <member name="M:log4net.Appender.AppenderCollection.Enumerator.MoveNext"> + <summary> + Advances the enumerator to the next element in the collection. + </summary> + <returns> + <c>true</c> if the enumerator was successfully advanced to the next element; + <c>false</c> if the enumerator has passed the end of the collection. + </returns> + <exception cref="T:System.InvalidOperationException"> + The collection was modified after the enumerator was created. + </exception> + </member> + <member name="M:log4net.Appender.AppenderCollection.Enumerator.Reset"> + <summary> + Sets the enumerator to its initial position, before the first element in the collection. + </summary> + </member> + <member name="P:log4net.Appender.AppenderCollection.Enumerator.Current"> + <summary> + Gets the current element in the collection. + </summary> + </member> + <member name="T:log4net.Appender.AppenderCollection.ReadOnlyAppenderCollection"> + <exclude/> + </member> + <member name="T:log4net.Appender.AspNetTraceAppender"> + <summary> + <para> + Appends log events to the ASP.NET <see cref="T:System.Web.TraceContext"/> system. + </para> + </summary> + <remarks> + <para> + Diagnostic information and tracing messages that you specify are appended to the output + of the page that is sent to the requesting browser. Optionally, you can view this information + from a separate trace viewer (Trace.axd) that displays trace information for every page in a + given application. + </para> + <para> + Trace statements are processed and displayed only when tracing is enabled. You can control + whether tracing is displayed to a page, to the trace viewer, or both. + </para> + <para> + The logging event is passed to the <see cref="M:System.Web.TraceContext.Write(System.String)"/> or + <see cref="M:System.Web.TraceContext.Warn(System.String)"/> method depending on the level of the logging event. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.AspNetTraceAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.AspNetTraceAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.AspNetTraceAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Write the logging event to the ASP.NET trace + </summary> + <param name="loggingEvent">the event to log</param> + <remarks> + <para> + Write the logging event to the ASP.NET trace + <c>HttpContext.Current.Trace</c> + (<see cref="T:System.Web.TraceContext"/>). + </para> + </remarks> + </member> + <member name="P:log4net.Appender.AspNetTraceAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.BufferingForwardingAppender"> + <summary> + Buffers events and then forwards them to attached appenders. + </summary> + <remarks> + <para> + The events are buffered in this appender until conditions are + met to allow the appender to deliver the events to the attached + appenders. See <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> for the + conditions that cause the buffer to be sent. + </para> + <para>The forwarding appender can be used to specify different + thresholds and filters for the same appender at different locations + within the hierarchy. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Core.IAppenderAttachable"> + <summary> + Interface for attaching appenders to objects. + </summary> + <remarks> + <para> + Interface for attaching, removing and retrieving appenders. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.IAppenderAttachable.AddAppender(log4net.Appender.IAppender)"> + <summary> + Attaches an appender. + </summary> + <param name="appender">The appender to add.</param> + <remarks> + <para> + Add the specified appender. The implementation may + choose to allow or deny duplicate appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IAppenderAttachable.GetAppender(System.String)"> + <summary> + Gets an attached appender with the specified name. + </summary> + <param name="name">The name of the appender to get.</param> + <returns> + The appender with the name specified, or <c>null</c> if no appender with the + specified name is found. + </returns> + <remarks> + <para> + Returns an attached appender with the <paramref name="name"/> specified. + If no appender with the specified name is found <c>null</c> will be + returned. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IAppenderAttachable.RemoveAllAppenders"> + <summary> + Removes all attached appenders. + </summary> + <remarks> + <para> + Removes and closes all attached appenders + </para> + </remarks> + </member> + <member name="M:log4net.Core.IAppenderAttachable.RemoveAppender(log4net.Appender.IAppender)"> + <summary> + Removes the specified appender from the list of attached appenders. + </summary> + <param name="appender">The appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + <para> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IAppenderAttachable.RemoveAppender(System.String)"> + <summary> + Removes the appender with the specified name from the list of appenders. + </summary> + <param name="name">The name of the appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + <para> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </para> + </remarks> + </member> + <member name="P:log4net.Core.IAppenderAttachable.Appenders"> + <summary> + Gets all attached appenders. + </summary> + <value> + A collection of attached appenders. + </value> + <remarks> + <para> + Gets a collection of attached appenders. + If there are no attached appenders the + implementation should return an empty + collection rather than <c>null</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.BufferingForwardingAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.OnClose"> + <summary> + Closes the appender and releases resources. + </summary> + <remarks> + <para> + Releases any resources allocated within the appender such as file handles, + network connections, etc. + </para> + <para> + It is a programming error to append to a closed appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.SendBuffer(log4net.Core.LoggingEvent[])"> + <summary> + Send the events. + </summary> + <param name="events">The events that need to be send.</param> + <remarks> + <para> + Forwards the events to the attached appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.AddAppender(log4net.Appender.IAppender)"> + <summary> + Adds an <see cref="T:log4net.Appender.IAppender"/> to the list of appenders of this + instance. + </summary> + <param name="newAppender">The <see cref="T:log4net.Appender.IAppender"/> to add to this appender.</param> + <remarks> + <para> + If the specified <see cref="T:log4net.Appender.IAppender"/> is already in the list of + appenders, then it won't be added again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.GetAppender(System.String)"> + <summary> + Looks for the appender with the specified name. + </summary> + <param name="name">The name of the appender to lookup.</param> + <returns> + The appender with the specified name, or <c>null</c>. + </returns> + <remarks> + <para> + Get the named appender attached to this buffering appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAllAppenders"> + <summary> + Removes all previously added appenders from this appender. + </summary> + <remarks> + <para> + This is useful when re-reading configuration information. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAppender(log4net.Appender.IAppender)"> + <summary> + Removes the specified appender from the list of appenders. + </summary> + <param name="appender">The appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </remarks> + </member> + <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAppender(System.String)"> + <summary> + Removes the appender with the specified name from the list of appenders. + </summary> + <param name="name">The name of the appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </remarks> + </member> + <member name="F:log4net.Appender.BufferingForwardingAppender.m_appenderAttachedImpl"> + <summary> + Implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface + </summary> + </member> + <member name="P:log4net.Appender.BufferingForwardingAppender.Appenders"> + <summary> + Gets the appenders contained in this appender as an + <see cref="T:System.Collections.ICollection"/>. + </summary> + <remarks> + If no appenders can be found, then an <see cref="T:log4net.Util.EmptyCollection"/> + is returned. + </remarks> + <returns> + A collection of the appenders in this appender. + </returns> + </member> + <member name="T:log4net.Appender.ColoredConsoleAppender"> + <summary> + Appends logging events to the console. + </summary> + <remarks> + <para> + ColoredConsoleAppender appends log events to the standard output stream + or the error output stream using a layout specified by the + user. It also allows the color of a specific type of message to be set. + </para> + <para> + By default, all output is written to the console's standard output stream. + The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> property can be set to direct the output to the + error stream. + </para> + <para> + NOTE: This appender writes directly to the application's attached console + not to the <c>System.Console.Out</c> or <c>System.Console.Error</c> <c>TextWriter</c>. + The <c>System.Console.Out</c> and <c>System.Console.Error</c> streams can be + programmatically redirected (for example NUnit does this to capture program output). + This appender will ignore these redirections because it needs to use Win32 + API calls to colorize the output. To respect these redirections the <see cref="T:log4net.Appender.ConsoleAppender"/> + must be used. + </para> + <para> + When configuring the colored console appender, mapping should be + specified to map a logging level to a color. For example: + </para> + <code lang="XML" escaped="true"> + <mapping> + <level value="ERROR"/> + <foreColor value="White"/> + <backColor value="Red, HighIntensity"/> + </mapping> + <mapping> + <level value="DEBUG"/> + <backColor value="Green"/> + </mapping> + </code> + <para> + The Level is the standard log4net logging level and ForeColor and BackColor can be any + combination of the following values: + <list type="bullet"> + <item><term>Blue</term><description></description></item> + <item><term>Green</term><description></description></item> + <item><term>Red</term><description></description></item> + <item><term>White</term><description></description></item> + <item><term>Yellow</term><description></description></item> + <item><term>Purple</term><description></description></item> + <item><term>Cyan</term><description></description></item> + <item><term>HighIntensity</term><description></description></item> + </list> + </para> + </remarks> + <author>Rick Hobbs</author> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.ConsoleOut"> + <summary> + The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console + standard output stream. + </summary> + <remarks> + <para> + The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console + standard output stream. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.ConsoleError"> + <summary> + The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console + standard error output stream. + </summary> + <remarks> + <para> + The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console + standard error output stream. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class. + </summary> + <remarks> + The instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class is set up to write + to the standard output stream. + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor(log4net.Layout.ILayout)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class + with the specified layout. + </summary> + <param name="layout">the layout to use for this appender</param> + <remarks> + The instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class is set up to write + to the standard output stream. + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor(log4net.Layout.ILayout,System.Boolean)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class + with the specified layout. + </summary> + <param name="layout">the layout to use for this appender</param> + <param name="writeToErrorStream">flag set to <c>true</c> to write to the console error stream</param> + <remarks> + When <paramref name="writeToErrorStream"/> is set to <c>true</c>, output is written to + the standard error output stream. Otherwise, output is written to the standard + output stream. + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.AddMapping(log4net.Appender.ColoredConsoleAppender.LevelColors)"> + <summary> + Add a mapping of level to color - done by the config file + </summary> + <param name="mapping">The mapping to add</param> + <remarks> + <para> + Add a <see cref="T:log4net.Appender.ColoredConsoleAppender.LevelColors"/> mapping to this appender. + Each mapping defines the foreground and background colors + for a level. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the event to the console. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.ActivateOptions"> + <summary> + Initialize the options for this appender + </summary> + <remarks> + <para> + Initialize the level to color mappings set on this appender. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.m_writeToErrorStream"> + <summary> + Flag to write output to the error stream rather than the standard output stream + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.m_levelMapping"> + <summary> + Mapping from level object to color value + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.m_consoleOutputWriter"> + <summary> + The console output stream writer to write to + </summary> + <remarks> + <para> + This writer is not thread safe. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ColoredConsoleAppender.Target"> + <summary> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </summary> + <value> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </value> + <remarks> + <para> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ColoredConsoleAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.ColoredConsoleAppender.Colors"> + <summary> + The enum of possible color values for use with the color mapping method + </summary> + <remarks> + <para> + The following flags can be combined together to + form the colors. + </para> + </remarks> + <seealso cref="T:log4net.Appender.ColoredConsoleAppender"/> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Blue"> + <summary> + color is blue + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Green"> + <summary> + color is green + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Red"> + <summary> + color is red + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.White"> + <summary> + color is white + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Yellow"> + <summary> + color is yellow + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Purple"> + <summary> + color is purple + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Cyan"> + <summary> + color is cyan + </summary> + </member> + <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.HighIntensity"> + <summary> + color is intensified + </summary> + </member> + <member name="T:log4net.Appender.ColoredConsoleAppender.LevelColors"> + <summary> + A class to act as a mapping between the level that a logging call is made at and + the color it should be displayed as. + </summary> + <remarks> + <para> + Defines the mapping between a level and the color it should be displayed in. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ColoredConsoleAppender.LevelColors.ActivateOptions"> + <summary> + Initialize the options for the object + </summary> + <remarks> + <para> + Combine the <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"/> together. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"> + <summary> + The mapped foreground color for the specified level + </summary> + <remarks> + <para> + Required property. + The mapped foreground color for the specified level. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"> + <summary> + The mapped background color for the specified level + </summary> + <remarks> + <para> + Required property. + The mapped background color for the specified level. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.CombinedColor"> + <summary> + The combined <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"/> suitable for + setting the console color. + </summary> + </member> + <member name="T:log4net.Appender.ConsoleAppender"> + <summary> + Appends logging events to the console. + </summary> + <remarks> + <para> + ConsoleAppender appends log events to the standard output stream + or the error output stream using a layout specified by the + user. + </para> + <para> + By default, all output is written to the console's standard output stream. + The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> property can be set to direct the output to the + error stream. + </para> + <para> + NOTE: This appender writes each message to the <c>System.Console.Out</c> or + <c>System.Console.Error</c> that is set at the time the event is appended. + Therefore it is possible to programmatically redirect the output of this appender + (for example NUnit does this to capture program output). While this is the desired + behavior of this appender it may have security implications in your application. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Appender.ConsoleAppender.ConsoleOut"> + <summary> + The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console + standard output stream. + </summary> + <remarks> + <para> + The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console + standard output stream. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.ConsoleAppender.ConsoleError"> + <summary> + The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console + standard error output stream. + </summary> + <remarks> + <para> + The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console + standard error output stream. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ConsoleAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class. + </summary> + <remarks> + The instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class is set up to write + to the standard output stream. + </remarks> + </member> + <member name="M:log4net.Appender.ConsoleAppender.#ctor(log4net.Layout.ILayout)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class + with the specified layout. + </summary> + <param name="layout">the layout to use for this appender</param> + <remarks> + The instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class is set up to write + to the standard output stream. + </remarks> + </member> + <member name="M:log4net.Appender.ConsoleAppender.#ctor(log4net.Layout.ILayout,System.Boolean)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class + with the specified layout. + </summary> + <param name="layout">the layout to use for this appender</param> + <param name="writeToErrorStream">flag set to <c>true</c> to write to the console error stream</param> + <remarks> + When <paramref name="writeToErrorStream"/> is set to <c>true</c>, output is written to + the standard error output stream. Otherwise, output is written to the standard + output stream. + </remarks> + </member> + <member name="M:log4net.Appender.ConsoleAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the event to the console. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ConsoleAppender.Target"> + <summary> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </summary> + <value> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </value> + <remarks> + <para> + Target is the value of the console output stream. + This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.ConsoleAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.DebugAppender"> + <summary> + Appends log events to the <see cref="T:System.Diagnostics.Debug"/> system. + </summary> + <remarks> + <para> + The application configuration file can be used to control what listeners + are actually used. See the MSDN documentation for the + <see cref="T:System.Diagnostics.Debug"/> class for details on configuring the + debug system. + </para> + <para> + Events are written using the <see cref="M:System.Diagnostics.Debug.Write(System.String,System.String)"/> + method. The event's logger name is passed as the value for the category name to the Write method. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.DebugAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.DebugAppender"/>. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.DebugAppender.#ctor(log4net.Layout.ILayout)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.DebugAppender"/> + with a specified layout. + </summary> + <param name="layout">The layout to use with this appender.</param> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.DebugAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Writes the logging event to the <see cref="T:System.Diagnostics.Debug"/> system. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the logging event to the <see cref="T:System.Diagnostics.Debug"/> system. + If <see cref="P:log4net.Appender.DebugAppender.ImmediateFlush"/> is <c>true</c> then the <see cref="M:System.Diagnostics.Debug.Flush"/> + is called. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.DebugAppender.m_immediateFlush"> + <summary> + Immediate flush means that the underlying writer or output stream + will be flushed at the end of each append operation. + </summary> + <remarks> + <para> + Immediate flush is slower but ensures that each append request is + actually written. If <see cref="P:log4net.Appender.DebugAppender.ImmediateFlush"/> is set to + <c>false</c>, then there is a good chance that the last few + logs events are not actually written to persistent media if and + when the application crashes. + </para> + <para> + The default value is <c>true</c>.</para> + </remarks> + </member> + <member name="P:log4net.Appender.DebugAppender.ImmediateFlush"> + <summary> + Gets or sets a value that indicates whether the appender will + flush at the end of each write. + </summary> + <remarks> + <para>The default behavior is to flush at the end of each + write. If the option is set to<c>false</c>, then the underlying + stream can defer writing to physical medium to a later time. + </para> + <para> + Avoiding the flush operation at the end of each append results + in a performance gain of 10 to 20 percent. However, there is safety + trade-off involved in skipping flushing. Indeed, when flushing is + skipped, then it is likely that the last few log events will not + be recorded on disk when the application exits. This is a high + price to pay even for a 20% performance gain. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.DebugAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.EventLogAppender"> + <summary> + Writes events to the system event log. + </summary> + <remarks> + <para> + The <c>EventID</c> of the event log entry can be + set using the <c>EventLogEventID</c> property (<see cref="P:log4net.Core.LoggingEvent.Properties"/>) + on the <see cref="T:log4net.Core.LoggingEvent"/>. + </para> + <para> + There is a limit of 32K characters for an event log message + </para> + <para> + When configuring the EventLogAppender a mapping can be + specified to map a logging level to an event log entry type. For example: + </para> + <code lang="XML"> + <mapping> + <level value="ERROR" /> + <eventLogEntryType value="Error" /> + </mapping> + <mapping> + <level value="DEBUG" /> + <eventLogEntryType value="Information" /> + </mapping> + </code> + <para> + The Level is the standard log4net logging level and eventLogEntryType can be any value + from the <see cref="T:System.Diagnostics.EventLogEntryType"/> enum, i.e.: + <list type="bullet"> + <item><term>Error</term><description>an error event</description></item> + <item><term>Warning</term><description>a warning event</description></item> + <item><term>Information</term><description>an informational event</description></item> + </list> + </para> + </remarks> + <author>Aspi Havewala</author> + <author>Douglas de la Torre</author> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Thomas Voss</author> + </member> + <member name="M:log4net.Appender.EventLogAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.EventLogAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.EventLogAppender.#ctor(log4net.Layout.ILayout)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.EventLogAppender"/> class + with the specified <see cref="T:log4net.Layout.ILayout"/>. + </summary> + <param name="layout">The <see cref="T:log4net.Layout.ILayout"/> to use with this appender.</param> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.EventLogAppender.AddMapping(log4net.Appender.EventLogAppender.Level2EventLogEntryType)"> + <summary> + Add a mapping of level to <see cref="T:System.Diagnostics.EventLogEntryType"/> - done by the config file + </summary> + <param name="mapping">The mapping to add</param> + <remarks> + <para> + Add a <see cref="T:log4net.Appender.EventLogAppender.Level2EventLogEntryType"/> mapping to this appender. + Each mapping defines the event log entry type for a level. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.EventLogAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.EventLogAppender.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="M:log4net.Appender.EventLogAppender.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.EventLogAppender.CreateEventSource(System.String,System.String,System.String)"> + <summary> + Create an event log source + </summary> + <remarks> + Uses different API calls under NET_2_0 + </remarks> + </member> + <member name="M:log4net.Appender.EventLogAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> + method. + </summary> + <param name="loggingEvent">the event to log</param> + <remarks> + <para>Writes the event to the system event log using the + <see cref="P:log4net.Appender.EventLogAppender.ApplicationName"/>.</para> + + <para>If the event has an <c>EventID</c> property (see <see cref="P:log4net.Core.LoggingEvent.Properties"/>) + set then this integer will be used as the event log event id.</para> + + <para> + There is a limit of 32K characters for an event log message + </para> + </remarks> + </member> + <member name="M:log4net.Appender.EventLogAppender.GetEntryType(log4net.Core.Level)"> + <summary> + Get the equivalent <see cref="T:System.Diagnostics.EventLogEntryType"/> for a <see cref="T:log4net.Core.Level"/> <paramref name="p"/> + </summary> + <param name="level">the Level to convert to an EventLogEntryType</param> + <returns>The equivalent <see cref="T:System.Diagnostics.EventLogEntryType"/> for a <see cref="T:log4net.Core.Level"/> <paramref name="p"/></returns> + <remarks> + Because there are fewer applicable <see cref="T:System.Diagnostics.EventLogEntryType"/> + values to use in logging levels than there are in the + <see cref="T:log4net.Core.Level"/> this is a one way mapping. There is + a loss of information during the conversion. + </remarks> + </member> + <member name="F:log4net.Appender.EventLogAppender.m_logName"> + <summary> + The log name is the section in the event logs where the messages + are stored. + </summary> + </member> + <member name="F:log4net.Appender.EventLogAppender.m_applicationName"> + <summary> + Name of the application to use when logging. This appears in the + application column of the event log named by <see cref="F:log4net.Appender.EventLogAppender.m_logName"/>. + </summary> + </member> + <member name="F:log4net.Appender.EventLogAppender.m_machineName"> + <summary> + The name of the machine which holds the event log. This is + currently only allowed to be '.' i.e. the current machine. + </summary> + </member> + <member name="F:log4net.Appender.EventLogAppender.m_levelMapping"> + <summary> + Mapping from level object to EventLogEntryType + </summary> + </member> + <member name="F:log4net.Appender.EventLogAppender.m_securityContext"> + <summary> + The security context to use for privileged calls + </summary> + </member> + <member name="P:log4net.Appender.EventLogAppender.LogName"> + <summary> + The name of the log where messages will be stored. + </summary> + <value> + The string name of the log where messages will be stored. + </value> + <remarks> + <para>This is the name of the log as it appears in the Event Viewer + tree. The default value is to log into the <c>Application</c> + log, this is where most applications write their events. However + if you need a separate log for your application (or applications) + then you should set the <see cref="P:log4net.Appender.EventLogAppender.LogName"/> appropriately.</para> + <para>This should not be used to distinguish your event log messages + from those of other applications, the <see cref="P:log4net.Appender.EventLogAppender.ApplicationName"/> + property should be used to distinguish events. This property should be + used to group together events into a single log. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.EventLogAppender.ApplicationName"> + <summary> + Property used to set the Application name. This appears in the + event logs when logging. + </summary> + <value> + The string used to distinguish events from different sources. + </value> + <remarks> + Sets the event log source property. + </remarks> + </member> + <member name="P:log4net.Appender.EventLogAppender.MachineName"> + <summary> + This property is used to return the name of the computer to use + when accessing the event logs. Currently, this is the current + computer, denoted by a dot "." + </summary> + <value> + The string name of the machine holding the event log that + will be logged into. + </value> + <remarks> + This property cannot be changed. It is currently set to '.' + i.e. the local machine. This may be changed in future. + </remarks> + </member> + <member name="P:log4net.Appender.EventLogAppender.SecurityContext"> + <summary> + Gets or sets the <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> used to write to the EventLog. + </summary> + <value> + The <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> used to write to the EventLog. + </value> + <remarks> + <para> + The system security context used to write to the EventLog. + </para> + <para> + Unless a <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> specified here for this appender + the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the + security context to use. The default behavior is to use the security context + of the current thread. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.EventLogAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.EventLogAppender.Level2EventLogEntryType"> + <summary> + A class to act as a mapping between the level that a logging call is made at and + the color it should be displayed as. + </summary> + <remarks> + <para> + Defines the mapping between a level and its event log entry type. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"> + <summary> + The <see cref="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"/> for this entry + </summary> + <remarks> + <para> + Required property. + The <see cref="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"/> for this entry + </para> + </remarks> + </member> + <member name="T:log4net.Appender.FileAppender"> + <summary> + Appends logging events to a file. + </summary> + <remarks> + <para> + Logging events are sent to the file specified by + the <see cref="P:log4net.Appender.FileAppender.File"/> property. + </para> + <para> + The file can be opened in either append or overwrite mode + by specifying the <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property. + If the file path is relative it is taken as relative from + the application base directory. The file encoding can be + specified by setting the <see cref="P:log4net.Appender.FileAppender.Encoding"/> property. + </para> + <para> + The layout's <see cref="P:log4net.Layout.ILayout.Header"/> and <see cref="P:log4net.Layout.ILayout.Footer"/> + values will be written each time the file is opened and closed + respectively. If the <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property is <see langword="true"/> + then the file may contain multiple copies of the header and footer. + </para> + <para> + This appender will first try to open the file for writing when <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> + is called. This will typically be during configuration. + If the file cannot be opened for writing the appender will attempt + to open the file again each time a message is logged to the appender. + If the file cannot be opened for writing when a message is logged then + the message will be discarded by this appender. + </para> + <para> + The <see cref="T:log4net.Appender.FileAppender"/> supports pluggable file locking models via + the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> property. + The default behavior, implemented by <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> + is to obtain an exclusive write lock on the file until this appender is closed. + The alternative model, <see cref="T:log4net.Appender.FileAppender.MinimalLock"/>, only holds a + write lock while the appender is writing a logging event. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Rodrigo B. de Oliveira</author> + <author>Douglas de la Torre</author> + <author>Niall Daley</author> + </member> + <member name="T:log4net.Appender.TextWriterAppender"> + <summary> + Sends logging events to a <see cref="T:System.IO.TextWriter"/>. + </summary> + <remarks> + <para> + An Appender that writes to a <see cref="T:System.IO.TextWriter"/>. + </para> + <para> + This appender may be used stand alone if initialized with an appropriate + writer, however it is typically used as a base class for an appender that + can open a <see cref="T:System.IO.TextWriter"/> to write to. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Douglas de la Torre</author> + </member> + <member name="M:log4net.Appender.TextWriterAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.#ctor(log4net.Layout.ILayout,System.IO.Stream)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class and + sets the output destination to a new <see cref="T:System.IO.StreamWriter"/> initialized + with the specified <see cref="T:System.IO.Stream"/>. + </summary> + <param name="layout">The layout to use with this appender.</param> + <param name="os">The <see cref="T:System.IO.Stream"/> to output to.</param> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.#ctor(log4net.Layout.ILayout,System.IO.TextWriter)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class and sets + the output destination to the specified <see cref="T:System.IO.StreamWriter"/>. + </summary> + <param name="layout">The layout to use with this appender</param> + <param name="writer">The <see cref="T:System.IO.TextWriter"/> to output to</param> + <remarks> + The <see cref="T:System.IO.TextWriter"/> must have been previously opened. + </remarks> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.PreAppendCheck"> + <summary> + This method determines if there is a sense in attempting to append. + </summary> + <remarks> + <para> + This method checked if an output target has been set and if a + layout has been set. + </para> + </remarks> + <returns><c>false</c> if any of the preconditions fail.</returns> + </member> + <member name="M:log4net.Appender.TextWriterAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> + method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes a log statement to the output stream if the output stream exists + and is writable. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.Append(log4net.Core.LoggingEvent[])"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"/> + method. + </summary> + <param name="loggingEvents">The array of events to log.</param> + <remarks> + <para> + This method writes all the bulk logged events to the output writer + before flushing the stream. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.OnClose"> + <summary> + Close this appender instance. The underlying stream or writer is also closed. + </summary> + <remarks> + Closed appenders cannot be reused. + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.WriteFooterAndCloseWriter"> + <summary> + Writes the footer and closes the underlying <see cref="T:System.IO.TextWriter"/>. + </summary> + <remarks> + <para> + Writes the footer and closes the underlying <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.CloseWriter"> + <summary> + Closes the underlying <see cref="T:System.IO.TextWriter"/>. + </summary> + <remarks> + <para> + Closes the underlying <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.Reset"> + <summary> + Clears internal references to the underlying <see cref="T:System.IO.TextWriter"/> + and other variables. + </summary> + <remarks> + <para> + Subclasses can override this method for an alternate closing behavior. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.WriteFooter"> + <summary> + Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property. + </summary> + <remarks> + <para> + Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.WriteHeader"> + <summary> + Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property. + </summary> + <remarks> + <para> + Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TextWriterAppender.PrepareWriter"> + <summary> + Called to allow a subclass to lazily initialize the writer + </summary> + <remarks> + <para> + This method is called when an event is logged and the <see cref="P:log4net.Appender.TextWriterAppender.Writer"/> or + <see cref="P:log4net.Appender.TextWriterAppender.QuietWriter"/> have not been set. This allows a subclass to + attempt to initialize the writer multiple times. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.TextWriterAppender.m_qtw"> + <summary> + This is the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events + will be written to. + </summary> + </member> + <member name="F:log4net.Appender.TextWriterAppender.m_immediateFlush"> + <summary> + Immediate flush means that the underlying <see cref="T:System.IO.TextWriter"/> + or output stream will be flushed at the end of each append operation. + </summary> + <remarks> + <para> + Immediate flush is slower but ensures that each append request is + actually written. If <see cref="P:log4net.Appender.TextWriterAppender.ImmediateFlush"/> is set to + <c>false</c>, then there is a good chance that the last few + logging events are not actually persisted if and when the application + crashes. + </para> + <para> + The default value is <c>true</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.TextWriterAppender.ImmediateFlush"> + <summary> + Gets or set whether the appender will flush at the end + of each append operation. + </summary> + <value> + <para> + The default behavior is to flush at the end of each + append operation. + </para> + <para> + If this option is set to <c>false</c>, then the underlying + stream can defer persisting the logging event to a later + time. + </para> + </value> + <remarks> + Avoiding the flush operation at the end of each append results in + a performance gain of 10 to 20 percent. However, there is safety + trade-off involved in skipping flushing. Indeed, when flushing is + skipped, then it is likely that the last few log events will not + be recorded on disk when the application exits. This is a high + price to pay even for a 20% performance gain. + </remarks> + </member> + <member name="P:log4net.Appender.TextWriterAppender.Writer"> + <summary> + Sets the <see cref="T:System.IO.TextWriter"/> where the log output will go. + </summary> + <remarks> + <para> + The specified <see cref="T:System.IO.TextWriter"/> must be open and writable. + </para> + <para> + The <see cref="T:System.IO.TextWriter"/> will be closed when the appender + instance is closed. + </para> + <para> + <b>Note:</b> Logging to an unopened <see cref="T:System.IO.TextWriter"/> will fail. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.TextWriterAppender.ErrorHandler"> + <summary> + Gets or set the <see cref="T:log4net.Core.IErrorHandler"/> and the underlying + <see cref="T:log4net.Util.QuietTextWriter"/>, if any, for this appender. + </summary> + <value> + The <see cref="T:log4net.Core.IErrorHandler"/> for this appender. + </value> + </member> + <member name="P:log4net.Appender.TextWriterAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.TextWriterAppender.QuietWriter"> + <summary> + Gets or sets the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events + will be written to. + </summary> + <value> + The <see cref="T:log4net.Util.QuietTextWriter"/> where logging events are written. + </value> + <remarks> + <para> + This is the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events + will be written to. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.#ctor(log4net.Layout.ILayout,System.String,System.Boolean)"> + <summary> + Construct a new appender using the layout, file and append mode. + </summary> + <param name="layout">the layout to use with this appender</param> + <param name="filename">the full path to the file to write to</param> + <param name="append">flag to indicate if the file should be appended to</param> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.#ctor(log4net.Layout.ILayout,System.String)"> + <summary> + Construct a new appender using the layout and file specified. + The file will be appended to. + </summary> + <param name="layout">the layout to use with this appender</param> + <param name="filename">the full path to the file to write to</param> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.ActivateOptions"> + <summary> + Activate the options on the file appender. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.FileAppender.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="M:log4net.Appender.FileAppender.ActivateOptions"/> must be called again. + </para> + <para> + This will cause the file to be opened. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.Reset"> + <summary> + Closes any previously opened file and calls the parent's <see cref="M:log4net.Appender.TextWriterAppender.Reset"/>. + </summary> + <remarks> + <para> + Resets the filename and the file stream. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.PrepareWriter"> + <summary> + Called to initialize the file writer + </summary> + <remarks> + <para> + Will be called for each logged message until the file is + successfully opened. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> + method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes a log statement to the output stream if the output stream exists + and is writable. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.Append(log4net.Core.LoggingEvent[])"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"/> + method. + </summary> + <param name="loggingEvents">The array of events to log.</param> + <remarks> + <para> + Acquires the output file locks once before writing all the events to + the stream. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.WriteFooter"> + <summary> + Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property. + </summary> + <remarks> + <para> + Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.WriteHeader"> + <summary> + Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property. + </summary> + <remarks> + <para> + Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.CloseWriter"> + <summary> + Closes the underlying <see cref="T:System.IO.TextWriter"/>. + </summary> + <remarks> + <para> + Closes the underlying <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.CloseFile"> + <summary> + Closes the previously opened file. + </summary> + <remarks> + <para> + Writes the <see cref="P:log4net.Layout.ILayout.Footer"/> to the file and then + closes the file. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.SafeOpenFile(System.String,System.Boolean)"> + <summary> + Sets and <i>opens</i> the file where the log output will go. The specified file must be writable. + </summary> + <param name="fileName">The path to the log file. Must be a fully qualified path.</param> + <param name="append">If true will append to fileName. Otherwise will truncate fileName</param> + <remarks> + <para> + Calls <see cref="M:log4net.Appender.FileAppender.OpenFile(System.String,System.Boolean)"/> but guarantees not to throw an exception. + Errors are passed to the <see cref="P:log4net.Appender.TextWriterAppender.ErrorHandler"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.OpenFile(System.String,System.Boolean)"> + <summary> + Sets and <i>opens</i> the file where the log output will go. The specified file must be writable. + </summary> + <param name="fileName">The path to the log file. Must be a fully qualified path.</param> + <param name="append">If true will append to fileName. Otherwise will truncate fileName</param> + <remarks> + <para> + If there was already an opened file, then the previous file + is closed first. + </para> + <para> + This method will ensure that the directory structure + for the <paramref name="fileName"/> specified exists. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.Stream)"> + <summary> + Sets the quiet writer used for file output + </summary> + <param name="fileStream">the file stream that has been opened for writing</param> + <remarks> + <para> + This implementation of <see cref="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.Stream)"/> creates a <see cref="T:System.IO.StreamWriter"/> + over the <paramref name="fileStream"/> and passes it to the + <see cref="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.TextWriter)"/> method. + </para> + <para> + This method can be overridden by sub classes that want to wrap the + <see cref="T:System.IO.Stream"/> in some way, for example to encrypt the output + data using a <c>System.Security.Cryptography.CryptoStream</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.TextWriter)"> + <summary> + Sets the quiet writer being used. + </summary> + <param name="writer">the writer over the file stream that has been opened for writing</param> + <remarks> + <para> + This method can be overridden by sub classes that want to + wrap the <see cref="T:System.IO.TextWriter"/> in some way. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.ConvertToFullPath(System.String)"> + <summary> + Convert a path into a fully qualified path. + </summary> + <param name="path">The path to convert.</param> + <returns>The fully qualified path.</returns> + <remarks> + <para> + Converts the path specified to a fully + qualified path. If the path is relative it is + taken as relative from the application base + directory. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.FileAppender.m_appendToFile"> + <summary> + Flag to indicate if we should append to the file + or overwrite the file. The default is to append. + </summary> + </member> + <member name="F:log4net.Appender.FileAppender.m_fileName"> + <summary> + The name of the log file. + </summary> + </member> + <member name="F:log4net.Appender.FileAppender.m_encoding"> + <summary> + The encoding to use for the file stream. + </summary> + </member> + <member name="F:log4net.Appender.FileAppender.m_securityContext"> + <summary> + The security context to use for privileged calls + </summary> + </member> + <member name="F:log4net.Appender.FileAppender.m_stream"> + <summary> + The stream to log to. Has added locking semantics + </summary> + </member> + <member name="F:log4net.Appender.FileAppender.m_lockingModel"> + <summary> + The locking model to use + </summary> + </member> + <member name="P:log4net.Appender.FileAppender.File"> + <summary> + Gets or sets the path to the file that logging will be written to. + </summary> + <value> + The path to the file that logging will be written to. + </value> + <remarks> + <para> + If the path is relative it is taken as relative from + the application base directory. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.FileAppender.AppendToFile"> + <summary> + Gets or sets a flag that indicates whether the file should be + appended to or overwritten. + </summary> + <value> + Indicates whether the file should be appended to or overwritten. + </value> + <remarks> + <para> + If the value is set to false then the file will be overwritten, if + it is set to true then the file will be appended to. + </para> + The default value is true. + </remarks> + </member> + <member name="P:log4net.Appender.FileAppender.Encoding"> + <summary> + Gets or sets <see cref="P:log4net.Appender.FileAppender.Encoding"/> used to write to the file. + </summary> + <value> + The <see cref="P:log4net.Appender.FileAppender.Encoding"/> used to write to the file. + </value> + <remarks> + <para> + The default encoding set is <see cref="P:System.Text.Encoding.Default"/> + which is the encoding for the system's current ANSI code page. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.FileAppender.SecurityContext"> + <summary> + Gets or sets the <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> used to write to the file. + </summary> + <value> + The <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> used to write to the file. + </value> + <remarks> + <para> + Unless a <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> specified here for this appender + the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the + security context to use. The default behavior is to use the security context + of the current thread. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.FileAppender.LockingModel"> + <summary> + Gets or sets the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to handle locking of the file. + </summary> + <value> + The <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to lock the file. + </value> + <remarks> + <para> + Gets or sets the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to handle locking of the file. + </para> + <para> + There are two built in locking models, <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> and <see cref="T:log4net.Appender.FileAppender.MinimalLock"/>. + The former locks the file from the start of logging to the end and the + later lock only for the minimal amount of time when logging each message. + </para> + <para> + The default locking model is the <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.FileAppender.LockingStream"> + <summary> + Write only <see cref="T:System.IO.Stream"/> that uses the <see cref="T:log4net.Appender.FileAppender.LockingModelBase"/> + to manage access to an underlying resource. + </summary> + </member> + <member name="M:log4net.Appender.FileAppender.LockingStream.BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)"> + <summary> + True asynchronous writes are not supported, the implementation forces a synchronous write. + </summary> + </member> + <member name="T:log4net.Core.LogException"> + <summary> + Exception base type for log4net. + </summary> + <remarks> + <para> + This type extends <see cref="T:System.ApplicationException"/>. It + does not add any new functionality but does differentiate the + type of exception being thrown. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.LogException.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogException.#ctor(System.String)"> + <summary> + Constructor + </summary> + <param name="message">A message to include with the exception.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class with + the specified message. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogException.#ctor(System.String,System.Exception)"> + <summary> + Constructor + </summary> + <param name="message">A message to include with the exception.</param> + <param name="innerException">A nested exception to include.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class + with the specified message and inner exception. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Serialization constructor + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param> + <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class + with serialized data. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.FileAppender.LockingModelBase"> + <summary> + Locking model base class + </summary> + <remarks> + <para> + Base class for the locking models available to the <see cref="T:log4net.Appender.FileAppender"/> derived loggers. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.LockingModelBase.OpenFile(System.String,System.Boolean,System.Text.Encoding)"> + <summary> + Open the output file + </summary> + <param name="filename">The filename to use</param> + <param name="append">Whether to append to the file, or overwrite</param> + <param name="encoding">The encoding to use</param> + <remarks> + <para> + Open the file specified and prepare for logging. + No writes will be made until <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/> is called. + Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/>, + <see cref="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.LockingModelBase.CloseFile"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.LockingModelBase.CloseFile"> + <summary> + Close the file + </summary> + <remarks> + <para> + Close the file. No further writes will be made. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"> + <summary> + Acquire the lock on the file + </summary> + <returns>A stream that is ready to be written to.</returns> + <remarks> + <para> + Acquire the lock on the file in preparation for writing to it. + Return a stream pointing to the file. <see cref="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"/> + must be called to release the lock on the output file. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"> + <summary> + Release the lock on the file + </summary> + <remarks> + <para> + Release the lock on the file. No further writes will be made to the + stream until <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/> is called again. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.FileAppender.LockingModelBase.CurrentAppender"> + <summary> + Gets or sets the <see cref="T:log4net.Appender.FileAppender"/> for this LockingModel + </summary> + <value> + The <see cref="T:log4net.Appender.FileAppender"/> for this LockingModel + </value> + <remarks> + <para> + The file appender this locking model is attached to and working on + behalf of. + </para> + <para> + The file appender is used to locate the security context and the error handler to use. + </para> + <para> + The value of this property will be set before <see cref="M:log4net.Appender.FileAppender.LockingModelBase.OpenFile(System.String,System.Boolean,System.Text.Encoding)"/> is + called. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.FileAppender.ExclusiveLock"> + <summary> + Hold an exclusive lock on the output file + </summary> + <remarks> + <para> + Open the file once for writing and hold it open until <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"/> is called. + Maintains an exclusive lock on the file during this time. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.ExclusiveLock.OpenFile(System.String,System.Boolean,System.Text.Encoding)"> + <summary> + Open the file specified and prepare for logging. + </summary> + <param name="filename">The filename to use</param> + <param name="append">Whether to append to the file, or overwrite</param> + <param name="encoding">The encoding to use</param> + <remarks> + <para> + Open the file specified and prepare for logging. + No writes will be made until <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"/> is called. + Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"/>, + <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"> + <summary> + Close the file + </summary> + <remarks> + <para> + Close the file. No further writes will be made. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"> + <summary> + Acquire the lock on the file + </summary> + <returns>A stream that is ready to be written to.</returns> + <remarks> + <para> + Does nothing. The lock is already taken + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.ExclusiveLock.ReleaseLock"> + <summary> + Release the lock on the file + </summary> + <remarks> + <para> + Does nothing. The lock will be released when the file is closed. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.FileAppender.MinimalLock"> + <summary> + Acquires the file lock for each write + </summary> + <remarks> + <para> + Opens the file once for each <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/>/<see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> cycle, + thus holding the lock for the minimal amount of time. This method of locking + is considerably slower than <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> but allows + other processes to move/delete the log file whilst logging continues. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.MinimalLock.OpenFile(System.String,System.Boolean,System.Text.Encoding)"> + <summary> + Prepares to open the file when the first message is logged. + </summary> + <param name="filename">The filename to use</param> + <param name="append">Whether to append to the file, or overwrite</param> + <param name="encoding">The encoding to use</param> + <remarks> + <para> + Open the file specified and prepare for logging. + No writes will be made until <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/> is called. + Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/>, + <see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.MinimalLock.CloseFile"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.MinimalLock.CloseFile"> + <summary> + Close the file + </summary> + <remarks> + <para> + Close the file. No further writes will be made. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"> + <summary> + Acquire the lock on the file + </summary> + <returns>A stream that is ready to be written to.</returns> + <remarks> + <para> + Acquire the lock on the file in preparation for writing to it. + Return a stream pointing to the file. <see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> + must be called to release the lock on the output file. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"> + <summary> + Release the lock on the file + </summary> + <remarks> + <para> + Release the lock on the file. No further writes will be made to the + stream until <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/> is called again. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.ForwardingAppender"> + <summary> + This appender forwards logging events to attached appenders. + </summary> + <remarks> + <para> + The forwarding appender can be used to specify different thresholds + and filters for the same appender at different locations within the hierarchy. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.ForwardingAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.ForwardingAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.OnClose"> + <summary> + Closes the appender and releases resources. + </summary> + <remarks> + <para> + Releases any resources allocated within the appender such as file handles, + network connections, etc. + </para> + <para> + It is a programming error to append to a closed appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Forward the logging event to the attached appenders + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Delivers the logging event to all the attached appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.Append(log4net.Core.LoggingEvent[])"> + <summary> + Forward the logging events to the attached appenders + </summary> + <param name="loggingEvents">The array of events to log.</param> + <remarks> + <para> + Delivers the logging events to all the attached appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.AddAppender(log4net.Appender.IAppender)"> + <summary> + Adds an <see cref="T:log4net.Appender.IAppender"/> to the list of appenders of this + instance. + </summary> + <param name="newAppender">The <see cref="T:log4net.Appender.IAppender"/> to add to this appender.</param> + <remarks> + <para> + If the specified <see cref="T:log4net.Appender.IAppender"/> is already in the list of + appenders, then it won't be added again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.GetAppender(System.String)"> + <summary> + Looks for the appender with the specified name. + </summary> + <param name="name">The name of the appender to lookup.</param> + <returns> + The appender with the specified name, or <c>null</c>. + </returns> + <remarks> + <para> + Get the named appender attached to this appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.RemoveAllAppenders"> + <summary> + Removes all previously added appenders from this appender. + </summary> + <remarks> + <para> + This is useful when re-reading configuration information. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.RemoveAppender(log4net.Appender.IAppender)"> + <summary> + Removes the specified appender from the list of appenders. + </summary> + <param name="appender">The appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </remarks> + </member> + <member name="M:log4net.Appender.ForwardingAppender.RemoveAppender(System.String)"> + <summary> + Removes the appender with the specified name from the list of appenders. + </summary> + <param name="name">The name of the appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </remarks> + </member> + <member name="F:log4net.Appender.ForwardingAppender.m_appenderAttachedImpl"> + <summary> + Implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface + </summary> + </member> + <member name="P:log4net.Appender.ForwardingAppender.Appenders"> + <summary> + Gets the appenders contained in this appender as an + <see cref="T:System.Collections.ICollection"/>. + </summary> + <remarks> + If no appenders can be found, then an <see cref="T:log4net.Util.EmptyCollection"/> + is returned. + </remarks> + <returns> + A collection of the appenders in this appender. + </returns> + </member> + <member name="T:log4net.Appender.LocalSyslogAppender"> + <summary> + Logs events to a local syslog service. + </summary> + <remarks> + <note> + This appender uses the POSIX libc library functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c>. + If these functions are not available on the local system then this appender will not work! + </note> + <para> + The functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c> are specified in SUSv2 and + POSIX 1003.1-2001 standards. These are used to log messages to the local syslog service. + </para> + <para> + This appender talks to a local syslog service. If you need to log to a remote syslog + daemon and you cannot configure your local syslog service to do this you may be + able to use the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> to log via UDP. + </para> + <para> + Syslog messages must have a facility and and a severity. The severity + is derived from the Level of the logging event. + The facility must be chosen from the set of defined syslog + <see cref="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"/> values. The facilities list is predefined + and cannot be extended. + </para> + <para> + An identifier is specified with each log message. This can be specified + by setting the <see cref="P:log4net.Appender.LocalSyslogAppender.Identity"/> property. The identity (also know + as the tag) must not contain white space. The default value for the + identity is the application name (from <see cref="P:log4net.Util.SystemInfo.ApplicationFriendlyName"/>). + </para> + </remarks> + <author>Rob Lyon</author> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.LocalSyslogAppender"/> class. + </summary> + <remarks> + This instance of the <see cref="T:log4net.Appender.LocalSyslogAppender"/> class is set up to write + to a local syslog service. + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.AddMapping(log4net.Appender.LocalSyslogAppender.LevelSeverity)"> + <summary> + Add a mapping of level to severity + </summary> + <param name="mapping">The mapping to add</param> + <remarks> + <para> + Adds a <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"/> to this appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.LocalSyslogAppender.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="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the event to a remote syslog daemon. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.OnClose"> + <summary> + Close the syslog when the appender is closed + </summary> + <remarks> + <para> + Close the syslog when the appender is closed + </para> + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.GetSeverity(log4net.Core.Level)"> + <summary> + Translates a log4net level to a syslog severity. + </summary> + <param name="level">A log4net level.</param> + <returns>A syslog severity.</returns> + <remarks> + <para> + Translates a log4net level to a syslog severity. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.GeneratePriority(log4net.Appender.LocalSyslogAppender.SyslogFacility,log4net.Appender.LocalSyslogAppender.SyslogSeverity)"> + <summary> + Generate a syslog priority. + </summary> + <param name="facility">The syslog facility.</param> + <param name="severity">The syslog severity.</param> + <returns>A syslog priority.</returns> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.m_facility"> + <summary> + The facility. The default facility is <see cref="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"/>. + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.m_identity"> + <summary> + The message identity + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.m_handleToIdentity"> + <summary> + Marshaled handle to the identity string. We have to hold on to the + string as the <c>openlog</c> and <c>syslog</c> APIs just hold the + pointer to the ident and dereference it for each log message. + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.m_levelMapping"> + <summary> + Mapping from level object to syslog severity + </summary> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.openlog(System.IntPtr,System.Int32,log4net.Appender.LocalSyslogAppender.SyslogFacility)"> + <summary> + Open connection to system logger. + </summary> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.syslog(System.Int32,System.String,System.String)"> + <summary> + Generate a log message. + </summary> + <remarks> + <para> + The libc syslog method takes a format string and a variable argument list similar + to the classic printf function. As this type of vararg list is not supported + by C# we need to specify the arguments explicitly. Here we have specified the + format string with a single message argument. The caller must set the format + string to <c>"%s"</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.LocalSyslogAppender.closelog"> + <summary> + Close descriptor used to write to system logger. + </summary> + </member> + <member name="P:log4net.Appender.LocalSyslogAppender.Identity"> + <summary> + Message identity + </summary> + <remarks> + <para> + An identifier is specified with each log message. This can be specified + by setting the <see cref="P:log4net.Appender.LocalSyslogAppender.Identity"/> property. The identity (also know + as the tag) must not contain white space. The default value for the + identity is the application name (from <see cref="P:log4net.Util.SystemInfo.ApplicationFriendlyName"/>). + </para> + </remarks> + </member> + <member name="P:log4net.Appender.LocalSyslogAppender.Facility"> + <summary> + Syslog facility + </summary> + <remarks> + Set to one of the <see cref="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"/> values. The list of + facilities is predefined and cannot be extended. The default value + is <see cref="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"/>. + </remarks> + </member> + <member name="P:log4net.Appender.LocalSyslogAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.LocalSyslogAppender.SyslogSeverity"> + <summary> + syslog severities + </summary> + <remarks> + <para> + The log4net Level maps to a syslog severity using the + <see cref="M:log4net.Appender.LocalSyslogAppender.AddMapping(log4net.Appender.LocalSyslogAppender.LevelSeverity)"/> method and the <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"/> + class. The severity is set on <see cref="P:log4net.Appender.LocalSyslogAppender.LevelSeverity.Severity"/>. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Emergency"> + <summary> + system is unusable + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Alert"> + <summary> + action must be taken immediately + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Critical"> + <summary> + critical conditions + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Error"> + <summary> + error conditions + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Warning"> + <summary> + warning conditions + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Notice"> + <summary> + normal but significant condition + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Informational"> + <summary> + informational + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Debug"> + <summary> + debug-level messages + </summary> + </member> + <member name="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"> + <summary> + syslog facilities + </summary> + <remarks> + <para> + The syslog facility defines which subsystem the logging comes from. + This is set on the <see cref="P:log4net.Appender.LocalSyslogAppender.Facility"/> property. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Kernel"> + <summary> + kernel messages + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"> + <summary> + random user-level messages + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Mail"> + <summary> + mail system + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Daemons"> + <summary> + system daemons + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Authorization"> + <summary> + security/authorization messages + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Syslog"> + <summary> + messages generated internally by syslogd + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Printer"> + <summary> + line printer subsystem + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.News"> + <summary> + network news subsystem + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Uucp"> + <summary> + UUCP subsystem + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Clock"> + <summary> + clock (cron/at) daemon + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Authorization2"> + <summary> + security/authorization messages (private) + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Ftp"> + <summary> + ftp daemon + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Ntp"> + <summary> + NTP subsystem + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Audit"> + <summary> + log audit + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Alert"> + <summary> + log alert + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Clock2"> + <summary> + clock daemon + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local0"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local1"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local2"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local3"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local4"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local5"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local6"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local7"> + <summary> + reserved for local use + </summary> + </member> + <member name="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"> + <summary> + A class to act as a mapping between the level that a logging call is made at and + the syslog severity that is should be logged at. + </summary> + <remarks> + <para> + A class to act as a mapping between the level that a logging call is made at and + the syslog severity that is should be logged at. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.LocalSyslogAppender.LevelSeverity.Severity"> + <summary> + The mapped syslog severity for the specified level + </summary> + <remarks> + <para> + Required property. + The mapped syslog severity for the specified level + </para> + </remarks> + </member> + <member name="T:log4net.Appender.MemoryAppender"> + <summary> + Stores logging events in an array. + </summary> + <remarks> + <para> + The memory appender stores all the logging events + that are appended in an in-memory array. + </para> + <para> + Use the <see cref="M:log4net.Appender.MemoryAppender.GetEvents"/> method to get + the current list of events that have been appended. + </para> + <para> + Use the <see cref="M:log4net.Appender.MemoryAppender.Clear"/> method to clear the + current list of events. + </para> + </remarks> + <author>Julian Biddle</author> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.MemoryAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.MemoryAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.MemoryAppender.GetEvents"> + <summary> + Gets the events that have been logged. + </summary> + <returns>The events that have been logged</returns> + <remarks> + <para> + Gets the events that have been logged. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.MemoryAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">the event to log</param> + <remarks> + <para>Stores the <paramref name="loggingEvent"/> in the events list.</para> + </remarks> + </member> + <member name="M:log4net.Appender.MemoryAppender.Clear"> + <summary> + Clear the list of events + </summary> + <remarks> + Clear the list of events + </remarks> + </member> + <member name="F:log4net.Appender.MemoryAppender.m_eventsList"> + <summary> + The list of events that have been appended. + </summary> + </member> + <member name="F:log4net.Appender.MemoryAppender.m_fixFlags"> + <summary> + Value indicating which fields in the event should be fixed + </summary> + <remarks> + By default all fields are fixed + </remarks> + </member> + <member name="P:log4net.Appender.MemoryAppender.OnlyFixPartialEventData"> + <summary> + Gets or sets a value indicating whether only part of the logging event + data should be fixed. + </summary> + <value> + <c>true</c> if the appender should only fix part of the logging event + data, otherwise <c>false</c>. The default is <c>false</c>. + </value> + <remarks> + <para> + Setting this property to <c>true</c> will cause only part of the event + data to be fixed and stored in the appender, hereby improving performance. + </para> + <para> + See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> for more information. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.MemoryAppender.Fix"> + <summary> + Gets or sets the fields that will be fixed in the event + </summary> + <remarks> + <para> + The logging event needs to have certain thread specific values + captured before it can be buffered. See <see cref="P:log4net.Core.LoggingEvent.Fix"/> + for details. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.NetSendAppender"> + <summary> + Logs entries by sending network messages using the + <see cref="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"/> native function. + </summary> + <remarks> + <para> + You can send messages only to names that are active + on the network. If you send the message to a user name, + that user must be logged on and running the Messenger + service to receive the message. + </para> + <para> + The receiver will get a top most window displaying the + messages one at a time, therefore this appender should + not be used to deliver a high volume of messages. + </para> + <para> + The following table lists some possible uses for this appender : + </para> + <para> + <list type="table"> + <listheader> + <term>Action</term> + <description>Property Value(s)</description> + </listheader> + <item> + <term>Send a message to a user account on the local machine</term> + <description> + <para> + <paramref name="Server"/> = <name of the local machine> + </para> + <para> + <paramref name="Recipient"/> = <user name> + </para> + </description> + </item> + <item> + <term>Send a message to a user account on a remote machine</term> + <description> + <para> + <paramref name="Server"/> = <name of the remote machine> + </para> + <para> + <paramref name="Recipient"/> = <user name> + </para> + </description> + </item> + <item> + <term>Send a message to a domain user account</term> + <description> + <para> + <paramref name="Server"/> = <name of a domain controller | uninitialized> + </para> + <para> + <paramref name="Recipient"/> = <user name> + </para> + </description> + </item> + <item> + <term>Send a message to all the names in a workgroup or domain</term> + <description> + <para> + <paramref name="Recipient"/> = <workgroup name | domain name>* + </para> + </description> + </item> + <item> + <term>Send a message from the local machine to a remote machine</term> + <description> + <para> + <paramref name="Server"/> = <name of the local machine | uninitialized> + </para> + <para> + <paramref name="Recipient"/> = <name of the remote machine> + </para> + </description> + </item> + </list> + </para> + <para> + <b>Note :</b> security restrictions apply for sending + network messages, see <see cref="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"/> + for more information. + </para> + </remarks> + <example> + <para> + An example configuration section to log information + using this appender from the local machine, named + LOCAL_PC, to machine OPERATOR_PC : + </para> + <code lang="XML" escaped="true"> + <appender name="NetSendAppender_Operator" type="log4net.Appender.NetSendAppender"> + <server value="LOCAL_PC"/> + <recipient value="OPERATOR_PC"/> + <layout type="log4net.Layout.PatternLayout" value="%-5p %c [%x] - %m%n"/> + </appender> + </code> + </example> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Appender.NetSendAppender.m_server"> + <summary> + The DNS or NetBIOS name of the server on which the function is to execute. + </summary> + </member> + <member name="F:log4net.Appender.NetSendAppender.m_sender"> + <summary> + The sender of the network message. + </summary> + </member> + <member name="F:log4net.Appender.NetSendAppender.m_recipient"> + <summary> + The message alias to which the message should be sent. + </summary> + </member> + <member name="F:log4net.Appender.NetSendAppender.m_securityContext"> + <summary> + The security context to use for privileged calls + </summary> + </member> + <member name="M:log4net.Appender.NetSendAppender.#ctor"> + <summary> + Initializes the appender. + </summary> + <remarks> + The default constructor initializes all fields to their default values. + </remarks> + </member> + <member name="M:log4net.Appender.NetSendAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.NetSendAppender.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="M:log4net.Appender.NetSendAppender.ActivateOptions"/> must be called again. + </para> + <para> + The appender will be ignored if no <see cref="P:log4net.Appender.NetSendAppender.Recipient"/> was specified. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException">The required property <see cref="P:log4net.Appender.NetSendAppender.Recipient"/> was not specified.</exception> + </member> + <member name="M:log4net.Appender.NetSendAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Sends the event using a network message. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"> + <summary> + Sends a buffer of information to a registered message alias. + </summary> + <param name="serverName">The DNS or NetBIOS name of the server on which the function is to execute.</param> + <param name="msgName">The message alias to which the message buffer should be sent</param> + <param name="fromName">The originator of the message.</param> + <param name="buffer">The message text.</param> + <param name="bufferSize">The length, in bytes, of the message text.</param> + <remarks> + <para> + The following restrictions apply for sending network messages: + </para> + <para> + <list type="table"> + <listheader> + <term>Platform</term> + <description>Requirements</description> + </listheader> + <item> + <term>Windows NT</term> + <description> + <para> + No special group membership is required to send a network message. + </para> + <para> + Admin, Accounts, Print, or Server Operator group membership is required to + successfully send a network message on a remote server. + </para> + </description> + </item> + <item> + <term>Windows 2000 or later</term> + <description> + <para> + If you send a message on a domain controller that is running Active Directory, + access is allowed or denied based on the access control list (ACL) for the securable + object. The default ACL permits only Domain Admins and Account Operators to send a network message. + </para> + <para> + On a member server or workstation, only Administrators and Server Operators can send a network message. + </para> + </description> + </item> + </list> + </para> + <para> + For more information see <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/security_requirements_for_the_network_management_functions.asp">Security Requirements for the Network Management Functions</a>. + </para> + </remarks> + <returns> + <para> + If the function succeeds, the return value is zero. + </para> + </returns> + </member> + <member name="P:log4net.Appender.NetSendAppender.Sender"> + <summary> + Gets or sets the sender of the message. + </summary> + <value> + The sender of the message. + </value> + <remarks> + If this property is not specified, the message is sent from the local computer. + </remarks> + </member> + <member name="P:log4net.Appender.NetSendAppender.Recipient"> + <summary> + Gets or sets the message alias to which the message should be sent. + </summary> + <value> + The recipient of the message. + </value> + <remarks> + This property should always be specified in order to send a message. + </remarks> + </member> + <member name="P:log4net.Appender.NetSendAppender.Server"> + <summary> + Gets or sets the DNS or NetBIOS name of the remote server on which the function is to execute. + </summary> + <value> + DNS or NetBIOS name of the remote server on which the function is to execute. + </value> + <remarks> + <para> + For Windows NT 4.0 and earlier, the string should begin with \\. + </para> + <para> + If this property is not specified, the local computer is used. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.NetSendAppender.SecurityContext"> + <summary> + Gets or sets the <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> used to call the NetSend method. + </summary> + <value> + The <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> used to call the NetSend method. + </value> + <remarks> + <para> + Unless a <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> specified here for this appender + the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the + security context to use. The default behavior is to use the security context + of the current thread. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.NetSendAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.OutputDebugStringAppender"> + <summary> + Appends log events to the OutputDebugString system. + </summary> + <remarks> + <para> + OutputDebugStringAppender appends log events to the + OutputDebugString system. + </para> + <para> + The string is passed to the native <c>OutputDebugString</c> + function. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.OutputDebugStringAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.OutputDebugStringAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.OutputDebugStringAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Write the logging event to the output debug string API + </summary> + <param name="loggingEvent">the event to log</param> + <remarks> + <para> + Write the logging event to the output debug string API + </para> + </remarks> + </member> + <member name="M:log4net.Appender.OutputDebugStringAppender.OutputDebugString(System.String)"> + <summary> + Stub for OutputDebugString native method + </summary> + <param name="message">the string to output</param> + <remarks> + <para> + Stub for OutputDebugString native method + </para> + </remarks> + </member> + <member name="P:log4net.Appender.OutputDebugStringAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.RemoteSyslogAppender"> + <summary> + Logs events to a remote syslog daemon. + </summary> + <remarks> + <para> + The BSD syslog protocol is used to remotely log to + a syslog daemon. The syslogd listens for for messages + on UDP port 514. + </para> + <para> + The syslog UDP protocol is not authenticated. Most syslog daemons + do not accept remote log messages because of the security implications. + You may be able to use the LocalSyslogAppender to talk to a local + syslog service. + </para> + <para> + There is an RFC 3164 that claims to document the BSD Syslog Protocol. + This RFC can be seen here: http://www.faqs.org/rfcs/rfc3164.html. + This appender generates what the RFC calls an "Original Device Message", + i.e. does not include the TIMESTAMP or HOSTNAME fields. By observation + this format of message will be accepted by all current syslog daemon + implementations. The daemon will attach the current time and the source + hostname or IP address to any messages received. + </para> + <para> + Syslog messages must have a facility and and a severity. The severity + is derived from the Level of the logging event. + The facility must be chosen from the set of defined syslog + <see cref="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"/> values. The facilities list is predefined + and cannot be extended. + </para> + <para> + An identifier is specified with each log message. This can be specified + by setting the <see cref="P:log4net.Appender.RemoteSyslogAppender.Identity"/> property. The identity (also know + as the tag) must not contain white space. The default value for the + identity is the application name (from <see cref="P:log4net.Core.LoggingEvent.Domain"/>). + </para> + </remarks> + <author>Rob Lyon</author> + <author>Nicko Cadell</author> + </member> + <member name="T:log4net.Appender.UdpAppender"> + <summary> + Sends logging events as connectionless UDP datagrams to a remote host or a + multicast group using an <see cref="T:System.Net.Sockets.UdpClient"/>. + </summary> + <remarks> + <para> + UDP guarantees neither that messages arrive, nor that they arrive in the correct order. + </para> + <para> + To view the logging results, a custom application can be developed that listens for logging + events. + </para> + <para> + When decoding events send via this appender remember to use the same encoding + to decode the events as was used to send the events. See the <see cref="P:log4net.Appender.UdpAppender.Encoding"/> + property to specify the encoding to use. + </para> + </remarks> + <example> + This example shows how to log receive logging events that are sent + on IP address 244.0.0.1 and port 8080 to the console. The event is + encoded in the packet as a unicode string and it is decoded as such. + <code lang="C#"> + IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + UdpClient udpClient; + byte[] buffer; + string loggingEvent; + + try + { + udpClient = new UdpClient(8080); + + while(true) + { + buffer = udpClient.Receive(ref remoteEndPoint); + loggingEvent = System.Text.Encoding.Unicode.GetString(buffer); + Console.WriteLine(loggingEvent); + } + } + catch(Exception e) + { + Console.WriteLine(e.ToString()); + } + </code> + <code lang="Visual Basic"> + Dim remoteEndPoint as IPEndPoint + Dim udpClient as UdpClient + Dim buffer as Byte() + Dim loggingEvent as String + + Try + remoteEndPoint = new IPEndPoint(IPAddress.Any, 0) + udpClient = new UdpClient(8080) + + While True + buffer = udpClient.Receive(ByRef remoteEndPoint) + loggingEvent = System.Text.Encoding.Unicode.GetString(buffer) + Console.WriteLine(loggingEvent) + Wend + Catch e As Exception + Console.WriteLine(e.ToString()) + End Try + </code> + <para> + An example configuration section to log information using this appender to the + IP 224.0.0.1 on port 8080: + </para> + <code lang="XML" escaped="true"> + <appender name="UdpAppender" type="log4net.Appender.UdpAppender"> + <remoteAddress value="224.0.0.1"/> + <remotePort value="8080"/> + <layout type="log4net.Layout.PatternLayout" value="%-5level %logger [%ndc] - %message%newline"/> + </appender> + </code> + </example> + <author>Gert Driesen</author> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.UdpAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.UdpAppender"/> class. + </summary> + <remarks> + The default constructor initializes all fields to their default values. + </remarks> + </member> + <member name="M:log4net.Appender.UdpAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.UdpAppender.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="M:log4net.Appender.UdpAppender.ActivateOptions"/> must be called again. + </para> + <para> + The appender will be ignored if no <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> was specified or + an invalid remote or local TCP port number was specified. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException">The required property <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> was not specified.</exception> + <exception cref="T:System.ArgumentOutOfRangeException">The TCP port number assigned to <see cref="P:log4net.Appender.UdpAppender.LocalPort"/> or <see cref="P:log4net.Appender.UdpAppender.RemotePort"/> is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception> + </member> + <member name="M:log4net.Appender.UdpAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Sends the event using an UDP datagram. + </para> + <para> + Exceptions are passed to the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.UdpAppender.OnClose"> + <summary> + Closes the UDP connection and releases all resources associated with + this <see cref="T:log4net.Appender.UdpAppender"/> instance. + </summary> + <remarks> + <para> + Disables the underlying <see cref="T:System.Net.Sockets.UdpClient"/> and releases all managed + and unmanaged resources associated with the <see cref="T:log4net.Appender.UdpAppender"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.UdpAppender.InitializeClientConnection"> + <summary> + Initializes the underlying <see cref="T:System.Net.Sockets.UdpClient"/> connection. + </summary> + <remarks> + <para> + The underlying <see cref="T:System.Net.Sockets.UdpClient"/> is initialized and binds to the + port number from which you intend to communicate. + </para> + <para> + Exceptions are passed to the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/>. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.UdpAppender.m_remoteAddress"> + <summary> + The IP address of the remote host or multicast group to which + the logging event will be sent. + </summary> + </member> + <member name="F:log4net.Appender.UdpAppender.m_remotePort"> + <summary> + The TCP port number of the remote host or multicast group to + which the logging event will be sent. + </summary> + </member> + <member name="F:log4net.Appender.UdpAppender.m_remoteEndPoint"> + <summary> + The cached remote endpoint to which the logging events will be sent. + </summary> + </member> + <member name="F:log4net.Appender.UdpAppender.m_localPort"> + <summary> + The TCP port number from which the <see cref="T:System.Net.Sockets.UdpClient"/> will communicate. + </summary> + </member> + <member name="F:log4net.Appender.UdpAppender.m_client"> + <summary> + The <see cref="T:System.Net.Sockets.UdpClient"/> instance that will be used for sending the + logging events. + </summary> + </member> + <member name="F:log4net.Appender.UdpAppender.m_encoding"> + <summary> + The encoding to use for the packet. + </summary> + </member> + <member name="P:log4net.Appender.UdpAppender.RemoteAddress"> + <summary> + Gets or sets the IP address of the remote host or multicast group to which + the underlying <see cref="T:System.Net.Sockets.UdpClient"/> should sent the logging event. + </summary> + <value> + The IP address of the remote host or multicast group to which the logging event + will be sent. + </value> + <remarks> + <para> + Multicast addresses are identified by IP class <b>D</b> addresses (in the range 224.0.0.0 to + 239.255.255.255). Multicast packets can pass across different networks through routers, so + it is possible to use multicasts in an Internet scenario as long as your network provider + supports multicasting. + </para> + <para> + Hosts that want to receive particular multicast messages must register their interest by joining + the multicast group. Multicast messages are not sent to networks where no host has joined + the multicast group. Class <b>D</b> IP addresses are used for multicast groups, to differentiate + them from normal host addresses, allowing nodes to easily detect if a message is of interest. + </para> + <para> + Static multicast addresses that are needed globally are assigned by IANA. A few examples are listed in the table below: + </para> + <para> + <list type="table"> + <listheader> + <term>IP Address</term> + <description>Description</description> + </listheader> + <item> + <term>224.0.0.1</term> + <description> + <para> + Sends a message to all system on the subnet. + </para> + </description> + </item> + <item> + <term>224.0.0.2</term> + <description> + <para> + Sends a message to all routers on the subnet. + </para> + </description> + </item> + <item> + <term>224.0.0.12</term> + <description> + <para> + The DHCP server answers messages on the IP address 224.0.0.12, but only on a subnet. + </para> + </description> + </item> + </list> + </para> + <para> + A complete list of actually reserved multicast addresses and their owners in the ranges + defined by RFC 3171 can be found at the <A href="http://www.iana.org/assignments/multicast-addresses">IANA web site</A>. + </para> + <para> + The address range 239.0.0.0 to 239.255.255.255 is reserved for administrative scope-relative + addresses. These addresses can be reused with other local groups. Routers are typically + configured with filters to prevent multicast traffic in this range from flowing outside + of the local network. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.UdpAppender.RemotePort"> + <summary> + Gets or sets the TCP port number of the remote host or multicast group to which + the underlying <see cref="T:System.Net.Sockets.UdpClient"/> should sent the logging event. + </summary> + <value> + An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/> + indicating the TCP port number of the remote host or multicast group to which the logging event + will be sent. + </value> + <remarks> + The underlying <see cref="T:System.Net.Sockets.UdpClient"/> will send messages to this TCP port number + on the remote host or multicast group. + </remarks> + <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception> + </member> + <member name="P:log4net.Appender.UdpAppender.LocalPort"> + <summary> + Gets or sets the TCP port number from which the underlying <see cref="T:System.Net.Sockets.UdpClient"/> will communicate. + </summary> + <value> + An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/> + indicating the TCP port number from which the underlying <see cref="T:System.Net.Sockets.UdpClient"/> will communicate. + </value> + <remarks> + <para> + The underlying <see cref="T:System.Net.Sockets.UdpClient"/> will bind to this port for sending messages. + </para> + <para> + Setting the value to 0 (the default) will cause the udp client not to bind to + a local port. + </para> + </remarks> + <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception> + </member> + <member name="P:log4net.Appender.UdpAppender.Encoding"> + <summary> + Gets or sets <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets. + </summary> + <value> + The <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets. + </value> + <remarks> + <para> + The <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.UdpAppender.Client"> + <summary> + Gets or sets the underlying <see cref="T:System.Net.Sockets.UdpClient"/>. + </summary> + <value> + The underlying <see cref="T:System.Net.Sockets.UdpClient"/>. + </value> + <remarks> + <see cref="T:log4net.Appender.UdpAppender"/> creates a <see cref="T:System.Net.Sockets.UdpClient"/> to send logging events + over a network. Classes deriving from <see cref="T:log4net.Appender.UdpAppender"/> can use this + property to get or set this <see cref="T:System.Net.Sockets.UdpClient"/>. Use the underlying <see cref="T:System.Net.Sockets.UdpClient"/> + returned from <see cref="P:log4net.Appender.UdpAppender.Client"/> if you require access beyond that which + <see cref="T:log4net.Appender.UdpAppender"/> provides. + </remarks> + </member> + <member name="P:log4net.Appender.UdpAppender.RemoteEndPoint"> + <summary> + Gets or sets the cached remote endpoint to which the logging events should be sent. + </summary> + <value> + The cached remote endpoint to which the logging events will be sent. + </value> + <remarks> + The <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> method will initialize the remote endpoint + with the values of the <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> and <see cref="P:log4net.Appender.UdpAppender.RemotePort"/> + properties. + </remarks> + </member> + <member name="P:log4net.Appender.UdpAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.DefaultSyslogPort"> + <summary> + Syslog port 514 + </summary> + </member> + <member name="M:log4net.Appender.RemoteSyslogAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> class. + </summary> + <remarks> + This instance of the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> class is set up to write + to a remote syslog daemon. + </remarks> + </member> + <member name="M:log4net.Appender.RemoteSyslogAppender.AddMapping(log4net.Appender.RemoteSyslogAppender.LevelSeverity)"> + <summary> + Add a mapping of level to severity + </summary> + <param name="mapping">The mapping to add</param> + <remarks> + <para> + Add a <see cref="T:log4net.Appender.RemoteSyslogAppender.LevelSeverity"/> mapping to this appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RemoteSyslogAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the event to a remote syslog daemon. + </para> + <para> + The format of the output will depend on the appender's layout. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RemoteSyslogAppender.ActivateOptions"> + <summary> + Initialize the options for this appender + </summary> + <remarks> + <para> + Initialize the level to syslog severity mappings set on this appender. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RemoteSyslogAppender.GetSeverity(log4net.Core.Level)"> + <summary> + Translates a log4net level to a syslog severity. + </summary> + <param name="level">A log4net level.</param> + <returns>A syslog severity.</returns> + <remarks> + <para> + Translates a log4net level to a syslog severity. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RemoteSyslogAppender.GeneratePriority(log4net.Appender.RemoteSyslogAppender.SyslogFacility,log4net.Appender.RemoteSyslogAppender.SyslogSeverity)"> + <summary> + Generate a syslog priority. + </summary> + <param name="facility">The syslog facility.</param> + <param name="severity">The syslog severity.</param> + <returns>A syslog priority.</returns> + <remarks> + <para> + Generate a syslog priority. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.m_facility"> + <summary> + The facility. The default facility is <see cref="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"/>. + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.m_identity"> + <summary> + The message identity + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.m_levelMapping"> + <summary> + Mapping from level object to syslog severity + </summary> + </member> + <member name="P:log4net.Appender.RemoteSyslogAppender.Identity"> + <summary> + Message identity + </summary> + <remarks> + <para> + An identifier is specified with each log message. This can be specified + by setting the <see cref="P:log4net.Appender.RemoteSyslogAppender.Identity"/> property. The identity (also know + as the tag) must not contain white space. The default value for the + identity is the application name (from <see cref="P:log4net.Core.LoggingEvent.Domain"/>). + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RemoteSyslogAppender.Facility"> + <summary> + Syslog facility + </summary> + <remarks> + Set to one of the <see cref="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"/> values. The list of + facilities is predefined and cannot be extended. The default value + is <see cref="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"/>. + </remarks> + </member> + <member name="T:log4net.Appender.RemoteSyslogAppender.SyslogSeverity"> + <summary> + syslog severities + </summary> + <remarks> + <para> + The syslog severities. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Emergency"> + <summary> + system is unusable + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Alert"> + <summary> + action must be taken immediately + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Critical"> + <summary> + critical conditions + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Error"> + <summary> + error conditions + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Warning"> + <summary> + warning conditions + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Notice"> + <summary> + normal but significant condition + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Informational"> + <summary> + informational + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Debug"> + <summary> + debug-level messages + </summary> + </member> + <member name="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"> + <summary> + syslog facilities + </summary> + <remarks> + <para> + The syslog facilities + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Kernel"> + <summary> + kernel messages + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"> + <summary> + random user-level messages + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Mail"> + <summary> + mail system + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Daemons"> + <summary> + system daemons + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Authorization"> + <summary> + security/authorization messages + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Syslog"> + <summary> + messages generated internally by syslogd + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Printer"> + <summary> + line printer subsystem + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.News"> + <summary> + network news subsystem + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Uucp"> + <summary> + UUCP subsystem + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Clock"> + <summary> + clock (cron/at) daemon + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Authorization2"> + <summary> + security/authorization messages (private) + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Ftp"> + <summary> + ftp daemon + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Ntp"> + <summary> + NTP subsystem + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Audit"> + <summary> + log audit + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Alert"> + <summary> + log alert + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Clock2"> + <summary> + clock daemon + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local0"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local1"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local2"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local3"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local4"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local5"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local6"> + <summary> + reserved for local use + </summary> + </member> + <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local7"> + <summary> + reserved for local use + </summary> + </member> + <member name="T:log4net.Appender.RemoteSyslogAppender.LevelSeverity"> + <summary> + A class to act as a mapping between the level that a logging call is made at and + the syslog severity that is should be logged at. + </summary> + <remarks> + <para> + A class to act as a mapping between the level that a logging call is made at and + the syslog severity that is should be logged at. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RemoteSyslogAppender.LevelSeverity.Severity"> + <summary> + The mapped syslog severity for the specified level + </summary> + <remarks> + <para> + Required property. + The mapped syslog severity for the specified level + </para> + </remarks> + </member> + <member name="T:log4net.Appender.RemotingAppender"> + <summary> + Delivers logging events to a remote logging sink. + </summary> + <remarks> + <para> + This Appender is designed to deliver events to a remote sink. + That is any object that implements the <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/> + interface. It delivers the events using .NET remoting. The + object to deliver events to is specified by setting the + appenders <see cref="P:log4net.Appender.RemotingAppender.Sink"/> property.</para> + <para> + The RemotingAppender buffers events before sending them. This allows it to + make more efficient use of the remoting infrastructure.</para> + <para> + Once the buffer is full the events are still not sent immediately. + They are scheduled to be sent using a pool thread. The effect is that + the send occurs asynchronously. This is very important for a + number of non obvious reasons. The remoting infrastructure will + flow thread local variables (stored in the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>), + if they are marked as <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>, across the + remoting boundary. If the server is not contactable then + the remoting infrastructure will clear the <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/> + objects from the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>. To prevent a logging failure from + having side effects on the calling application the remoting call must be made + from a separate thread to the one used by the application. A <see cref="T:System.Threading.ThreadPool"/> + thread is used for this. If no <see cref="T:System.Threading.ThreadPool"/> thread is available then + the events will block in the thread pool manager until a thread is available.</para> + <para> + Because the events are sent asynchronously using pool threads it is possible to close + this appender before all the queued events have been sent. + When closing the appender attempts to wait until all the queued events have been sent, but + this will timeout after 30 seconds regardless.</para> + <para> + If this appender is being closed because the <see cref="E:System.AppDomain.ProcessExit"/> + event has fired it may not be possible to send all the queued events. During process + exit the runtime limits the time that a <see cref="E:System.AppDomain.ProcessExit"/> + event handler is allowed to run for. If the runtime terminates the threads before + the queued events have been sent then they will be lost. To ensure that all events + are sent the appender must be closed before the application exits. See + <see cref="M:log4net.Core.LoggerManager.Shutdown"/> for details on how to shutdown + log4net programmatically.</para> + </remarks> + <seealso cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Daniel Cazzulino</author> + </member> + <member name="M:log4net.Appender.RemotingAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.RemotingAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RemotingAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.RemotingAppender.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="M:log4net.Appender.RemotingAppender.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RemotingAppender.SendBuffer(log4net.Core.LoggingEvent[])"> + <summary> + Send the contents of the buffer to the remote sink. + </summary> + <remarks> + The events are not sent immediately. They are scheduled to be sent + using a pool thread. The effect is that the send occurs asynchronously. + This is very important for a number of non obvious reasons. The remoting + infrastructure will flow thread local variables (stored in the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>), + if they are marked as <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>, across the + remoting boundary. If the server is not contactable then + the remoting infrastructure will clear the <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/> + objects from the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>. To prevent a logging failure from + having side effects on the calling application the remoting call must be made + from a separate thread to the one used by the application. A <see cref="T:System.Threading.ThreadPool"/> + thread is used for this. If no <see cref="T:System.Threading.ThreadPool"/> thread is available then + the events will block in the thread pool manager until a thread is available. + </remarks> + <param name="events">The events to send.</param> + </member> + <member name="M:log4net.Appender.RemotingAppender.OnClose"> + <summary> + Override base class close. + </summary> + <remarks> + <para> + This method waits while there are queued work items. The events are + sent asynchronously using <see cref="T:System.Threading.ThreadPool"/> work items. These items + will be sent once a thread pool thread is available to send them, therefore + it is possible to close the appender before all the queued events have been + sent.</para> + <para> + This method attempts to wait until all the queued events have been sent, but this + method will timeout after 30 seconds regardless.</para> + <para> + If the appender is being closed because the <see cref="E:System.AppDomain.ProcessExit"/> + event has fired it may not be possible to send all the queued events. During process + exit the runtime limits the time that a <see cref="E:System.AppDomain.ProcessExit"/> + event handler is allowed to run for.</para> + </remarks> + </member> + <member name="M:log4net.Appender.RemotingAppender.BeginAsyncSend"> + <summary> + A work item is being queued into the thread pool + </summary> + </member> + <member name="M:log4net.Appender.RemotingAppender.EndAsyncSend"> + <summary> + A work item from the thread pool has completed + </summary> + </member> + <member name="M:log4net.Appender.RemotingAppender.SendBufferCallback(System.Object)"> + <summary> + Send the contents of the buffer to the remote sink. + </summary> + <remarks> + This method is designed to be used with the <see cref="T:System.Threading.ThreadPool"/>. + This method expects to be passed an array of <see cref="T:log4net.Core.LoggingEvent"/> + objects in the state param. + </remarks> + <param name="state">the logging events to send</param> + </member> + <member name="F:log4net.Appender.RemotingAppender.m_sinkUrl"> + <summary> + The URL of the remote sink. + </summary> + </member> + <member name="F:log4net.Appender.RemotingAppender.m_sinkObj"> + <summary> + The local proxy (.NET remoting) for the remote logging sink. + </summary> + </member> + <member name="F:log4net.Appender.RemotingAppender.m_queuedCallbackCount"> + <summary> + The number of queued callbacks currently waiting or executing + </summary> + </member> + <member name="F:log4net.Appender.RemotingAppender.m_workQueueEmptyEvent"> + <summary> + Event used to signal when there are no queued work items + </summary> + <remarks> + This event is set when there are no queued work items. In this + state it is safe to close the appender. + </remarks> + </member> + <member name="P:log4net.Appender.RemotingAppender.Sink"> + <summary> + Gets or sets the URL of the well-known object that will accept + the logging events. + </summary> + <value> + The well-known URL of the remote sink. + </value> + <remarks> + <para> + The URL of the remoting sink that will accept logging events. + The sink must implement the <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/> + interface. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"> + <summary> + Interface used to deliver <see cref="T:log4net.Core.LoggingEvent"/> objects to a remote sink. + </summary> + <remarks> + This interface must be implemented by a remoting sink + if the <see cref="T:log4net.Appender.RemotingAppender"/> is to be used + to deliver logging events to the sink. + </remarks> + </member> + <member name="M:log4net.Appender.RemotingAppender.IRemoteLoggingSink.LogEvents(log4net.Core.LoggingEvent[])"> + <summary> + Delivers logging events to the remote sink + </summary> + <param name="events">Array of events to log.</param> + <remarks> + <para> + Delivers logging events to the remote sink + </para> + </remarks> + </member> + <member name="T:log4net.Appender.RollingFileAppender"> + <summary> + Appender that rolls log files based on size or date or both. + </summary> + <remarks> + <para> + RollingFileAppender can roll log files based on size or date or both + depending on the setting of the <see cref="P:log4net.Appender.RollingFileAppender.RollingStyle"/> property. + When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Size"/> the log file will be rolled + once its size exceeds the <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/>. + When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Date"/> the log file will be rolled + once the date boundary specified in the <see cref="P:log4net.Appender.RollingFileAppender.DatePattern"/> property + is crossed. + When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"/> the log file will be + rolled once the date boundary specified in the <see cref="P:log4net.Appender.RollingFileAppender.DatePattern"/> property + is crossed, but within a date boundary the file will also be rolled + once its size exceeds the <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/>. + When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Once"/> the log file will be rolled when + the appender is configured. This effectively means that the log file can be + rolled once per program execution. + </para> + <para> + A of few additional optional features have been added: + <list type="bullet"> + <item>Attach date pattern for current log file <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/></item> + <item>Backup number increments for newer files <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/></item> + <item>Infinite number of backups by file size <see cref="P:log4net.Appender.RollingFileAppender.MaxSizeRollBackups"/></item> + </list> + </para> + + <note> + <para> + For large or infinite numbers of backup files a <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> + greater than zero is highly recommended, otherwise all the backup files need + to be renamed each time a new backup is created. + </para> + <para> + When Date/Time based rolling is used setting <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> + to <see langword="true"/> will reduce the number of file renamings to few or none. + </para> + </note> + + <note type="caution"> + <para> + Changing <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> or <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> without clearing + the log file directory of backup files will cause unexpected and unwanted side effects. + </para> + </note> + + <para> + If Date/Time based rolling is enabled this appender will attempt to roll existing files + in the directory without a Date/Time tag based on the last write date of the base log file. + The appender only rolls the log file when a message is logged. If Date/Time based rolling + is enabled then the appender will not roll the log file at the Date/Time boundary but + at the point when the next message is logged after the boundary has been crossed. + </para> + + <para> + The <see cref="T:log4net.Appender.RollingFileAppender"/> extends the <see cref="T:log4net.Appender.FileAppender"/> and + has the same behavior when opening the log file. + The appender will first try to open the file for writing when <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> + is called. This will typically be during configuration. + If the file cannot be opened for writing the appender will attempt + to open the file again each time a message is logged to the appender. + If the file cannot be opened for writing when a message is logged then + the message will be discarded by this appender. + </para> + <para> + When rolling a backup file necessitates deleting an older backup file the + file to be deleted is moved to a temporary name before being deleted. + </para> + + <note type="caution"> + <para> + A maximum number of backup files when rolling on date/time boundaries is not supported. + </para> + </note> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Aspi Havewala</author> + <author>Douglas de la Torre</author> + <author>Edward Smit</author> + </member> + <member name="M:log4net.Appender.RollingFileAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.RollingFileAppender"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.SetQWForFiles(System.IO.TextWriter)"> + <summary> + Sets the quiet writer being used. + </summary> + <remarks> + This method can be overridden by sub classes. + </remarks> + <param name="writer">the writer to set</param> + </member> + <member name="M:log4net.Appender.RollingFileAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Write out a logging event. + </summary> + <param name="loggingEvent">the event to write to file.</param> + <remarks> + <para> + Handles append time behavior for RollingFileAppender. This checks + if a roll over either by date (checked first) or time (checked second) + is need and then appends to the file last. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.Append(log4net.Core.LoggingEvent[])"> + <summary> + Write out an array of logging events. + </summary> + <param name="loggingEvents">the events to write to file.</param> + <remarks> + <para> + Handles append time behavior for RollingFileAppender. This checks + if a roll over either by date (checked first) or time (checked second) + is need and then appends to the file last. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.AdjustFileBeforeAppend"> + <summary> + Performs any required rolling before outputting the next event + </summary> + <remarks> + <para> + Handles append time behavior for RollingFileAppender. This checks + if a roll over either by date (checked first) or time (checked second) + is need and then appends to the file last. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.OpenFile(System.String,System.Boolean)"> + <summary> + Creates and opens the file for logging. If <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> + is false then the fully qualified name is determined and used. + </summary> + <param name="fileName">the name of the file to open</param> + <param name="append">true to append to existing file</param> + <remarks> + <para>This method will ensure that the directory structure + for the <paramref name="fileName"/> specified exists.</para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.GetNextOutputFileName(System.String)"> + <summary> + Get the current output file name + </summary> + <param name="fileName">the base file name</param> + <returns>the output file name</returns> + <remarks> + The output file name is based on the base fileName specified. + If <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> is set then the output + file name is the same as the base file passed in. Otherwise + the output file depends on the date pattern, on the count + direction or both. + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.DetermineCurSizeRollBackups"> + <summary> + Determines curSizeRollBackups (only within the current roll point) + </summary> + </member> + <member name="M:log4net.Appender.RollingFileAppender.GetWildcardPatternForFile(System.String)"> + <summary> + Generates a wildcard pattern that can be used to find all files + that are similar to the base file name. + </summary> + <param name="baseFileName"></param> + <returns></returns> + </member> + <member name="M:log4net.Appender.RollingFileAppender.GetExistingFiles(System.String)"> + <summary> + Builds a list of filenames for all files matching the base filename plus a file + pattern. + </summary> + <param name="baseFilePath"></param> + <returns></returns> + </member> + <member name="M:log4net.Appender.RollingFileAppender.RollOverIfDateBoundaryCrossing"> + <summary> + Initiates a roll over if needed for crossing a date boundary since the last run. + </summary> + </member> + <member name="M:log4net.Appender.RollingFileAppender.ExistingInit"> + <summary> + Initializes based on existing conditions at time of <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>. + </summary> + <remarks> + <para> + Initializes based on existing conditions at time of <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>. + The following is done + <list type="bullet"> + <item>determine curSizeRollBackups (only within the current roll point)</item> + <item>initiates a roll over if needed for crossing a date boundary since the last run.</item> + </list> + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.InitializeFromOneFile(System.String,System.String)"> + <summary> + Does the work of bumping the 'current' file counter higher + to the highest count when an incremental file name is seen. + The highest count is either the first file (when count direction + is greater than 0) or the last file (when count direction less than 0). + In either case, we want to know the highest count that is present. + </summary> + <param name="baseFile"></param> + <param name="curFileName"></param> + </member> + <member name="M:log4net.Appender.RollingFileAppender.InitializeRollBackups(System.String,System.Collections.ArrayList)"> + <summary> + Takes a list of files and a base file name, and looks for + 'incremented' versions of the base file. Bumps the max + count up to the highest count seen. + </summary> + <param name="baseFile"></param> + <param name="arrayFiles"></param> + </member> + <member name="M:log4net.Appender.RollingFileAppender.ComputeCheckPeriod(System.String)"> + <summary> + Calculates the RollPoint for the datePattern supplied. + </summary> + <param name="datePattern">the date pattern to calculate the check period for</param> + <returns>The RollPoint that is most accurate for the date pattern supplied</returns> + <remarks> + Essentially the date pattern is examined to determine what the + most suitable roll point is. The roll point chosen is the roll point + with the smallest period that can be detected using the date pattern + supplied. i.e. if the date pattern only outputs the year, month, day + and hour then the smallest roll point that can be detected would be + and hourly roll point as minutes could not be detected. + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.RollingFileAppender.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="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> must be called again. + </para> + <para> + Sets initial conditions including date/time roll over information, first check, + scheduledFilename, and calls <see cref="M:log4net.Appender.RollingFileAppender.ExistingInit"/> to initialize + the current number of backups. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.RollOverTime(System.Boolean)"> + <summary> + Rollover the file(s) to date/time tagged file(s). + </summary> + <param name="fileIsOpen">set to true if the file to be rolled is currently open</param> + <remarks> + <para> + Rollover the file(s) to date/time tagged file(s). + Resets curSizeRollBackups. + If fileIsOpen is set then the new file is opened (through SafeOpenFile). + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.RollFile(System.String,System.String)"> + <summary> + Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>. + </summary> + <param name="fromFile">Name of existing file to roll.</param> + <param name="toFile">New name for file.</param> + <remarks> + <para> + Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>. It + also checks for existence of target file and deletes if it does. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.FileExists(System.String)"> + <summary> + Test if a file exists at a specified path + </summary> + <param name="path">the path to the file</param> + <returns>true if the file exists</returns> + <remarks> + <para> + Test if a file exists at a specified path + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.DeleteFile(System.String)"> + <summary> + Deletes the specified file if it exists. + </summary> + <param name="fileName">The file to delete.</param> + <remarks> + <para> + Delete a file if is exists. + The file is first moved to a new filename then deleted. + This allows the file to be removed even when it cannot + be deleted, but it still can be moved. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.RollOverSize"> + <summary> + Implements file roll base on file size. + </summary> + <remarks> + <para> + If the maximum number of size based backups is reached + (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the oldest + file is deleted -- its index determined by the sign of countDirection. + If <c>countDirection</c> < 0, then files + {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>} + are renamed to {<c>File.2</c>, ..., + <c>File.curSizeRollBackups</c>}. Moreover, <c>File</c> is + renamed <c>File.1</c> and closed. + </para> + <para> + A new file is created to receive further log output. + </para> + <para> + If <c>maxSizeRollBackups</c> is equal to zero, then the + <c>File</c> is truncated with no backup files created. + </para> + <para> + If <c>maxSizeRollBackups</c> < 0, then <c>File</c> is + renamed if needed and no files are deleted. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.RollOverRenameFiles(System.String)"> + <summary> + Implements file roll. + </summary> + <param name="baseFileName">the base name to rename</param> + <remarks> + <para> + If the maximum number of size based backups is reached + (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the oldest + file is deleted -- its index determined by the sign of countDirection. + If <c>countDirection</c> < 0, then files + {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>} + are renamed to {<c>File.2</c>, ..., + <c>File.curSizeRollBackups</c>}. + </para> + <para> + If <c>maxSizeRollBackups</c> is equal to zero, then the + <c>File</c> is truncated with no backup files created. + </para> + <para> + If <c>maxSizeRollBackups</c> < 0, then <c>File</c> is + renamed if needed and no files are deleted. + </para> + <para> + This is called by <see cref="M:log4net.Appender.RollingFileAppender.RollOverSize"/> to rename the files. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.RollingFileAppender.NextCheckDate(System.DateTime,log4net.Appender.RollingFileAppender.RollPoint)"> + <summary> + Get the start time of the next window for the current rollpoint + </summary> + <param name="currentDateTime">the current date</param> + <param name="rollPoint">the type of roll point we are working with</param> + <returns>the start time for the next roll point an interval after the currentDateTime date</returns> + <remarks> + <para> + Returns the date of the next roll point after the currentDateTime date passed to the method. + </para> + <para> + The basic strategy is to subtract the time parts that are less significant + than the rollpoint from the current time. This should roll the time back to + the start of the time window for the current rollpoint. Then we add 1 window + worth of time and get the start time of the next window for the rollpoint. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_dateTime"> + <summary> + This object supplies the current date/time. Allows test code to plug in + a method to control this class when testing date/time based rolling. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_datePattern"> + <summary> + The date pattern. By default, the pattern is set to <c>".yyyy-MM-dd"</c> + meaning daily rollover. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_scheduledFilename"> + <summary> + The actual formatted filename that is currently being written to + or will be the file transferred to on roll over + (based on staticLogFileName). + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_nextCheck"> + <summary> + The timestamp when we shall next recompute the filename. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_now"> + <summary> + Holds date of last roll over + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_rollPoint"> + <summary> + The type of rolling done + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_maxFileSize"> + <summary> + The default maximum file size is 10MB + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_maxSizeRollBackups"> + <summary> + There is zero backup files by default + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_curSizeRollBackups"> + <summary> + How many sized based backups have been made so far + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_countDirection"> + <summary> + The rolling file count direction. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_rollingStyle"> + <summary> + The rolling mode used in this appender. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_rollDate"> + <summary> + Cache flag set if we are rolling by date. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_rollSize"> + <summary> + Cache flag set if we are rolling by size. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_staticLogFileName"> + <summary> + Value indicating whether to always log to the same file. + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.m_baseFileName"> + <summary> + FileName provided in configuration. Used for rolling properly + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.s_date1970"> + <summary> + The 1st of January 1970 in UTC + </summary> + </member> + <member name="P:log4net.Appender.RollingFileAppender.DatePattern"> + <summary> + Gets or sets the date pattern to be used for generating file names + when rolling over on date. + </summary> + <value> + The date pattern to be used for generating file names when rolling + over on date. + </value> + <remarks> + <para> + Takes a string in the same format as expected by + <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/>. + </para> + <para> + This property determines the rollover schedule when rolling over + on date. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.MaxSizeRollBackups"> + <summary> + Gets or sets the maximum number of backup files that are kept before + the oldest is erased. + </summary> + <value> + The maximum number of backup files that are kept before the oldest is + erased. + </value> + <remarks> + <para> + If set to zero, then there will be no backup files and the log file + will be truncated when it reaches <see cref="P:log4net.Appender.RollingFileAppender.MaxFileSize"/>. + </para> + <para> + If a negative number is supplied then no deletions will be made. Note + that this could result in very slow performance as a large number of + files are rolled over unless <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> is used. + </para> + <para> + The maximum applies to <b>each</b> time based group of files and + <b>not</b> the total. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.MaxFileSize"> + <summary> + Gets or sets the maximum size that the output file is allowed to reach + before being rolled over to backup files. + </summary> + <value> + The maximum size in bytes that the output file is allowed to reach before being + rolled over to backup files. + </value> + <remarks> + <para> + This property is equivalent to <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/> except + that it is required for differentiating the setter taking a + <see cref="T:System.Int64"/> argument from the setter taking a <see cref="T:System.String"/> + argument. + </para> + <para> + The default maximum file size is 10MB (10*1024*1024). + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.MaximumFileSize"> + <summary> + Gets or sets the maximum size that the output file is allowed to reach + before being rolled over to backup files. + </summary> + <value> + The maximum size that the output file is allowed to reach before being + rolled over to backup files. + </value> + <remarks> + <para> + This property allows you to specify the maximum size with the + suffixes "KB", "MB" or "GB" so that the size is interpreted being + expressed respectively in kilobytes, megabytes or gigabytes. + </para> + <para> + For example, the value "10KB" will be interpreted as 10240 bytes. + </para> + <para> + The default maximum file size is 10MB. + </para> + <para> + If you have the option to set the maximum file size programmatically + consider using the <see cref="P:log4net.Appender.RollingFileAppender.MaxFileSize"/> property instead as this + allows you to set the size in bytes as a <see cref="T:System.Int64"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.CountDirection"> + <summary> + Gets or sets the rolling file count direction. + </summary> + <value> + The rolling file count direction. + </value> + <remarks> + <para> + Indicates if the current file is the lowest numbered file or the + highest numbered file. + </para> + <para> + By default newer files have lower numbers (<see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> < 0), + i.e. log.1 is most recent, log.5 is the 5th backup, etc... + </para> + <para> + <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> >= 0 does the opposite i.e. + log.1 is the first backup made, log.5 is the 5th backup made, etc. + For infinite backups use <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> >= 0 to reduce + rollover costs. + </para> + <para>The default file count direction is -1.</para> + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.RollingStyle"> + <summary> + Gets or sets the rolling style. + </summary> + <value>The rolling style.</value> + <remarks> + <para> + The default rolling style is <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"/>. + </para> + <para> + When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Once"/> this appender's + <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property is set to <c>false</c>, otherwise + the appender would append to a single file rather than rolling + the file each time it is opened. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.StaticLogFileName"> + <summary> + Gets or sets a value indicating whether to always log to + the same file. + </summary> + <value> + <c>true</c> if always should be logged to the same file, otherwise <c>false</c>. + </value> + <remarks> + <para> + By default file.log is always the current file. Optionally + file.log.yyyy-mm-dd for current formatted datePattern can by the currently + logging file (or file.log.curSizeRollBackup or even + file.log.yyyy-mm-dd.curSizeRollBackup). + </para> + <para> + This will make time based rollovers with a large number of backups + much faster as the appender it won't have to rename all the backups! + </para> + </remarks> + </member> + <member name="T:log4net.Appender.RollingFileAppender.RollingMode"> + <summary> + Style of rolling to use + </summary> + <remarks> + <para> + Style of rolling to use + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Once"> + <summary> + Roll files once per program execution + </summary> + <remarks> + <para> + Roll files once per program execution. + Well really once each time this appender is + configured. + </para> + <para> + Setting this option also sets <c>AppendToFile</c> to + <c>false</c> on the <c>RollingFileAppender</c>, otherwise + this appender would just be a normal file appender. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Size"> + <summary> + Roll files based only on the size of the file + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Date"> + <summary> + Roll files based only on the date + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"> + <summary> + Roll files based on both the size and date of the file + </summary> + </member> + <member name="T:log4net.Appender.RollingFileAppender.RollPoint"> + <summary> + The code assumes that the following 'time' constants are in a increasing sequence. + </summary> + <remarks> + <para> + The code assumes that the following 'time' constants are in a increasing sequence. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.InvalidRollPoint"> + <summary> + Roll the log not based on the date + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfMinute"> + <summary> + Roll the log for each minute + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfHour"> + <summary> + Roll the log for each hour + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.HalfDay"> + <summary> + Roll the log twice a day (midday and midnight) + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfDay"> + <summary> + Roll the log each day (midnight) + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfWeek"> + <summary> + Roll the log each week + </summary> + </member> + <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfMonth"> + <summary> + Roll the log each month + </summary> + </member> + <member name="T:log4net.Appender.RollingFileAppender.IDateTime"> + <summary> + This interface is used to supply Date/Time information to the <see cref="T:log4net.Appender.RollingFileAppender"/>. + </summary> + <remarks> + This interface is used to supply Date/Time information to the <see cref="T:log4net.Appender.RollingFileAppender"/>. + Used primarily to allow test classes to plug themselves in so they can + supply test date/times. + </remarks> + </member> + <member name="P:log4net.Appender.RollingFileAppender.IDateTime.Now"> + <summary> + Gets the <i>current</i> time. + </summary> + <value>The <i>current</i> time.</value> + <remarks> + <para> + Gets the <i>current</i> time. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.RollingFileAppender.DefaultDateTime"> + <summary> + Default implementation of <see cref="T:log4net.Appender.RollingFileAppender.IDateTime"/> that returns the current time. + </summary> + </member> + <member name="P:log4net.Appender.RollingFileAppender.DefaultDateTime.Now"> + <summary> + Gets the <b>current</b> time. + </summary> + <value>The <b>current</b> time.</value> + <remarks> + <para> + Gets the <b>current</b> time. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.SmtpAppender"> + <summary> + Send an e-mail when a specific logging event occurs, typically on errors + or fatal errors. + </summary> + <remarks> + <para> + The number of logging events delivered in this e-mail depend on + the value of <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option. The + <see cref="T:log4net.Appender.SmtpAppender"/> keeps only the last + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> logging events in its + cyclic buffer. This keeps memory requirements at a reasonable level while + still delivering useful application context. + </para> + <note type="caution"> + Authentication and setting the server Port are only available on the MS .NET 1.1 runtime. + For these features to be enabled you need to ensure that you are using a version of + the log4net assembly that is built against the MS .NET 1.1 framework and that you are + running the your application on the MS .NET 1.1 runtime. On all other platforms only sending + unauthenticated messages to a server listening on port 25 (the default) is supported. + </note> + <para> + Authentication is supported by setting the <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> property to + either <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> or <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/>. + If using <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> authentication then the <see cref="P:log4net.Appender.SmtpAppender.Username"/> + and <see cref="P:log4net.Appender.SmtpAppender.Password"/> properties must also be set. + </para> + <para> + To set the SMTP server port use the <see cref="P:log4net.Appender.SmtpAppender.Port"/> property. The default port is 25. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.SmtpAppender.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Appender.SmtpAppender.SendBuffer(log4net.Core.LoggingEvent[])"> + <summary> + Sends the contents of the cyclic buffer as an e-mail message. + </summary> + <param name="events">The logging events to send.</param> + </member> + <member name="M:log4net.Appender.SmtpAppender.SendEmail(System.String)"> + <summary> + Send the email message + </summary> + <param name="messageBody">the body text to include in the mail</param> + </member> + <member name="P:log4net.Appender.SmtpAppender.To"> + <summary> + Gets or sets a semicolon-delimited list of recipient e-mail addresses. + </summary> + <value> + A semicolon-delimited list of e-mail addresses. + </value> + <remarks> + <para> + A semicolon-delimited list of recipient e-mail addresses. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.From"> + <summary> + Gets or sets the e-mail address of the sender. + </summary> + <value> + The e-mail address of the sender. + </value> + <remarks> + <para> + The e-mail address of the sender. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.Subject"> + <summary> + Gets or sets the subject line of the e-mail message. + </summary> + <value> + The subject line of the e-mail message. + </value> + <remarks> + <para> + The subject line of the e-mail message. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.SmtpHost"> + <summary> + Gets or sets the name of the SMTP relay mail server to use to send + the e-mail messages. + </summary> + <value> + The name of the e-mail relay server. If SmtpServer is not set, the + name of the local SMTP server is used. + </value> + <remarks> + <para> + The name of the e-mail relay server. If SmtpServer is not set, the + name of the local SMTP server is used. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.LocationInfo"> + <summary> + Obsolete + </summary> + <remarks> + Use the BufferingAppenderSkeleton Fix methods instead + </remarks> + <remarks> + <para> + Obsolete property. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.Authentication"> + <summary> + The mode to use to authentication with the SMTP server + </summary> + <remarks> + <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note> + <para> + Valid Authentication mode values are: <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"/>, + <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>, and <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/>. + The default value is <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"/>. When using + <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> you must specify the <see cref="P:log4net.Appender.SmtpAppender.Username"/> + and <see cref="P:log4net.Appender.SmtpAppender.Password"/> to use to authenticate. + When using <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/> the Windows credentials for the current + thread, if impersonating, or the process will be used to authenticate. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.Username"> + <summary> + The username to use to authenticate with the SMTP server + </summary> + <remarks> + <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note> + <para> + A <see cref="P:log4net.Appender.SmtpAppender.Username"/> and <see cref="P:log4net.Appender.SmtpAppender.Password"/> must be specified when + <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> is set to <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>, + otherwise the username will be ignored. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.Password"> + <summary> + The password to use to authenticate with the SMTP server + </summary> + <remarks> + <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note> + <para> + A <see cref="P:log4net.Appender.SmtpAppender.Username"/> and <see cref="P:log4net.Appender.SmtpAppender.Password"/> must be specified when + <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> is set to <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>, + otherwise the password will be ignored. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.Port"> + <summary> + The port on which the SMTP server is listening + </summary> + <remarks> + <note type="caution">Server Port is only available on the MS .NET 1.1 runtime.</note> + <para> + The port on which the SMTP server is listening. The default + port is <c>25</c>. The Port can only be changed when running on + the MS .NET 1.1 runtime. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.Priority"> + <summary> + Gets or sets the priority of the e-mail message + </summary> + <value> + One of the <see cref="T:System.Web.Mail.MailPriority"/> values. + </value> + <remarks> + <para> + Sets the priority of the e-mails generated by this + appender. The default priority is <see cref="F:System.Web.Mail.MailPriority.Normal"/>. + </para> + <para> + If you are using this appender to report errors then + you may want to set the priority to <see cref="F:System.Web.Mail.MailPriority.High"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.SmtpAppender.SmtpAuthentication"> + <summary> + Values for the <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> property. + </summary> + <remarks> + <para> + SMTP authentication modes. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"> + <summary> + No authentication + </summary> + </member> + <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"> + <summary> + Basic authentication. + </summary> + <remarks> + Requires a username and password to be supplied + </remarks> + </member> + <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"> + <summary> + Integrated authentication + </summary> + <remarks> + Uses the Windows credentials from the current thread or process to authenticate. + </remarks> + </member> + <member name="T:log4net.Appender.SmtpPickupDirAppender"> + <summary> + Send an email when a specific logging event occurs, typically on errors + or fatal errors. Rather than sending via smtp it writes a file into the + directory specified by <see cref="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"/>. This allows services such + as the IIS SMTP agent to manage sending the messages. + </summary> + <remarks> + <para> + The configuration for this appender is identical to that of the <c>SMTPAppender</c>, + except that instead of specifying the <c>SMTPAppender.SMTPHost</c> you specify + <see cref="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"/>. + </para> + <para> + The number of logging events delivered in this e-mail depend on + the value of <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option. The + <see cref="T:log4net.Appender.SmtpPickupDirAppender"/> keeps only the last + <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> logging events in its + cyclic buffer. This keeps memory requirements at a reasonable level while + still delivering useful application context. + </para> + </remarks> + <author>Niall Daley</author> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.SmtpPickupDirAppender.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Appender.SmtpPickupDirAppender.SendBuffer(log4net.Core.LoggingEvent[])"> + <summary> + Sends the contents of the cyclic buffer as an e-mail message. + </summary> + <param name="events">The logging events to send.</param> + <remarks> + <para> + Sends the contents of the cyclic buffer as an e-mail message. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"> + <summary> + Activate the options on this appender. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.SmtpPickupDirAppender.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="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.SmtpPickupDirAppender.ConvertToFullPath(System.String)"> + <summary> + Convert a path into a fully qualified path. + </summary> + <param name="path">The path to convert.</param> + <returns>The fully qualified path.</returns> + <remarks> + <para> + Converts the path specified to a fully + qualified path. If the path is relative it is + taken as relative from the application base + directory. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.SmtpPickupDirAppender.m_securityContext"> + <summary> + The security context to use for privileged calls + </summary> + </member> + <member name="P:log4net.Appender.SmtpPickupDirAppender.To"> + <summary> + Gets or sets a semicolon-delimited list of recipient e-mail addresses. + </summary> + <value> + A semicolon-delimited list of e-mail addresses. + </value> + <remarks> + <para> + A semicolon-delimited list of e-mail addresses. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpPickupDirAppender.From"> + <summary> + Gets or sets the e-mail address of the sender. + </summary> + <value> + The e-mail address of the sender. + </value> + <remarks> + <para> + The e-mail address of the sender. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpPickupDirAppender.Subject"> + <summary> + Gets or sets the subject line of the e-mail message. + </summary> + <value> + The subject line of the e-mail message. + </value> + <remarks> + <para> + The subject line of the e-mail message. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"> + <summary> + Gets or sets the path to write the messages to. + </summary> + <remarks> + <para> + Gets or sets the path to write the messages to. This should be the same + as that used by the agent sending the messages. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"> + <summary> + Gets or sets the <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> used to write to the pickup directory. + </summary> + <value> + The <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> used to write to the pickup directory. + </value> + <remarks> + <para> + Unless a <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> specified here for this appender + the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the + security context to use. The default behavior is to use the security context + of the current thread. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.SmtpPickupDirAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.TelnetAppender"> + <summary> + Appender that allows clients to connect via Telnet to receive log messages + </summary> + <remarks> + <para> + The TelnetAppender accepts socket connections and streams logging messages + back to the client. + The output is provided in a telnet-friendly way so that a log can be monitored + over a TCP/IP socket. + This allows simple remote monitoring of application logging. + </para> + <para> + The default <see cref="P:log4net.Appender.TelnetAppender.Port"/> is 23 (the telnet port). + </para> + </remarks> + <author>Keith Long</author> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Appender.TelnetAppender.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.OnClose"> + <summary> + Overrides the parent method to close the socket handler + </summary> + <remarks> + <para> + Closes all the outstanding connections. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.ActivateOptions"> + <summary> + Initialize the appender based on the options set. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Appender.TelnetAppender.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="M:log4net.Appender.TelnetAppender.ActivateOptions"/> must be called again. + </para> + <para> + Create the socket handler and wait for connections + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Writes the logging event to each connected client. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the logging event to each connected client. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.TelnetAppender.Port"> + <summary> + Gets or sets the TCP port number on which this <see cref="T:log4net.Appender.TelnetAppender"/> will listen for connections. + </summary> + <value> + An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/> + indicating the TCP port number on which this <see cref="T:log4net.Appender.TelnetAppender"/> will listen for connections. + </value> + <remarks> + <para> + The default value is 23 (the telnet port). + </para> + </remarks> + <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> + or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception> + </member> + <member name="P:log4net.Appender.TelnetAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.TelnetAppender.SocketHandler"> + <summary> + Helper class to manage connected clients + </summary> + <remarks> + <para> + The SocketHandler class is used to accept connections from + clients. It is threaded so that clients can connect/disconnect + asynchronously. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.#ctor(System.Int32)"> + <summary> + Opens a new server port on <paramref ref="port"/> + </summary> + <param name="port">the local port to listen on for connections</param> + <remarks> + <para> + Creates a socket handler on the specified local server port. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.Send(System.String)"> + <summary> + Sends a string message to each of the connected clients + </summary> + <param name="message">the text to send</param> + <remarks> + <para> + Sends a string message to each of the connected clients + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.AddClient(log4net.Appender.TelnetAppender.SocketHandler.SocketClient)"> + <summary> + Add a client to the internal clients list + </summary> + <param name="client">client to add</param> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.RemoveClient(log4net.Appender.TelnetAppender.SocketHandler.SocketClient)"> + <summary> + Remove a client from the internal clients list + </summary> + <param name="client">client to remove</param> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.OnConnect(System.IAsyncResult)"> + <summary> + Callback used to accept a connection on the server socket + </summary> + <param name="asyncResult">The result of the asynchronous operation</param> + <remarks> + <para> + On connection adds to the list of connections + if there are two many open connections you will be disconnected + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.Dispose"> + <summary> + Close all network connections + </summary> + <remarks> + <para> + Make sure we close all network connections + </para> + </remarks> + </member> + <member name="P:log4net.Appender.TelnetAppender.SocketHandler.HasConnections"> + <summary> + Test if this handler has active connections + </summary> + <value> + <c>true</c> if this handler has active connections + </value> + <remarks> + <para> + This property will be <c>true</c> while this handler has + active connections, that is at least one connection that + the handler will attempt to send a message to. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.TelnetAppender.SocketHandler.SocketClient"> + <summary> + Class that represents a client connected to this handler + </summary> + <remarks> + <para> + Class that represents a client connected to this handler + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.#ctor(System.Net.Sockets.Socket)"> + <summary> + Create this <see cref="T:log4net.Appender.TelnetAppender.SocketHandler.SocketClient"/> for the specified <see cref="T:System.Net.Sockets.Socket"/> + </summary> + <param name="socket">the client's socket</param> + <remarks> + <para> + Opens a stream writer on the socket. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.Send(System.String)"> + <summary> + Write a string to the client + </summary> + <param name="message">string to send</param> + <remarks> + <para> + Write a string to the client + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.Dispose"> + <summary> + Cleanup the clients connection + </summary> + <remarks> + <para> + Close the socket connection. + </para> + </remarks> + </member> + <member name="T:log4net.Appender.TraceAppender"> + <summary> + Appends log events to the <see cref="T:System.Diagnostics.Trace"/> system. + </summary> + <remarks> + <para> + The application configuration file can be used to control what listeners + are actually used. See the MSDN documentation for the + <see cref="T:System.Diagnostics.Trace"/> class for details on configuring the + trace system. + </para> + <para> + Events are written using the <c>System.Diagnostics.Trace.Write(string,string)</c> + method. The event's logger name is passed as the value for the category name to the Write method. + </para> + <para> + <b>Compact Framework</b><br/> + The Compact Framework does not support the <see cref="T:System.Diagnostics.Trace"/> + class for any operation except <c>Assert</c>. When using the Compact Framework this + appender will write to the <see cref="T:System.Diagnostics.Debug"/> system rather than + the Trace system. This appender will therefore behave like the <see cref="T:log4net.Appender.DebugAppender"/>. + </para> + </remarks> + <author>Douglas de la Torre</author> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Appender.TraceAppender.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.TraceAppender"/>. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TraceAppender.#ctor(log4net.Layout.ILayout)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Appender.TraceAppender"/> + with a specified layout. + </summary> + <param name="layout">The layout to use with this appender.</param> + <remarks> + <para> + Obsolete constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Appender.TraceAppender.Append(log4net.Core.LoggingEvent)"> + <summary> + Writes the logging event to the <see cref="T:System.Diagnostics.Trace"/> system. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Writes the logging event to the <see cref="T:System.Diagnostics.Trace"/> system. + </para> + </remarks> + </member> + <member name="F:log4net.Appender.TraceAppender.m_immediateFlush"> + <summary> + Immediate flush means that the underlying writer or output stream + will be flushed at the end of each append operation. + </summary> + <remarks> + <para> + Immediate flush is slower but ensures that each append request is + actually written. If <see cref="P:log4net.Appender.TraceAppender.ImmediateFlush"/> is set to + <c>false</c>, then there is a good chance that the last few + logs events are not actually written to persistent media if and + when the application crashes. + </para> + <para> + The default value is <c>true</c>.</para> + </remarks> + </member> + <member name="P:log4net.Appender.TraceAppender.ImmediateFlush"> + <summary> + Gets or sets a value that indicates whether the appender will + flush at the end of each write. + </summary> + <remarks> + <para>The default behavior is to flush at the end of each + write. If the option is set to<c>false</c>, then the underlying + stream can defer writing to physical medium to a later time. + </para> + <para> + Avoiding the flush operation at the end of each append results + in a performance gain of 10 to 20 percent. However, there is safety + trade-off involved in skipping flushing. Indeed, when flushing is + skipped, then it is likely that the last few log events will not + be recorded on disk when the application exits. This is a high + price to pay even for a 20% performance gain. + </para> + </remarks> + </member> + <member name="P:log4net.Appender.TraceAppender.RequiresLayout"> + <summary> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </summary> + <value><c>true</c></value> + <remarks> + <para> + This appender requires a <see cref="N:log4net.Layout"/> to be set. + </para> + </remarks> + </member> + <member name="T:log4net.Config.AliasDomainAttribute"> + <summary> + Assembly level attribute that specifies a domain to alias to this assembly's repository. + </summary> + <remarks> + <para> + <b>AliasDomainAttribute is obsolete. Use AliasRepositoryAttribute instead of AliasDomainAttribute.</b> + </para> + <para> + An assembly's logger repository is defined by its <see cref="T:log4net.Config.DomainAttribute"/>, + however this can be overridden by an assembly loaded before the target assembly. + </para> + <para> + An assembly can alias another assembly's domain to its repository by + specifying this attribute with the name of the target domain. + </para> + <para> + This attribute can only be specified on the assembly and may be used + as many times as necessary to alias all the required domains. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Config.AliasRepositoryAttribute"> + <summary> + Assembly level attribute that specifies a repository to alias to this assembly's repository. + </summary> + <remarks> + <para> + An assembly's logger repository is defined by its <see cref="T:log4net.Config.RepositoryAttribute"/>, + however this can be overridden by an assembly loaded before the target assembly. + </para> + <para> + An assembly can alias another assembly's repository to its repository by + specifying this attribute with the name of the target repository. + </para> + <para> + This attribute can only be specified on the assembly and may be used + as many times as necessary to alias all the required repositories. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.AliasRepositoryAttribute.#ctor(System.String)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.AliasRepositoryAttribute"/> class with + the specified repository to alias to this assembly's repository. + </summary> + <param name="name">The repository to alias to this assemby's repository.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Config.AliasRepositoryAttribute"/> class with + the specified repository to alias to this assembly's repository. + </para> + </remarks> + </member> + <member name="P:log4net.Config.AliasRepositoryAttribute.Name"> + <summary> + Gets or sets the repository to alias to this assemby's repository. + </summary> + <value> + The repository to alias to this assemby's repository. + </value> + <remarks> + <para> + The name of the repository to alias to this assemby's repository. + </para> + </remarks> + </member> + <member name="M:log4net.Config.AliasDomainAttribute.#ctor(System.String)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.AliasDomainAttribute"/> class with + the specified domain to alias to this assembly's repository. + </summary> + <param name="name">The domain to alias to this assemby's repository.</param> + <remarks> + <para> + Obsolete. Use <see cref="T:log4net.Config.AliasRepositoryAttribute"/> instead of <see cref="T:log4net.Config.AliasDomainAttribute"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Config.BasicConfigurator"> + <summary> + Use this class to quickly configure a <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>. + </summary> + <remarks> + <para> + Allows very simple programmatic configuration of log4net. + </para> + <para> + Only one appender can be configured using this configurator. + The appender is set at the root of the hierarchy and all logging + events will be delivered to that appender. + </para> + <para> + Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore + they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method + be called after the appenders properties have been configured. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.BasicConfigurator.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.BasicConfigurator"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to prevent instantiation of this class. + </para> + </remarks> + </member> + <member name="M:log4net.Config.BasicConfigurator.Configure"> + <summary> + Initializes the log4net system with a default configuration. + </summary> + <remarks> + <para> + Initializes the log4net logging system using a <see cref="T:log4net.Appender.ConsoleAppender"/> + that will write to <c>Console.Out</c>. The log messages are + formatted using the <see cref="T:log4net.Layout.PatternLayout"/> layout object + with the <see cref="F:log4net.Layout.PatternLayout.DetailConversionPattern"/> + layout style. + </para> + </remarks> + </member> + <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Appender.IAppender)"> + <summary> + Initializes the log4net system using the specified appender. + </summary> + <param name="appender">The appender to use to log all logging events.</param> + <remarks> + <para> + Initializes the log4net system using the specified appender. + </para> + </remarks> + </member> + <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Repository.ILoggerRepository)"> + <summary> + Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> with a default configuration. + </summary> + <param name="repository">The repository to configure.</param> + <remarks> + <para> + Initializes the specified repository using a <see cref="T:log4net.Appender.ConsoleAppender"/> + that will write to <c>Console.Out</c>. The log messages are + formatted using the <see cref="T:log4net.Layout.PatternLayout"/> layout object + with the <see cref="F:log4net.Layout.PatternLayout.DetailConversionPattern"/> + layout style. + </para> + </remarks> + </member> + <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Repository.ILoggerRepository,log4net.Appender.IAppender)"> + <summary> + Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified appender. + </summary> + <param name="repository">The repository to configure.</param> + <param name="appender">The appender to use to log all logging events.</param> + <remarks> + <para> + Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified appender. + </para> + </remarks> + </member> + <member name="T:log4net.Config.ConfiguratorAttribute"> + <summary> + Base class for all log4net configuration attributes. + </summary> + <remarks> + This is an abstract class that must be extended by + specific configurators. This attribute allows the + configurator to be parameterized by an assembly level + attribute. + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.ConfiguratorAttribute.#ctor(System.Int32)"> + <summary> + Constructor used by subclasses. + </summary> + <param name="priority">the ordering priority for this configurator</param> + <remarks> + <para> + The <paramref name="priority"/> is used to order the configurator + attributes before they are invoked. Higher priority configurators are executed + before lower priority ones. + </para> + </remarks> + </member> + <member name="M:log4net.Config.ConfiguratorAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly. + </summary> + <param name="sourceAssembly">The assembly that this attribute was defined on.</param> + <param name="targetRepository">The repository to configure.</param> + <remarks> + <para> + Abstract method implemented by a subclass. When this method is called + the subclass should configure the <paramref name="targetRepository"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Config.ConfiguratorAttribute.CompareTo(System.Object)"> + <summary> + Compare this instance to another ConfiguratorAttribute + </summary> + <param name="obj">the object to compare to</param> + <returns>see <see cref="M:System.IComparable.CompareTo(System.Object)"/></returns> + <remarks> + <para> + Compares the priorities of the two <see cref="T:log4net.Config.ConfiguratorAttribute"/> instances. + Sorts by priority in descending order. Objects with the same priority are + randomly ordered. + </para> + </remarks> + </member> + <member name="T:log4net.Config.DomainAttribute"> + <summary> + Assembly level attribute that specifies the logging domain for the assembly. + </summary> + <remarks> + <para> + <b>DomainAttribute is obsolete. Use RepositoryAttribute instead of DomainAttribute.</b> + </para> + <para> + Assemblies are mapped to logging domains. Each domain has its own + logging repository. This attribute specified on the assembly controls + the configuration of the domain. The <see cref="P:log4net.Config.RepositoryAttribute.Name"/> property specifies the name + of the domain that this assembly is a part of. The <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/> + specifies the type of the repository objects to create for the domain. If + this attribute is not specified and a <see cref="P:log4net.Config.RepositoryAttribute.Name"/> is not specified + then the assembly will be part of the default shared logging domain. + </para> + <para> + This attribute can only be specified on the assembly and may only be used + once per assembly. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Config.RepositoryAttribute"> + <summary> + Assembly level attribute that specifies the logging repository for the assembly. + </summary> + <remarks> + <para> + Assemblies are mapped to logging repository. This attribute specified + on the assembly controls + the configuration of the repository. The <see cref="P:log4net.Config.RepositoryAttribute.Name"/> property specifies the name + of the repository that this assembly is a part of. The <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/> + specifies the type of the <see cref="T:log4net.Repository.ILoggerRepository"/> object + to create for the assembly. If this attribute is not specified or a <see cref="P:log4net.Config.RepositoryAttribute.Name"/> + is not specified then the assembly will be part of the default shared logging repository. + </para> + <para> + This attribute can only be specified on the assembly and may only be used + once per assembly. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.RepositoryAttribute.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.RepositoryAttribute"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Config.RepositoryAttribute.#ctor(System.String)"> + <summary> + Initialize a new instance of the <see cref="T:log4net.Config.RepositoryAttribute"/> class + with the name of the repository. + </summary> + <param name="name">The name of the repository.</param> + <remarks> + <para> + Initialize the attribute with the name for the assembly's repository. + </para> + </remarks> + </member> + <member name="P:log4net.Config.RepositoryAttribute.Name"> + <summary> + Gets or sets the name of the logging repository. + </summary> + <value> + The string name to use as the name of the repository associated with this + assembly. + </value> + <remarks> + <para> + This value does not have to be unique. Several assemblies can share the + same repository. They will share the logging configuration of the repository. + </para> + </remarks> + </member> + <member name="P:log4net.Config.RepositoryAttribute.RepositoryType"> + <summary> + Gets or sets the type of repository to create for this assembly. + </summary> + <value> + The type of repository to create for this assembly. + </value> + <remarks> + <para> + The type of the repository to create for the assembly. + The type must implement the <see cref="T:log4net.Repository.ILoggerRepository"/> + interface. + </para> + <para> + This will be the type of repository created when + the repository is created. If multiple assemblies reference the + same repository then the repository is only created once using the + <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/> of the first assembly to call into the + repository. + </para> + </remarks> + </member> + <member name="M:log4net.Config.DomainAttribute.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.DomainAttribute"/> class. + </summary> + <remarks> + <para> + Obsolete. Use RepositoryAttribute instead of DomainAttribute. + </para> + </remarks> + </member> + <member name="M:log4net.Config.DomainAttribute.#ctor(System.String)"> + <summary> + Initialize a new instance of the <see cref="T:log4net.Config.DomainAttribute"/> class + with the name of the domain. + </summary> + <param name="name">The name of the domain.</param> + <remarks> + <para> + Obsolete. Use RepositoryAttribute instead of DomainAttribute. + </para> + </remarks> + </member> + <member name="T:log4net.Config.DOMConfigurator"> + <summary> + Use this class to initialize the log4net environment using an Xml tree. + </summary> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + Configures a <see cref="T:log4net.Repository.ILoggerRepository"/> using an Xml tree. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.DOMConfigurator.#ctor"> + <summary> + Private constructor + </summary> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure"> + <summary> + Automatically configures the log4net system based on the + application's configuration settings. + </summary> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + Each application has a configuration file. This has the + same name as the application with '.config' appended. + This file is XML and calling this function prompts the + configurator to look in that file for a section called + <c>log4net</c> that contains the configuration data. + </remarks> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository)"> + <summary> + Automatically configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using settings + stored in the application's configuration file. + </summary> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + Each application has a configuration file. This has the + same name as the application with '.config' appended. + This file is XML and calling this function prompts the + configurator to look in that file for a section called + <c>log4net</c> that contains the configuration data. + </remarks> + <param name="repository">The repository to configure.</param> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(System.Xml.XmlElement)"> + <summary> + Configures log4net using a <c>log4net</c> element + </summary> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + Loads the log4net configuration from the XML element + supplied as <paramref name="element"/>. + </remarks> + <param name="element">The element to parse.</param> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified XML + element. + </summary> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + Loads the log4net configuration from the XML element + supplied as <paramref name="element"/>. + </remarks> + <param name="repository">The repository to configure.</param> + <param name="element">The element to parse.</param> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"> + <summary> + Configures log4net using the specified configuration file. + </summary> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the log4net configuration data. + </para> + <para> + The log4net configuration file can possible be specified in the application's + configuration file (either <c>MyAppName.exe.config</c> for a + normal application on <c>Web.config</c> for an ASP.NET application). + </para> + <example> + The following example configures log4net using a configuration file, of which the + location is stored in the application's configuration file : + </example> + <code lang="C#"> + using log4net.Config; + using System.IO; + using System.Configuration; + + ... + + DOMConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); + </code> + <para> + In the <c>.config</c> file, the path to the log4net can be specified like this : + </para> + <code lang="XML" escaped="true"> + <configuration> + <appSettings> + <add key="log4net-config-file" value="log.config"/> + </appSettings> + </configuration> + </code> + </remarks> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(System.IO.Stream)"> + <summary> + Configures log4net using the specified configuration file. + </summary> + <param name="configStream">A stream to load the XML configuration from.</param> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + The configuration data must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the log4net configuration data. + </para> + <para> + Note that this method will NOT close the stream parameter. + </para> + </remarks> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration + file. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The log4net configuration file can possible be specified in the application's + configuration file (either <c>MyAppName.exe.config</c> for a + normal application on <c>Web.config</c> for an ASP.NET application). + </para> + <example> + The following example configures log4net using a configuration file, of which the + location is stored in the application's configuration file : + </example> + <code lang="C#"> + using log4net.Config; + using System.IO; + using System.Configuration; + + ... + + DOMConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); + </code> + <para> + In the <c>.config</c> file, the path to the log4net can be specified like this : + </para> + <code lang="XML" escaped="true"> + <configuration> + <appSettings> + <add key="log4net-config-file" value="log.config"/> + </appSettings> + </configuration> + </code> + </remarks> + </member> + <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.Stream)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration + file. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configStream">The stream to load the XML configuration from.</param> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + The configuration data must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + Note that this method will NOT close the stream parameter. + </para> + </remarks> + </member> + <member name="M:log4net.Config.DOMConfigurator.ConfigureAndWatch(System.IO.FileInfo)"> + <summary> + Configures log4net using the file specified, monitors the file for changes + and reloads the configuration if a change is detected. + </summary> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/> + and depends on the behavior of that class. + </para> + <para> + For more information on how to configure log4net using + a separate configuration file, see <see cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>. + </para> + </remarks> + <seealso cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/> + </member> + <member name="M:log4net.Config.DOMConfigurator.ConfigureAndWatch(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the file specified, + monitors the file for changes and reloads the configuration if a change + is detected. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b> + </para> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/> + and depends on the behavior of that class. + </para> + <para> + For more information on how to configure log4net using + a separate configuration file, see <see cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>. + </para> + </remarks> + <seealso cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/> + </member> + <member name="T:log4net.Config.DOMConfiguratorAttribute"> + <summary> + Assembly level attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>. + </summary> + <remarks> + <para> + <b>AliasDomainAttribute is obsolete. Use AliasRepositoryAttribute instead of AliasDomainAttribute.</b> + </para> + <para> + This attribute may only be used at the assembly scope and can only + be used once per assembly. + </para> + <para> + Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/> + without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/> + methods. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Config.XmlConfiguratorAttribute"> + <summary> + Assembly level attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>. + </summary> + <remarks> + <para> + This attribute may only be used at the assembly scope and can only + be used once per assembly. + </para> + <para> + Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/> + without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/> + methods. + </para> + <para> + If neither of the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> or <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> + properties are set the configuration is loaded from the application's .config file. + If set the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> property takes priority over the + <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> property. The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> property + specifies a path to a file to load the config from. The path is relative to the + application's base directory; <see cref="P:System.AppDomain.BaseDirectory"/>. + The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> property is used as a postfix to the assembly file name. + The config file must be located in the application's base directory; <see cref="P:System.AppDomain.BaseDirectory"/>. + For example in a console application setting the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> to + <c>config</c> has the same effect as not specifying the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> or + <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> properties. + </para> + <para> + The <see cref="P:log4net.Config.XmlConfiguratorAttribute.Watch"/> property can be set to cause the <see cref="T:log4net.Config.XmlConfigurator"/> + to watch the configuration file for changes. + </para> + <note> + <para> + Log4net will only look for assembly level configuration attributes once. + When using the log4net assembly level attributes to control the configuration + of log4net you must ensure that the first call to any of the + <see cref="T:log4net.Core.LoggerManager"/> methods is made from the assembly with the configuration + attributes. + </para> + <para> + If you cannot guarantee the order in which log4net calls will be made from + different assemblies you must use programmatic configuration instead, i.e. + call the <see cref="M:log4net.Config.XmlConfigurator.Configure"/> method directly. + </para> + </note> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.XmlConfiguratorAttribute.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfiguratorAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly. + </summary> + <param name="sourceAssembly">The assembly that this attribute was defined on.</param> + <param name="targetRepository">The repository to configure.</param> + <remarks> + <para> + Configure the repository using the <see cref="T:log4net.Config.XmlConfigurator"/>. + The <paramref name="targetRepository"/> specified must extend the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> + class otherwise the <see cref="T:log4net.Config.XmlConfigurator"/> will not be able to + configure it. + </para> + </remarks> + <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="repository"/> does not extend <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.</exception> + </member> + <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromFile(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Attempt to load configuration from the local file system + </summary> + <param name="sourceAssembly">The assembly that this attribute was defined on.</param> + <param name="targetRepository">The repository to configure.</param> + </member> + <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromFile(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Configure the specified repository using a <see cref="T:System.IO.FileInfo"/> + </summary> + <param name="targetRepository">The repository to configure.</param> + <param name="configFile">the FileInfo pointing to the config file</param> + </member> + <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromUri(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Attempt to load configuration from a URI + </summary> + <param name="sourceAssembly">The assembly that this attribute was defined on.</param> + <param name="targetRepository">The repository to configure.</param> + </member> + <member name="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"> + <summary> + Gets or sets the filename of the configuration file. + </summary> + <value> + The filename of the configuration file. + </value> + <remarks> + <para> + If specified, this is the name of the configuration file to use with + the <see cref="T:log4net.Config.XmlConfigurator"/>. This file path is relative to the + <b>application base</b> directory (<see cref="P:System.AppDomain.BaseDirectory"/>). + </para> + <para> + The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> takes priority over the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"> + <summary> + Gets or sets the extension of the configuration file. + </summary> + <value> + The extension of the configuration file. + </value> + <remarks> + <para> + If specified this is the extension for the configuration file. + The path to the config file is built by using the <b>application + base</b> directory (<see cref="P:System.AppDomain.BaseDirectory"/>), + the <b>assembly file name</b> and the config file extension. + </para> + <para> + If the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> is set to <c>MyExt</c> then + possible config file names would be: <c>MyConsoleApp.exe.MyExt</c> or + <c>MyClassLibrary.dll.MyExt</c>. + </para> + <para> + The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> takes priority over the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Config.XmlConfiguratorAttribute.Watch"> + <summary> + Gets or sets a value indicating whether to watch the configuration file. + </summary> + <value> + <c>true</c> if the configuration should be watched, <c>false</c> otherwise. + </value> + <remarks> + <para> + If this flag is specified and set to <c>true</c> then the framework + will watch the configuration file and will reload the config each time + the file is modified. + </para> + <para> + The config file can only be watched if it is loaded from local disk. + In a No-Touch (Smart Client) deployment where the application is downloaded + from a web server the config file may not reside on the local disk + and therefore it may not be able to watch it. + </para> + <note> + Watching configuration is not supported on the SSCLI. + </note> + </remarks> + </member> + <member name="T:log4net.Config.Log4NetConfigurationSectionHandler"> + <summary> + Class to register for the log4net section of the configuration file + </summary> + <remarks> + The log4net section of the configuration file needs to have a section + handler registered. This is the section handler used. It simply returns + the XML element that is the root of the section. + </remarks> + <example> + Example of registering the log4net section handler : + <code lang="XML" escaped="true"> + <configuration> + <configSections> + <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> + </configSections> + <log4net> + log4net configuration XML goes here + </log4net> + </configuration> + </code> + </example> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.Log4NetConfigurationSectionHandler.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> class. + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.Config.Log4NetConfigurationSectionHandler.Create(System.Object,System.Object,System.Xml.XmlNode)"> + <summary> + Parses the configuration section. + </summary> + <param name="parent">The configuration settings in a corresponding parent configuration section.</param> + <param name="configContext">The configuration context when called from the ASP.NET configuration system. Otherwise, this parameter is reserved and is a null reference.</param> + <param name="section">The <see cref="T:System.Xml.XmlNode"/> for the log4net section.</param> + <returns>The <see cref="T:System.Xml.XmlNode"/> for the log4net section.</returns> + <remarks> + <para> + Returns the <see cref="T:System.Xml.XmlNode"/> containing the configuration data, + </para> + </remarks> + </member> + <member name="T:log4net.Config.PluginAttribute"> + <summary> + Assembly level attribute that specifies a plugin to attach to + the repository. + </summary> + <remarks> + <para> + Specifies the type of a plugin to create and attach to the + assembly's repository. The plugin type must implement the + <see cref="T:log4net.Plugin.IPlugin"/> interface. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Plugin.IPluginFactory"> + <summary> + Interface used to create plugins. + </summary> + <remarks> + <para> + Interface used to create a plugin. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Plugin.IPluginFactory.CreatePlugin"> + <summary> + Creates the plugin object. + </summary> + <returns>the new plugin instance</returns> + <remarks> + <para> + Create and return a new plugin instance. + </para> + </remarks> + </member> + <member name="M:log4net.Config.PluginAttribute.#ctor(System.String)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.PluginAttribute"/> class + with the specified type. + </summary> + <param name="typeName">The type name of plugin to create.</param> + <remarks> + <para> + Create the attribute with the plugin type specified. + </para> + <para> + Where possible use the constructor that takes a <see cref="T:System.Type"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Config.PluginAttribute.#ctor(System.Type)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.PluginAttribute"/> class + with the specified type. + </summary> + <param name="type">The type of plugin to create.</param> + <remarks> + <para> + Create the attribute with the plugin type specified. + </para> + </remarks> + </member> + <member name="M:log4net.Config.PluginAttribute.CreatePlugin"> + <summary> + Creates the plugin object defined by this attribute. + </summary> + <remarks> + <para> + Creates the instance of the <see cref="T:log4net.Plugin.IPlugin"/> object as + specified by this attribute. + </para> + </remarks> + <returns>The plugin object.</returns> + </member> + <member name="M:log4net.Config.PluginAttribute.ToString"> + <summary> + Returns a representation of the properties of this object. + </summary> + <remarks> + <para> + Overrides base class <see cref="M:System.Object.ToString"/> method to + return a representation of the properties of this object. + </para> + </remarks> + <returns>A representation of the properties of this object</returns> + </member> + <member name="P:log4net.Config.PluginAttribute.Type"> + <summary> + Gets or sets the type for the plugin. + </summary> + <value> + The type for the plugin. + </value> + <remarks> + <para> + The type for the plugin. + </para> + </remarks> + </member> + <member name="P:log4net.Config.PluginAttribute.TypeName"> + <summary> + Gets or sets the type name for the plugin. + </summary> + <value> + The type name for the plugin. + </value> + <remarks> + <para> + The type name for the plugin. + </para> + <para> + Where possible use the <see cref="P:log4net.Config.PluginAttribute.Type"/> property instead. + </para> + </remarks> + </member> + <member name="T:log4net.Config.SecurityContextProviderAttribute"> + <summary> + Assembly level attribute to configure the <see cref="T:log4net.Core.SecurityContextProvider"/>. + </summary> + <remarks> + <para> + This attribute may only be used at the assembly scope and can only + be used once per assembly. + </para> + <para> + Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/> + without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/> + methods. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Config.SecurityContextProviderAttribute.#ctor(System.Type)"> + <summary> + Construct provider attribute with type specified + </summary> + <param name="providerType">the type of the provider to use</param> + <remarks> + <para> + The provider specified must subclass the <see cref="T:log4net.Core.SecurityContextProvider"/> + class. + </para> + </remarks> + </member> + <member name="M:log4net.Config.SecurityContextProviderAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Configures the SecurityContextProvider + </summary> + <param name="sourceAssembly">The assembly that this attribute was defined on.</param> + <param name="targetRepository">The repository to configure.</param> + <remarks> + <para> + Creates a provider instance from the <see cref="P:log4net.Config.SecurityContextProviderAttribute.ProviderType"/> specified. + Sets this as the default security context provider <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Config.SecurityContextProviderAttribute.ProviderType"> + <summary> + Gets or sets the type of the provider to use. + </summary> + <value> + the type of the provider to use. + </value> + <remarks> + <para> + The provider specified must subclass the <see cref="T:log4net.Core.SecurityContextProvider"/> + class. + </para> + </remarks> + </member> + <member name="T:log4net.Config.XmlConfigurator"> + <summary> + Use this class to initialize the log4net environment using an Xml tree. + </summary> + <remarks> + <para> + Configures a <see cref="T:log4net.Repository.ILoggerRepository"/> using an Xml tree. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Config.XmlConfigurator.#ctor"> + <summary> + Private constructor + </summary> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure"> + <summary> + Automatically configures the log4net system based on the + application's configuration settings. + </summary> + <remarks> + <para> + Each application has a configuration file. This has the + same name as the application with '.config' appended. + This file is XML and calling this function prompts the + configurator to look in that file for a section called + <c>log4net</c> that contains the configuration data. + </para> + <para> + To use this method to configure log4net you must specify + the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> section + handler for the <c>log4net</c> configuration section. See the + <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> for an example. + </para> + </remarks> + <seealso cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository)"> + <summary> + Automatically configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using settings + stored in the application's configuration file. + </summary> + <remarks> + <para> + Each application has a configuration file. This has the + same name as the application with '.config' appended. + This file is XML and calling this function prompts the + configurator to look in that file for a section called + <c>log4net</c> that contains the configuration data. + </para> + <para> + To use this method to configure log4net you must specify + the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> section + handler for the <c>log4net</c> configuration section. See the + <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> for an example. + </para> + </remarks> + <param name="repository">The repository to configure.</param> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(System.Xml.XmlElement)"> + <summary> + Configures log4net using a <c>log4net</c> element + </summary> + <remarks> + <para> + Loads the log4net configuration from the XML element + supplied as <paramref name="element"/>. + </para> + </remarks> + <param name="element">The element to parse.</param> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified XML + element. + </summary> + <remarks> + Loads the log4net configuration from the XML element + supplied as <paramref name="element"/>. + </remarks> + <param name="repository">The repository to configure.</param> + <param name="element">The element to parse.</param> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"> + <summary> + Configures log4net using the specified configuration file. + </summary> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the log4net configuration data. + </para> + <para> + The log4net configuration file can possible be specified in the application's + configuration file (either <c>MyAppName.exe.config</c> for a + normal application on <c>Web.config</c> for an ASP.NET application). + </para> + <para> + The first element matching <c><configuration></c> will be read as the + configuration. If this file is also a .NET .config file then you must specify + a configuration section for the <c>log4net</c> element otherwise .NET will + complain. Set the type for the section handler to <see cref="T:System.Configuration.IgnoreSectionHandler"/>, for example: + <code lang="XML" escaped="true"> + <configSections> + <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> + </configSections> + </code> + </para> + <example> + The following example configures log4net using a configuration file, of which the + location is stored in the application's configuration file : + </example> + <code lang="C#"> + using log4net.Config; + using System.IO; + using System.Configuration; + + ... + + XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); + </code> + <para> + In the <c>.config</c> file, the path to the log4net can be specified like this : + </para> + <code lang="XML" escaped="true"> + <configuration> + <appSettings> + <add key="log4net-config-file" value="log.config"/> + </appSettings> + </configuration> + </code> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(System.Uri)"> + <summary> + Configures log4net using the specified configuration URI. + </summary> + <param name="configUri">A URI to load the XML configuration from.</param> + <remarks> + <para> + The configuration data must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the log4net configuration data. + </para> + <para> + The <see cref="T:System.Net.WebRequest"/> must support the URI scheme specified. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(System.IO.Stream)"> + <summary> + Configures log4net using the specified configuration data stream. + </summary> + <param name="configStream">A stream to load the XML configuration from.</param> + <remarks> + <para> + The configuration data must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the log4net configuration data. + </para> + <para> + Note that this method will NOT close the stream parameter. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration + file. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The log4net configuration file can possible be specified in the application's + configuration file (either <c>MyAppName.exe.config</c> for a + normal application on <c>Web.config</c> for an ASP.NET application). + </para> + <para> + The first element matching <c><configuration></c> will be read as the + configuration. If this file is also a .NET .config file then you must specify + a configuration section for the <c>log4net</c> element otherwise .NET will + complain. Set the type for the section handler to <see cref="T:System.Configuration.IgnoreSectionHandler"/>, for example: + <code lang="XML" escaped="true"> + <configSections> + <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> + </configSections> + </code> + </para> + <example> + The following example configures log4net using a configuration file, of which the + location is stored in the application's configuration file : + </example> + <code lang="C#"> + using log4net.Config; + using System.IO; + using System.Configuration; + + ... + + XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"])); + </code> + <para> + In the <c>.config</c> file, the path to the log4net can be specified like this : + </para> + <code lang="XML" escaped="true"> + <configuration> + <appSettings> + <add key="log4net-config-file" value="log.config"/> + </appSettings> + </configuration> + </code> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Uri)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration + URI. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configUri">A URI to load the XML configuration from.</param> + <remarks> + <para> + The configuration data must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The <see cref="T:System.Net.WebRequest"/> must support the URI scheme specified. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.Stream)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration + file. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configStream">The stream to load the XML configuration from.</param> + <remarks> + <para> + The configuration data must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + Note that this method will NOT close the stream parameter. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatch(System.IO.FileInfo)"> + <summary> + Configures log4net using the file specified, monitors the file for changes + and reloads the configuration if a change is detected. + </summary> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/> + and depends on the behavior of that class. + </para> + <para> + For more information on how to configure log4net using + a separate configuration file, see <see cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>. + </para> + </remarks> + <seealso cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatch(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the file specified, + monitors the file for changes and reloads the configuration if a change + is detected. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configFile">The XML file to load the configuration from.</param> + <remarks> + <para> + The configuration file must be valid XML. It must contain + at least one element called <c>log4net</c> that holds + the configuration data. + </para> + <para> + The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/> + and depends on the behavior of that class. + </para> + <para> + For more information on how to configure log4net using + a separate configuration file, see <see cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>. + </para> + </remarks> + <seealso cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureFromXml(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)"> + <summary> + Configures the specified repository using a <c>log4net</c> element. + </summary> + <param name="repository">The hierarchy to configure.</param> + <param name="element">The element to parse.</param> + <remarks> + <para> + Loads the log4net configuration from the XML element + supplied as <paramref name="element"/>. + </para> + <para> + This method is ultimately called by one of the Configure methods + to load the configuration from an <see cref="T:System.Xml.XmlElement"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"> + <summary> + Class used to watch config files. + </summary> + <remarks> + <para> + Uses the <see cref="T:System.IO.FileSystemWatcher"/> to monitor + changes to a specified file. Because multiple change notifications + may be raised when the file is modified, a timer is used to + compress the notifications into a single event. The timer + waits for <see cref="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"/> time before delivering + the event notification. If any further <see cref="T:System.IO.FileSystemWatcher"/> + change notifications arrive while the timer is waiting it + is reset and waits again for <see cref="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"/> to + elapse. + </para> + </remarks> + </member> + <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"> + <summary> + The default amount of time to wait after receiving notification + before reloading the config file. + </summary> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.StartWatching(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Watch a specified config file used to configure a repository + </summary> + <param name="repository">The repository to configure.</param> + <param name="configFile">The configuration file to watch.</param> + <remarks> + <para> + Watch a specified config file used to configure a repository + </para> + </remarks> + </member> + <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_configFile"> + <summary> + Holds the FileInfo used to configure the XmlConfigurator + </summary> + </member> + <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_repository"> + <summary> + Holds the repository being configured. + </summary> + </member> + <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_timer"> + <summary> + The timer used to compress the notification events. + </summary> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.#ctor(log4net.Repository.ILoggerRepository,System.IO.FileInfo)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/> class. + </summary> + <param name="repository">The repository to configure.</param> + <param name="configFile">The configuration file to watch.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.ConfigureAndWatchHandler_OnChanged(System.Object,System.IO.FileSystemEventArgs)"> + <summary> + Event handler used by <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/>. + </summary> + <param name="source">The <see cref="T:System.IO.FileSystemWatcher"/> firing the event.</param> + <param name="e">The argument indicates the file that caused the event to be fired.</param> + <remarks> + <para> + This handler reloads the configuration from the file when the event is fired. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.ConfigureAndWatchHandler_OnRenamed(System.Object,System.IO.RenamedEventArgs)"> + <summary> + Event handler used by <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/>. + </summary> + <param name="source">The <see cref="T:System.IO.FileSystemWatcher"/> firing the event.</param> + <param name="e">The argument indicates the file that caused the event to be fired.</param> + <remarks> + <para> + This handler reloads the configuration from the file when the event is fired. + </para> + </remarks> + </member> + <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.OnWatchedFileChange(System.Object)"> + <summary> + Called by the timer when the configuration has been updated. + </summary> + <param name="state">null</param> + </member> + <member name="T:log4net.Core.CompactRepositorySelector"> + <summary> + The implementation of the <see cref="T:log4net.Core.IRepositorySelector"/> interface suitable + for use with the compact framework + </summary> + <remarks> + <para> + This <see cref="T:log4net.Core.IRepositorySelector"/> implementation is a simple + mapping between repository name and <see cref="T:log4net.Repository.ILoggerRepository"/> + object. + </para> + <para> + The .NET Compact Framework 1.0 does not support retrieving assembly + level attributes therefore unlike the <c>DefaultRepositorySelector</c> + this selector does not examine the calling assembly for attributes. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="T:log4net.Core.IRepositorySelector"> + <summary> + Interface used by the <see cref="T:log4net.LogManager"/> to select the <see cref="T:log4net.Repository.ILoggerRepository"/>. + </summary> + <remarks> + <para> + The <see cref="T:log4net.LogManager"/> uses a <see cref="T:log4net.Core.IRepositorySelector"/> + to specify the policy for selecting the correct <see cref="T:log4net.Repository.ILoggerRepository"/> + to return to the caller. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"> + <summary> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly. + </summary> + <param name="assembly">The assembly to use to lookup to the <see cref="T:log4net.Repository.ILoggerRepository"/></param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the assembly.</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly. + </para> + <para> + How the association between <see cref="T:System.Reflection.Assembly"/> and <see cref="T:log4net.Repository.ILoggerRepository"/> + is made is not defined. The implementation may choose any method for + this association. The results of this method must be repeatable, i.e. + when called again with the same arguments the result must be the + save value. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IRepositorySelector.GetRepository(System.String)"> + <summary> + Gets the named <see cref="T:log4net.Repository.ILoggerRepository"/>. + </summary> + <param name="repositoryName">The name to use to lookup to the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <returns>The named <see cref="T:log4net.Repository.ILoggerRepository"/></returns> + <remarks> + Lookup a named <see cref="T:log4net.Repository.ILoggerRepository"/>. This is the repository created by + calling <see cref="M:log4net.Core.IRepositorySelector.CreateRepository(System.String,System.Type)"/>. + </remarks> + </member> + <member name="M:log4net.Core.IRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)"> + <summary> + Creates a new repository for the assembly specified. + </summary> + <param name="assembly">The assembly to use to create the domain to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <returns>The repository created.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the domain + specified such that a call to <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + <para> + How the association between <see cref="T:System.Reflection.Assembly"/> and <see cref="T:log4net.Repository.ILoggerRepository"/> + is made is not defined. The implementation may choose any method for + this association. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IRepositorySelector.CreateRepository(System.String,System.Type)"> + <summary> + Creates a new repository with the name specified. + </summary> + <param name="repositoryName">The name to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <returns>The repository created.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the name + specified such that a call to <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.String)"/> with the + same name will return the same repository instance. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IRepositorySelector.ExistsRepository(System.String)"> + <summary> + Test if a named repository exists + </summary> + <param name="repositoryName">the named repository to check</param> + <returns><c>true</c> if the repository exists</returns> + <remarks> + <para> + Test if a named repository exists. Use <see cref="M:log4net.Core.IRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)"/> + to create a new repository and <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"/> to retrieve + a repository. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IRepositorySelector.GetAllRepositories"> + <summary> + Gets an array of all currently defined repositories. + </summary> + <returns> + An array of the <see cref="T:log4net.Repository.ILoggerRepository"/> instances created by + this <see cref="T:log4net.Core.IRepositorySelector"/>.</returns> + <remarks> + <para> + Gets an array of all of the repositories created by this selector. + </para> + </remarks> + </member> + <member name="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"> + <summary> + Event to notify that a logger repository has been created. + </summary> + <value> + Event to notify that a logger repository has been created. + </value> + <remarks> + <para> + Event raised when a new repository is created. + The event source will be this selector. The event args will + be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which + holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.#ctor(System.Type)"> + <summary> + Create a new repository selector + </summary> + <param name="defaultRepositoryType">the type of the repositories to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param> + <remarks> + <para> + Create an new compact repository selector. + The default type for repositories must be specified, + an appropriate value would be <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException">throw if <paramref name="defaultRepositoryType"/> is null</exception> + <exception cref="T:System.ArgumentOutOfRangeException">throw if <paramref name="defaultRepositoryType"/> does not implement <see cref="T:log4net.Repository.ILoggerRepository"/></exception> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.GetRepository(System.Reflection.Assembly)"> + <summary> + Get the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly + </summary> + <param name="assembly">not used</param> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/></returns> + <remarks> + <para> + The <paramref name="assembly"/> argument is not used. This selector does not create a + separate repository for each assembly. + </para> + <para> + As a named repository is not specified the default repository is + returned. The default repository is named <c>log4net-default-repository</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"> + <summary> + Get the named <see cref="T:log4net.Repository.ILoggerRepository"/> + </summary> + <param name="repositoryName">the name of the repository to lookup</param> + <returns>The named <see cref="T:log4net.Repository.ILoggerRepository"/></returns> + <remarks> + <para> + Get the named <see cref="T:log4net.Repository.ILoggerRepository"/>. The default + repository is <c>log4net-default-repository</c>. Other repositories + must be created using the <see cref="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"/>. + If the named repository does not exist an exception is thrown. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException">throw if <paramref name="repositoryName"/> is null</exception> + <exception cref="T:log4net.Core.LogException">throw if the <paramref name="repositoryName"/> does not exist</exception> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)"> + <summary> + Create a new repository for the assembly specified + </summary> + <param name="assembly">not used</param> + <param name="repositoryType">the type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param> + <returns>the repository created</returns> + <remarks> + <para> + The <paramref name="assembly"/> argument is not used. This selector does not create a + separate repository for each assembly. + </para> + <para> + If the <paramref name="repositoryType"/> is <c>null</c> then the + default repository type specified to the constructor is used. + </para> + <para> + As a named repository is not specified the default repository is + returned. The default repository is named <c>log4net-default-repository</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"> + <summary> + Create a new repository for the repository specified + </summary> + <param name="repositoryName">the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/></param> + <param name="repositoryType">the type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>. + If this param is null then the default repository type is used.</param> + <returns>the repository created</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"/> with the + same repository specified will return the same repository instance. + </para> + <para> + If the named repository already exists an exception will be thrown. + </para> + <para> + If <paramref name="repositoryType"/> is <c>null</c> then the default + repository type specified to the constructor is used. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException">throw if <paramref name="repositoryName"/> is null</exception> + <exception cref="T:log4net.Core.LogException">throw if the <paramref name="repositoryName"/> already exists</exception> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.ExistsRepository(System.String)"> + <summary> + Test if a named repository exists + </summary> + <param name="repositoryName">the named repository to check</param> + <returns><c>true</c> if the repository exists</returns> + <remarks> + <para> + Test if a named repository exists. Use <see cref="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"/> + to create a new repository and <see cref="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"/> to retrieve + a repository. + </para> + </remarks> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.GetAllRepositories"> + <summary> + Gets a list of <see cref="T:log4net.Repository.ILoggerRepository"/> objects + </summary> + <returns>an array of all known <see cref="T:log4net.Repository.ILoggerRepository"/> objects</returns> + <remarks> + <para> + Gets an array of all of the repositories created by this selector. + </para> + </remarks> + </member> + <member name="M:log4net.Core.CompactRepositorySelector.OnLoggerRepositoryCreatedEvent(log4net.Repository.ILoggerRepository)"> + <summary> + Notify the registered listeners that the repository has been created + </summary> + <param name="repository">The repository that has been created</param> + <remarks> + <para> + Raises the <event cref="E:log4net.Core.CompactRepositorySelector.LoggerRepositoryCreatedEvent">LoggerRepositoryCreatedEvent</event> + event. + </para> + </remarks> + </member> + <member name="E:log4net.Core.CompactRepositorySelector.LoggerRepositoryCreatedEvent"> + <summary> + Event to notify that a logger repository has been created. + </summary> + <value> + Event to notify that a logger repository has been created. + </value> + <remarks> + <para> + Event raised when a new repository is created. + The event source will be this selector. The event args will + be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which + holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Core.DefaultRepositorySelector"> + <summary> + The default implementation of the <see cref="T:log4net.Core.IRepositorySelector"/> interface. + </summary> + <remarks> + <para> + Uses attributes defined on the calling assembly to determine how to + configure the hierarchy for the repository. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.#ctor(System.Type)"> + <summary> + Creates a new repository selector. + </summary> + <param name="defaultRepositoryType">The type of the repositories to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param> + <remarks> + <para> + Create an new repository selector. + The default type for repositories must be specified, + an appropriate value would be <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException"><paramref name="defaultRepositoryType"/> is <see langword="null"/>.</exception> + <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="defaultRepositoryType"/> does not implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"> + <summary> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly. + </summary> + <param name="repositoryAssembly">The assembly use to lookup the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <remarks> + <para> + The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and the repository + to create can be overridden by specifying the <see cref="T:log4net.Config.RepositoryAttribute"/> + attribute on the <paramref name="repositoryAssembly"/>. + </para> + <para> + The default values are to use the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> + implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the + <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository. + </para> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically configured using + any <see cref="T:log4net.Config.ConfiguratorAttribute"/> attributes defined on + the <paramref name="repositoryAssembly"/>. + </para> + </remarks> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the assembly</returns> + <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"> + <summary> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified repository. + </summary> + <param name="repositoryName">The repository to use to lookup the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified repository.</returns> + <remarks> + <para> + Returns the named repository. If <paramref name="repositoryName"/> is <c>null</c> + a <see cref="T:System.ArgumentNullException"/> is thrown. If the repository + does not exist a <see cref="T:log4net.Core.LogException"/> is thrown. + </para> + <para> + Use <see cref="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"/> to create a repository. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException"><paramref name="repositoryName"/> is <see langword="null"/>.</exception> + <exception cref="T:log4net.Core.LogException"><paramref name="repositoryName"/> does not exist.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)"> + <summary> + Create a new repository for the assembly specified + </summary> + <param name="repositoryAssembly">the assembly to use to create the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <returns>The repository created.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + <para> + The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and + the repository to create can be overridden by specifying the + <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the + <paramref name="repositoryAssembly"/>. The default values are to use the + <paramref name="repositoryType"/> implementation of the + <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the + <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository. + </para> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically + configured using any <see cref="T:log4net.Config.ConfiguratorAttribute"/> + attributes defined on the <paramref name="repositoryAssembly"/>. + </para> + <para> + If a repository for the <paramref name="repositoryAssembly"/> already exists + that repository will be returned. An error will not be raised and that + repository may be of a different type to that specified in <paramref name="repositoryType"/>. + Also the <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the + assembly may be used to override the repository type specified in + <paramref name="repositoryType"/>. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type,System.String,System.Boolean)"> + <summary> + Creates a new repository for the assembly specified. + </summary> + <param name="repositoryAssembly">the assembly to use to create the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <param name="repositoryName">The name to assign to the created repository</param> + <param name="readAssemblyAttributes">Set to <c>true</c> to read and apply the assembly attributes</param> + <returns>The repository created.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + <para> + The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and + the repository to create can be overridden by specifying the + <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the + <paramref name="repositoryAssembly"/>. The default values are to use the + <paramref name="repositoryType"/> implementation of the + <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the + <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository. + </para> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically + configured using any <see cref="T:log4net.Config.ConfiguratorAttribute"/> + attributes defined on the <paramref name="repositoryAssembly"/>. + </para> + <para> + If a repository for the <paramref name="repositoryAssembly"/> already exists + that repository will be returned. An error will not be raised and that + repository may be of a different type to that specified in <paramref name="repositoryType"/>. + Also the <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the + assembly may be used to override the repository type specified in + <paramref name="repositoryType"/>. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"> + <summary> + Creates a new repository for the specified repository. + </summary> + <param name="repositoryName">The repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param> + <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>. + If this param is <see langword="null"/> then the default repository type is used.</param> + <returns>The new repository.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"/> with the + same repository specified will return the same repository instance. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException"><paramref name="repositoryName"/> is <see langword="null"/>.</exception> + <exception cref="T:log4net.Core.LogException"><paramref name="repositoryName"/> already exists.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.ExistsRepository(System.String)"> + <summary> + Test if a named repository exists + </summary> + <param name="repositoryName">the named repository to check</param> + <returns><c>true</c> if the repository exists</returns> + <remarks> + <para> + Test if a named repository exists. Use <see cref="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"/> + to create a new repository and <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"/> to retrieve + a repository. + </para> + </remarks> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.GetAllRepositories"> + <summary> + Gets a list of <see cref="T:log4net.Repository.ILoggerRepository"/> objects + </summary> + <returns>an array of all known <see cref="T:log4net.Repository.ILoggerRepository"/> objects</returns> + <remarks> + <para> + Gets an array of all of the repositories created by this selector. + </para> + </remarks> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.AliasRepository(System.String,log4net.Repository.ILoggerRepository)"> + <summary> + Aliases a repository to an existing repository. + </summary> + <param name="repositoryAlias">The repository to alias.</param> + <param name="repositoryTarget">The repository that the repository is aliased to.</param> + <remarks> + <para> + The repository specified will be aliased to the repository when created. + The repository must not already exist. + </para> + <para> + When the repository is created it must utilize the same repository type as + the repository it is aliased to, otherwise the aliasing will fail. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException"> + <para><paramref name="repositoryAlias"/> is <see langword="null"/>.</para> + <para>-or-</para> + <para><paramref name="repositoryTarget"/> is <see langword="null"/>.</para> + </exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.OnLoggerRepositoryCreatedEvent(log4net.Repository.ILoggerRepository)"> + <summary> + Notifies the registered listeners that the repository has been created. + </summary> + <param name="repository">The repository that has been created.</param> + <remarks> + <para> + Raises the <see cref="E:log4net.Core.DefaultRepositorySelector.LoggerRepositoryCreatedEvent"/> event. + </para> + </remarks> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.GetInfoForAssembly(System.Reflection.Assembly,System.String@,System.Type@)"> + <summary> + Gets the repository name and repository type for the specified assembly. + </summary> + <param name="assembly">The assembly that has a <see cref="T:log4net.Config.RepositoryAttribute"/>.</param> + <param name="repositoryName">in/out param to hold the repository name to use for the assembly, caller should set this to the default value before calling.</param> + <param name="repositoryType">in/out param to hold the type of the repository to create for the assembly, caller should set this to the default value before calling.</param> + <exception cref="T:System.ArgumentNullException"><paramref name="assembly"/> is <see langword="null"/>.</exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.ConfigureRepository(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Configures the repository using information from the assembly. + </summary> + <param name="assembly">The assembly containing <see cref="T:log4net.Config.ConfiguratorAttribute"/> + attributes which define the configuration for the repository.</param> + <param name="repository">The repository to configure.</param> + <exception cref="T:System.ArgumentNullException"> + <para><paramref name="assembly"/> is <see langword="null"/>.</para> + <para>-or-</para> + <para><paramref name="repository"/> is <see langword="null"/>.</para> + </exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.LoadPlugins(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Loads the attribute defined plugins on the assembly. + </summary> + <param name="assembly">The assembly that contains the attributes.</param> + <param name="repository">The repository to add the plugins to.</param> + <exception cref="T:System.ArgumentNullException"> + <para><paramref name="assembly"/> is <see langword="null"/>.</para> + <para>-or-</para> + <para><paramref name="repository"/> is <see langword="null"/>.</para> + </exception> + </member> + <member name="M:log4net.Core.DefaultRepositorySelector.LoadAliases(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)"> + <summary> + Loads the attribute defined aliases on the assembly. + </summary> + <param name="assembly">The assembly that contains the attributes.</param> + <param name="repository">The repository to alias to.</param> + <exception cref="T:System.ArgumentNullException"> + <para><paramref name="assembly"/> is <see langword="null"/>.</para> + <para>-or-</para> + <para><paramref name="repository"/> is <see langword="null"/>.</para> + </exception> + </member> + <member name="E:log4net.Core.DefaultRepositorySelector.LoggerRepositoryCreatedEvent"> + <summary> + Event to notify that a logger repository has been created. + </summary> + <value> + Event to notify that a logger repository has been created. + </value> + <remarks> + <para> + Event raised when a new repository is created. + The event source will be this selector. The event args will + be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which + holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Core.ErrorCode"> + <summary> + Defined error codes that can be passed to the <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/> method. + </summary> + <remarks> + <para> + Values passed to the <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/> method. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Core.ErrorCode.GenericFailure"> + <summary> + A general error + </summary> + </member> + <member name="F:log4net.Core.ErrorCode.WriteFailure"> + <summary> + Error while writing output + </summary> + </member> + <member name="F:log4net.Core.ErrorCode.FlushFailure"> + <summary> + Failed to flush file + </summary> + </member> + <member name="F:log4net.Core.ErrorCode.CloseFailure"> + <summary> + Failed to close file + </summary> + </member> + <member name="F:log4net.Core.ErrorCode.FileOpenFailure"> + <summary> + Unable to open output file + </summary> + </member> + <member name="F:log4net.Core.ErrorCode.MissingLayout"> + <summary> + No layout specified + </summary> + </member> + <member name="F:log4net.Core.ErrorCode.AddressParseFailure"> + <summary> + Failed to parse address + </summary> + </member> + <member name="T:log4net.Core.IErrorHandler"> + <summary> + Appenders may delegate their error handling to an <see cref="T:log4net.Core.IErrorHandler"/>. + </summary> + <remarks> + <para> + Error handling is a particularly tedious to get right because by + definition errors are hard to predict and to reproduce. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"> + <summary> + Handles the error and information about the error condition is passed as + a parameter. + </summary> + <param name="message">The message associated with the error.</param> + <param name="e">The <see cref="T:System.Exception"/> that was thrown when the error occurred.</param> + <param name="errorCode">The error code associated with the error.</param> + <remarks> + <para> + Handles the error and information about the error condition is passed as + a parameter. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception)"> + <summary> + Prints the error message passed as a parameter. + </summary> + <param name="message">The message associated with the error.</param> + <param name="e">The <see cref="T:System.Exception"/> that was thrown when the error occurred.</param> + <remarks> + <para> + See <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.IErrorHandler.Error(System.String)"> + <summary> + Prints the error message passed as a parameter. + </summary> + <param name="message">The message associated with the error.</param> + <remarks> + <para> + See <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Core.IFixingRequired"> + <summary> + Interface for objects that require fixing. + </summary> + <remarks> + <para> + Interface that indicates that the object requires fixing before it + can be taken outside the context of the appender's + <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method. + </para> + <para> + When objects that implement this interface are stored + in the context properties maps <see cref="T:log4net.GlobalContext"/> + <see cref="P:log4net.GlobalContext.Properties"/> and <see cref="T:log4net.ThreadContext"/> + <see cref="P:log4net.ThreadContext.Properties"/> are fixed + (see <see cref="P:log4net.Core.LoggingEvent.Fix"/>) the <see cref="M:log4net.Core.IFixingRequired.GetFixedObject"/> + method will be called. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Core.IFixingRequired.GetFixedObject"> + <summary> + Get a portable version of this object + </summary> + <returns>the portable instance of this object</returns> + <remarks> + <para> + Get a portable instance object that represents the current + state of this object. The portable object can be stored + and logged from any thread with identical results. + </para> + </remarks> + </member> + <member name="T:log4net.Core.ILogger"> + <summary> + Interface that all loggers implement + </summary> + <remarks> + <para> + This interface supports logging events and testing if a level + is enabled for logging. + </para> + <para> + These methods will not throw exceptions. Note to implementor, ensure + that the implementation of these methods cannot allow an exception + to be thrown to the caller. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.ILogger.Log(System.Type,log4net.Core.Level,System.Object,System.Exception)"> + <summary> + This generic form is intended to be used by wrappers. + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <param name="level">The level of the message to be logged.</param> + <param name="message">The message object to log.</param> + <param name="exception">the exception to log, including its stack trace. Pass <c>null</c> to not log an exception.</param> + <remarks> + <para> + Generates a logging event for the specified <paramref name="level"/> using + the <paramref name="message"/> and <paramref name="exception"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.ILogger.Log(log4net.Core.LoggingEvent)"> + <summary> + This is the most generic printing method that is intended to be used + by wrappers. + </summary> + <param name="logEvent">The event being logged.</param> + <remarks> + <para> + Logs the specified logging event through this logger. + </para> + </remarks> + </member> + <member name="M:log4net.Core.ILogger.IsEnabledFor(log4net.Core.Level)"> + <summary> + Checks if this logger is enabled for a given <see cref="T:log4net.Core.Level"/> passed as parameter. + </summary> + <param name="level">The level to check.</param> + <returns> + <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>. + </returns> + <remarks> + <para> + Test if this logger is going to log events of the specified <paramref name="level"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Core.ILogger.Name"> + <summary> + Gets the name of the logger. + </summary> + <value> + The name of the logger. + </value> + <remarks> + <para> + The name of this logger + </para> + </remarks> + </member> + <member name="P:log4net.Core.ILogger.Repository"> + <summary> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this + <c>Logger</c> instance is attached to. + </summary> + <value> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that this logger belongs to. + </value> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this + <c>Logger</c> instance is attached to. + </para> + </remarks> + </member> + <member name="T:log4net.Core.ILoggerWrapper"> + <summary> + Base interface for all wrappers + </summary> + <remarks> + <para> + Base interface for all wrappers. + </para> + <para> + All wrappers must implement this interface. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="P:log4net.Core.ILoggerWrapper.Logger"> + <summary> + Get the implementation behind this wrapper object. + </summary> + <value> + The <see cref="T:log4net.Core.ILogger"/> object that in implementing this object. + </value> + <remarks> + <para> + The <see cref="T:log4net.Core.ILogger"/> object that in implementing this + object. The <c>Logger</c> object may not + be the same object as this object because of logger decorators. + This gets the actual underlying objects that is used to process + the log events. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LoggerRepositoryCreationEventHandler"> + <summary> + Delegate used to handle logger repository creation event notifications + </summary> + <param name="sender">The <see cref="T:log4net.Core.IRepositorySelector"/> which created the repository.</param> + <param name="e">The <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> event args + that holds the <see cref="T:log4net.Repository.ILoggerRepository"/> instance that has been created.</param> + <remarks> + <para> + Delegate used to handle logger repository creation event notifications. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LoggerRepositoryCreationEventArgs"> + <summary> + Provides data for the <see cref="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"/> event. + </summary> + <remarks> + <para> + A <see cref="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"/> + event is raised every time a <see cref="T:log4net.Repository.ILoggerRepository"/> is created. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggerRepositoryCreationEventArgs.m_repository"> + <summary> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created + </summary> + </member> + <member name="M:log4net.Core.LoggerRepositoryCreationEventArgs.#ctor(log4net.Repository.ILoggerRepository)"> + <summary> + Construct instance using <see cref="T:log4net.Repository.ILoggerRepository"/> specified + </summary> + <param name="repository">the <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created</param> + <remarks> + <para> + Construct instance using <see cref="T:log4net.Repository.ILoggerRepository"/> specified + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggerRepositoryCreationEventArgs.LoggerRepository"> + <summary> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created + </summary> + <value> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created + </value> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created + </para> + </remarks> + </member> + <member name="T:log4net.Core.ITriggeringEventEvaluator"> + <summary> + Test if an <see cref="T:log4net.Core.LoggingEvent"/> triggers an action + </summary> + <remarks> + <para> + Implementations of this interface allow certain appenders to decide + when to perform an appender specific action. + </para> + <para> + The action or behavior triggered is defined by the implementation. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Core.ITriggeringEventEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"> + <summary> + Test if this event triggers the action + </summary> + <param name="loggingEvent">The event to check</param> + <returns><c>true</c> if this event triggers the action, otherwise <c>false</c></returns> + <remarks> + <para> + Return <c>true</c> if this event triggers the action + </para> + </remarks> + </member> + <member name="T:log4net.Core.Level"> + <summary> + Defines the default set of levels recognized by the system. + </summary> + <remarks> + <para> + Each <see cref="T:log4net.Core.LoggingEvent"/> has an associated <see cref="T:log4net.Core.Level"/>. + </para> + <para> + Levels have a numeric <see cref="P:log4net.Core.Level.Value"/> that defines the relative + ordering between levels. Two Levels with the same <see cref="P:log4net.Core.Level.Value"/> + are deemed to be equivalent. + </para> + <para> + The levels that are recognized by log4net are set for each <see cref="T:log4net.Repository.ILoggerRepository"/> + and each repository can have different levels defined. The levels are stored + in the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/> on the repository. Levels are + looked up by name from the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. + </para> + <para> + When logging at level INFO the actual level used is not <see cref="F:log4net.Core.Level.Info"/> but + the value of <c>LoggerRepository.LevelMap["INFO"]</c>. The default value for this is + <see cref="F:log4net.Core.Level.Info"/>, but this can be changed by reconfiguring the level map. + </para> + <para> + Each level has a <see cref="P:log4net.Core.Level.DisplayName"/> in addition to its <see cref="P:log4net.Core.Level.Name"/>. The + <see cref="P:log4net.Core.Level.DisplayName"/> is the string that is written into the output log. By default + the display name is the same as the level name, but this can be used to alias levels + or to localize the log output. + </para> + <para> + Some of the predefined levels recognized by the system are: + </para> + <list type="bullet"> + <item> + <description><see cref="F:log4net.Core.Level.Off"/>.</description> + </item> + <item> + <description><see cref="F:log4net.Core.Level.Fatal"/>.</description> + </item> + <item> + <description><see cref="F:log4net.Core.Level.Error"/>.</description> + </item> + <item> + <description><see cref="F:log4net.Core.Level.Warn"/>.</description> + </item> + <item> + <description><see cref="F:log4net.Core.Level.Info"/>.</description> + </item> + <item> + <description><see cref="F:log4net.Core.Level.Debug"/>.</description> + </item> + <item> + <description><see cref="F:log4net.Core.Level.All"/>.</description> + </item> + </list> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.Level.#ctor(System.Int32,System.String,System.String)"> + <summary> + Constructor + </summary> + <param name="level">Integer value for this level, higher values represent more severe levels.</param> + <param name="levelName">The string name of this level.</param> + <param name="displayName">The display name for this level. This may be localized or otherwise different from the name</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.Level"/> class with + the specified level name and value. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.#ctor(System.Int32,System.String)"> + <summary> + Constructor + </summary> + <param name="level">Integer value for this level, higher values represent more severe levels.</param> + <param name="levelName">The string name of this level.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.Level"/> class with + the specified level name and value. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.ToString"> + <summary> + Returns the <see cref="T:System.String"/> representation of the current + <see cref="T:log4net.Core.Level"/>. + </summary> + <returns> + A <see cref="T:System.String"/> representation of the current <see cref="T:log4net.Core.Level"/>. + </returns> + <remarks> + <para> + Returns the level <see cref="P:log4net.Core.Level.Name"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.Equals(System.Object)"> + <summary> + Compares levels. + </summary> + <param name="o">The object to compare against.</param> + <returns><c>true</c> if the objects are equal.</returns> + <remarks> + <para> + Compares the levels of <see cref="T:log4net.Core.Level"/> instances, and + defers to base class if the target object is not a <see cref="T:log4net.Core.Level"/> + instance. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.GetHashCode"> + <summary> + Returns a hash code + </summary> + <returns>A hash code for the current <see cref="T:log4net.Core.Level"/>.</returns> + <remarks> + <para> + Returns a hash code suitable for use in hashing algorithms and data + structures like a hash table. + </para> + <para> + Returns the hash code of the level <see cref="P:log4net.Core.Level.Value"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.CompareTo(System.Object)"> + <summary> + Compares this instance to a specified object and returns an + indication of their relative values. + </summary> + <param name="r">A <see cref="T:log4net.Core.Level"/> instance or <see langword="null"/> to compare with this instance.</param> + <returns> + A 32-bit signed integer that indicates the relative order of the + values compared. The return value has these meanings: + <list type="table"> + <listheader> + <term>Value</term> + <description>Meaning</description> + </listheader> + <item> + <term>Less than zero</term> + <description>This instance is less than <paramref name="r"/>.</description> + </item> + <item> + <term>Zero</term> + <description>This instance is equal to <paramref name="r"/>.</description> + </item> + <item> + <term>Greater than zero</term> + <description> + <para>This instance is greater than <paramref name="r"/>.</para> + <para>-or-</para> + <para><paramref name="r"/> is <see langword="null"/>.</para> + </description> + </item> + </list> + </returns> + <remarks> + <para> + <paramref name="r"/> must be an instance of <see cref="T:log4net.Core.Level"/> + or <see langword="null"/>; otherwise, an exception is thrown. + </para> + </remarks> + <exception cref="T:System.ArgumentException"><paramref name="r"/> is not a <see cref="T:log4net.Core.Level"/>.</exception> + </member> + <member name="M:log4net.Core.Level.op_GreaterThan(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/> + is greater than another specified <see cref="T:log4net.Core.Level"/>. + </summary> + <param name="l">A <see cref="T:log4net.Core.Level"/></param> + <param name="r">A <see cref="T:log4net.Core.Level"/></param> + <returns> + <c>true</c> if <paramref name="l"/> is greater than + <paramref name="r"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.op_LessThan(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/> + is less than another specified <see cref="T:log4net.Core.Level"/>. + </summary> + <param name="l">A <see cref="T:log4net.Core.Level"/></param> + <param name="r">A <see cref="T:log4net.Core.Level"/></param> + <returns> + <c>true</c> if <paramref name="l"/> is less than + <paramref name="r"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.op_GreaterThanOrEqual(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/> + is greater than or equal to another specified <see cref="T:log4net.Core.Level"/>. + </summary> + <param name="l">A <see cref="T:log4net.Core.Level"/></param> + <param name="r">A <see cref="T:log4net.Core.Level"/></param> + <returns> + <c>true</c> if <paramref name="l"/> is greater than or equal to + <paramref name="r"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.op_LessThanOrEqual(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/> + is less than or equal to another specified <see cref="T:log4net.Core.Level"/>. + </summary> + <param name="l">A <see cref="T:log4net.Core.Level"/></param> + <param name="r">A <see cref="T:log4net.Core.Level"/></param> + <returns> + <c>true</c> if <paramref name="l"/> is less than or equal to + <paramref name="r"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.op_Equality(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Returns a value indicating whether two specified <see cref="T:log4net.Core.Level"/> + objects have the same value. + </summary> + <param name="l">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param> + <param name="r">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param> + <returns> + <c>true</c> if the value of <paramref name="l"/> is the same as the + value of <paramref name="r"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.op_Inequality(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Returns a value indicating whether two specified <see cref="T:log4net.Core.Level"/> + objects have different values. + </summary> + <param name="l">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param> + <param name="r">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param> + <returns> + <c>true</c> if the value of <paramref name="l"/> is different from + the value of <paramref name="r"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="M:log4net.Core.Level.Compare(log4net.Core.Level,log4net.Core.Level)"> + <summary> + Compares two specified <see cref="T:log4net.Core.Level"/> instances. + </summary> + <param name="l">The first <see cref="T:log4net.Core.Level"/> to compare.</param> + <param name="r">The second <see cref="T:log4net.Core.Level"/> to compare.</param> + <returns> + A 32-bit signed integer that indicates the relative order of the + two values compared. The return value has these meanings: + <list type="table"> + <listheader> + <term>Value</term> + <description>Meaning</description> + </listheader> + <item> + <term>Less than zero</term> + <description><paramref name="l"/> is less than <paramref name="r"/>.</description> + </item> + <item> + <term>Zero</term> + <description><paramref name="l"/> is equal to <paramref name="r"/>.</description> + </item> + <item> + <term>Greater than zero</term> + <description><paramref name="l"/> is greater than <paramref name="r"/>.</description> + </item> + </list> + </returns> + <remarks> + <para> + Compares two levels. + </para> + </remarks> + </member> + <member name="F:log4net.Core.Level.Off"> + <summary> + The <see cref="F:log4net.Core.Level.Off"/> level designates a higher level than all the rest. + </summary> + </member> + <member name="F:log4net.Core.Level.Emergency"> + <summary> + The <see cref="F:log4net.Core.Level.Emergency"/> level designates very severe error events. + System unusable, emergencies. + </summary> + </member> + <member name="F:log4net.Core.Level.Fatal"> + <summary> + The <see cref="F:log4net.Core.Level.Fatal"/> level designates very severe error events + that will presumably lead the application to abort. + </summary> + </member> + <member name="F:log4net.Core.Level.Alert"> + <summary> + The <see cref="F:log4net.Core.Level.Alert"/> level designates very severe error events. + Take immediate action, alerts. + </summary> + </member> + <member name="F:log4net.Core.Level.Critical"> + <summary> + The <see cref="F:log4net.Core.Level.Critical"/> level designates very severe error events. + Critical condition, critical. + </summary> + </member> + <member name="F:log4net.Core.Level.Severe"> + <summary> + The <see cref="F:log4net.Core.Level.Severe"/> level designates very severe error events. + </summary> + </member> + <member name="F:log4net.Core.Level.Error"> + <summary> + The <see cref="F:log4net.Core.Level.Error"/> level designates error events that might + still allow the application to continue running. + </summary> + </member> + <member name="F:log4net.Core.Level.Warn"> + <summary> + The <see cref="F:log4net.Core.Level.Warn"/> level designates potentially harmful + situations. + </summary> + </member> + <member name="F:log4net.Core.Level.Notice"> + <summary> + The <see cref="F:log4net.Core.Level.Notice"/> level designates informational messages + that highlight the progress of the application at the highest level. + </summary> + </member> + <member name="F:log4net.Core.Level.Info"> + <summary> + The <see cref="F:log4net.Core.Level.Info"/> level designates informational messages that + highlight the progress of the application at coarse-grained level. + </summary> + </member> + <member name="F:log4net.Core.Level.Debug"> + <summary> + The <see cref="F:log4net.Core.Level.Debug"/> level designates fine-grained informational + events that are most useful to debug an application. + </summary> + </member> + <member name="F:log4net.Core.Level.Fine"> + <summary> + The <see cref="F:log4net.Core.Level.Fine"/> level designates fine-grained informational + events that are most useful to debug an application. + </summary> + </member> + <member name="F:log4net.Core.Level.Trace"> + <summary> + The <see cref="F:log4net.Core.Level.Trace"/> level designates fine-grained informational + events that are most useful to debug an application. + </summary> + </member> + <member name="F:log4net.Core.Level.Finer"> + <summary> + The <see cref="F:log4net.Core.Level.Finer"/> level designates fine-grained informational + events that are most useful to debug an application. + </summary> + </member> + <member name="F:log4net.Core.Level.Verbose"> + <summary> + The <see cref="F:log4net.Core.Level.Verbose"/> level designates fine-grained informational + events that are most useful to debug an application. + </summary> + </member> + <member name="F:log4net.Core.Level.Finest"> + <summary> + The <see cref="F:log4net.Core.Level.Finest"/> level designates fine-grained informational + events that are most useful to debug an application. + </summary> + </member> + <member name="F:log4net.Core.Level.All"> + <summary> + The <see cref="F:log4net.Core.Level.All"/> level designates the lowest level possible. + </summary> + </member> + <member name="P:log4net.Core.Level.Name"> + <summary> + Gets the name of this level. + </summary> + <value> + The name of this level. + </value> + <remarks> + <para> + Gets the name of this level. + </para> + </remarks> + </member> + <member name="P:log4net.Core.Level.Value"> + <summary> + Gets the value of this level. + </summary> + <value> + The value of this level. + </value> + <remarks> + <para> + Gets the value of this level. + </para> + </remarks> + </member> + <member name="P:log4net.Core.Level.DisplayName"> + <summary> + Gets the display name of this level. + </summary> + <value> + The display name of this level. + </value> + <remarks> + <para> + Gets the display name of this level. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LevelCollection"> + <summary> + A strongly-typed collection of <see cref="T:log4net.Core.Level"/> objects. + </summary> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Core.LevelCollection.ReadOnly(log4net.Core.LevelCollection)"> + <summary> + Creates a read-only wrapper for a <c>LevelCollection</c> instance. + </summary> + <param name="list">list to create a readonly wrapper arround</param> + <returns> + A <c>LevelCollection</c> wrapper that is read-only. + </returns> + </member> + <member name="M:log4net.Core.LevelCollection.#ctor"> + <summary> + Initializes a new instance of the <c>LevelCollection</c> class + that is empty and has the default initial capacity. + </summary> + </member> + <member name="M:log4net.Core.LevelCollection.#ctor(System.Int32)"> + <summary> + Initializes a new instance of the <c>LevelCollection</c> class + that has the specified initial capacity. + </summary> + <param name="capacity"> + The number of elements that the new <c>LevelCollection</c> is initially capable of storing. + </param> + </member> + <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.LevelCollection)"> + <summary> + Initializes a new instance of the <c>LevelCollection</c> class + that contains elements copied from the specified <c>LevelCollection</c>. + </summary> + <param name="c">The <c>LevelCollection</c> whose elements are copied to the new collection.</param> + </member> + <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.Level[])"> + <summary> + Initializes a new instance of the <c>LevelCollection</c> class + that contains elements copied from the specified <see cref="T:log4net.Core.Level"/> array. + </summary> + <param name="a">The <see cref="T:log4net.Core.Level"/> array whose elements are copied to the new list.</param> + </member> + <member name="M:log4net.Core.LevelCollection.#ctor(System.Collections.ICollection)"> + <summary> + Initializes a new instance of the <c>LevelCollection</c> class + that contains elements copied from the specified <see cref="T:log4net.Core.Level"/> collection. + </summary> + <param name="col">The <see cref="T:log4net.Core.Level"/> collection whose elements are copied to the new list.</param> + </member> + <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.LevelCollection.Tag)"> + <summary> + Allow subclasses to avoid our default constructors + </summary> + <param name="tag"></param> + </member> + <member name="M:log4net.Core.LevelCollection.CopyTo(log4net.Core.Level[])"> + <summary> + Copies the entire <c>LevelCollection</c> to a one-dimensional + <see cref="T:log4net.Core.Level"/> array. + </summary> + <param name="array">The one-dimensional <see cref="T:log4net.Core.Level"/> array to copy to.</param> + </member> + <member name="M:log4net.Core.LevelCollection.CopyTo(log4net.Core.Level[],System.Int32)"> + <summary> + Copies the entire <c>LevelCollection</c> to a one-dimensional + <see cref="T:log4net.Core.Level"/> array, starting at the specified index of the target array. + </summary> + <param name="array">The one-dimensional <see cref="T:log4net.Core.Level"/> array to copy to.</param> + <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param> + </member> + <member name="M:log4net.Core.LevelCollection.Add(log4net.Core.Level)"> + <summary> + Adds a <see cref="T:log4net.Core.Level"/> to the end of the <c>LevelCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Core.Level"/> to be added to the end of the <c>LevelCollection</c>.</param> + <returns>The index at which the value has been added.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.Clear"> + <summary> + Removes all elements from the <c>LevelCollection</c>. + </summary> + </member> + <member name="M:log4net.Core.LevelCollection.Clone"> + <summary> + Creates a shallow copy of the <see cref="T:log4net.Core.LevelCollection"/>. + </summary> + <returns>A new <see cref="T:log4net.Core.LevelCollection"/> with a shallow copy of the collection data.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.Contains(log4net.Core.Level)"> + <summary> + Determines whether a given <see cref="T:log4net.Core.Level"/> is in the <c>LevelCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Core.Level"/> to check for.</param> + <returns><c>true</c> if <paramref name="item"/> is found in the <c>LevelCollection</c>; otherwise, <c>false</c>.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.IndexOf(log4net.Core.Level)"> + <summary> + Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Core.Level"/> + in the <c>LevelCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Core.Level"/> to locate in the <c>LevelCollection</c>.</param> + <returns> + The zero-based index of the first occurrence of <paramref name="item"/> + in the entire <c>LevelCollection</c>, if found; otherwise, -1. + </returns> + </member> + <member name="M:log4net.Core.LevelCollection.Insert(System.Int32,log4net.Core.Level)"> + <summary> + Inserts an element into the <c>LevelCollection</c> at the specified index. + </summary> + <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param> + <param name="item">The <see cref="T:log4net.Core.Level"/> to insert.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Core.LevelCollection.Remove(log4net.Core.Level)"> + <summary> + Removes the first occurrence of a specific <see cref="T:log4net.Core.Level"/> from the <c>LevelCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Core.Level"/> to remove from the <c>LevelCollection</c>.</param> + <exception cref="T:System.ArgumentException"> + The specified <see cref="T:log4net.Core.Level"/> was not found in the <c>LevelCollection</c>. + </exception> + </member> + <member name="M:log4net.Core.LevelCollection.RemoveAt(System.Int32)"> + <summary> + Removes the element at the specified index of the <c>LevelCollection</c>. + </summary> + <param name="index">The zero-based index of the element to remove.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Core.LevelCollection.GetEnumerator"> + <summary> + Returns an enumerator that can iterate through the <c>LevelCollection</c>. + </summary> + <returns>An <see cref="T:log4net.Core.LevelCollection.Enumerator"/> for the entire <c>LevelCollection</c>.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.AddRange(log4net.Core.LevelCollection)"> + <summary> + Adds the elements of another <c>LevelCollection</c> to the current <c>LevelCollection</c>. + </summary> + <param name="x">The <c>LevelCollection</c> whose elements should be added to the end of the current <c>LevelCollection</c>.</param> + <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.AddRange(log4net.Core.Level[])"> + <summary> + Adds the elements of a <see cref="T:log4net.Core.Level"/> array to the current <c>LevelCollection</c>. + </summary> + <param name="x">The <see cref="T:log4net.Core.Level"/> array whose elements should be added to the end of the <c>LevelCollection</c>.</param> + <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.AddRange(System.Collections.ICollection)"> + <summary> + Adds the elements of a <see cref="T:log4net.Core.Level"/> collection to the current <c>LevelCollection</c>. + </summary> + <param name="col">The <see cref="T:log4net.Core.Level"/> collection whose elements should be added to the end of the <c>LevelCollection</c>.</param> + <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns> + </member> + <member name="M:log4net.Core.LevelCollection.TrimToSize"> + <summary> + Sets the capacity to the actual number of elements. + </summary> + </member> + <member name="M:log4net.Core.LevelCollection.ValidateIndex(System.Int32)"> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Core.LevelCollection.ValidateIndex(System.Int32,System.Boolean)"> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para> + </exception> + </member> + <member name="P:log4net.Core.LevelCollection.Count"> + <summary> + Gets the number of elements actually contained in the <c>LevelCollection</c>. + </summary> + </member> + <member name="P:log4net.Core.LevelCollection.IsSynchronized"> + <summary> + Gets a value indicating whether access to the collection is synchronized (thread-safe). + </summary> + <value>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</value> + </member> + <member name="P:log4net.Core.LevelCollection.SyncRoot"> + <summary> + Gets an object that can be used to synchronize access to the collection. + </summary> + </member> + <member name="P:log4net.Core.LevelCollection.Item(System.Int32)"> + <summary> + Gets or sets the <see cref="T:log4net.Core.Level"/> at the specified index. + </summary> + <param name="index">The zero-based index of the element to get or set.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para> + </exception> + </member> + <member name="P:log4net.Core.LevelCollection.IsFixedSize"> + <summary> + Gets a value indicating whether the collection has a fixed size. + </summary> + <value>true if the collection has a fixed size; otherwise, false. The default is false</value> + </member> + <member name="P:log4net.Core.LevelCollection.IsReadOnly"> + <summary> + Gets a value indicating whether the IList is read-only. + </summary> + <value>true if the collection is read-only; otherwise, false. The default is false</value> + </member> + <member name="P:log4net.Core.LevelCollection.Capacity"> + <summary> + Gets or sets the number of elements the <c>LevelCollection</c> can contain. + </summary> + </member> + <member name="T:log4net.Core.LevelCollection.ILevelCollectionEnumerator"> + <summary> + Supports type-safe iteration over a <see cref="T:log4net.Core.LevelCollection"/>. + </summary> + </member> + <member name="M:log4net.Core.LevelCollection.ILevelCollectionEnumerator.MoveNext"> + <summary> + Advances the enumerator to the next element in the collection. + </summary> + <returns> + <c>true</c> if the enumerator was successfully advanced to the next element; + <c>false</c> if the enumerator has passed the end of the collection. + </returns> + <exception cref="T:System.InvalidOperationException"> + The collection was modified after the enumerator was created. + </exception> + </member> + <member name="M:log4net.Core.LevelCollection.ILevelCollectionEnumerator.Reset"> + <summary> + Sets the enumerator to its initial position, before the first element in the collection. + </summary> + </member> + <member name="P:log4net.Core.LevelCollection.ILevelCollectionEnumerator.Current"> + <summary> + Gets the current element in the collection. + </summary> + </member> + <member name="T:log4net.Core.LevelCollection.Tag"> + <summary> + Type visible only to our subclasses + Used to access protected constructor + </summary> + </member> + <member name="F:log4net.Core.LevelCollection.Tag.Default"> + <summary> + A value + </summary> + </member> + <member name="T:log4net.Core.LevelCollection.Enumerator"> + <summary> + Supports simple iteration over a <see cref="T:log4net.Core.LevelCollection"/>. + </summary> + </member> + <member name="M:log4net.Core.LevelCollection.Enumerator.#ctor(log4net.Core.LevelCollection)"> + <summary> + Initializes a new instance of the <c>Enumerator</c> class. + </summary> + <param name="tc"></param> + </member> + <member name="M:log4net.Core.LevelCollection.Enumerator.MoveNext"> + <summary> + Advances the enumerator to the next element in the collection. + </summary> + <returns> + <c>true</c> if the enumerator was successfully advanced to the next element; + <c>false</c> if the enumerator has passed the end of the collection. + </returns> + <exception cref="T:System.InvalidOperationException"> + The collection was modified after the enumerator was created. + </exception> + </member> + <member name="M:log4net.Core.LevelCollection.Enumerator.Reset"> + <summary> + Sets the enumerator to its initial position, before the first element in the collection. + </summary> + </member> + <member name="P:log4net.Core.LevelCollection.Enumerator.Current"> + <summary> + Gets the current element in the collection. + </summary> + </member> + <member name="T:log4net.Core.LevelEvaluator"> + <summary> + An evaluator that triggers at a threshold level + </summary> + <remarks> + <para> + This evaluator will trigger if the level of the event + passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/> + is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/> + level. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Core.LevelEvaluator.m_threshold"> + <summary> + The threshold for triggering + </summary> + </member> + <member name="M:log4net.Core.LevelEvaluator.#ctor"> + <summary> + Create a new evaluator using the <see cref="F:log4net.Core.Level.Off"/> threshold. + </summary> + <remarks> + <para> + Create a new evaluator using the <see cref="F:log4net.Core.Level.Off"/> threshold. + </para> + <para> + This evaluator will trigger if the level of the event + passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/> + is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/> + level. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LevelEvaluator.#ctor(log4net.Core.Level)"> + <summary> + Create a new evaluator using the specified <see cref="T:log4net.Core.Level"/> threshold. + </summary> + <param name="threshold">the threshold to trigger at</param> + <remarks> + <para> + Create a new evaluator using the specified <see cref="T:log4net.Core.Level"/> threshold. + </para> + <para> + This evaluator will trigger if the level of the event + passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/> + is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/> + level. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"> + <summary> + Is this <paramref name="loggingEvent"/> the triggering event? + </summary> + <param name="loggingEvent">The event to check</param> + <returns>This method returns <c>true</c>, if the event level + is equal or higher than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>. + Otherwise it returns <c>false</c></returns> + <remarks> + <para> + This evaluator will trigger if the level of the event + passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/> + is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/> + level. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LevelEvaluator.Threshold"> + <summary> + the threshold to trigger at + </summary> + <value> + The <see cref="T:log4net.Core.Level"/> that will cause this evaluator to trigger + </value> + <remarks> + <para> + This evaluator will trigger if the level of the event + passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/> + is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/> + level. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LevelMap"> + <summary> + Mapping between string name and Level object + </summary> + <remarks> + <para> + Mapping between string name and <see cref="T:log4net.Core.Level"/> object. + This mapping is held separately for each <see cref="T:log4net.Repository.ILoggerRepository"/>. + The level name is case insensitive. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Core.LevelMap.m_mapName2Level"> + <summary> + Mapping from level name to Level object. The + level name is case insensitive + </summary> + </member> + <member name="M:log4net.Core.LevelMap.#ctor"> + <summary> + Construct the level map + </summary> + <remarks> + <para> + Construct the level map. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LevelMap.Clear"> + <summary> + Clear the internal maps of all levels + </summary> + <remarks> + <para> + Clear the internal maps of all levels + </para> + </remarks> + </member> + <member name="M:log4net.Core.LevelMap.Add(System.String,System.Int32)"> + <summary> + Create a new Level and add it to the map + </summary> + <param name="name">the string to display for the Level</param> + <param name="value">the level value to give to the Level</param> + <remarks> + <para> + Create a new Level and add it to the map + </para> + </remarks> + <seealso cref="M:log4net.Core.LevelMap.Add(System.String,System.Int32,System.String)"/> + </member> + <member name="M:log4net.Core.LevelMap.Add(System.String,System.Int32,System.String)"> + <summary> + Create a new Level and add it to the map + </summary> + <param name="name">the string to display for the Level</param> + <param name="value">the level value to give to the Level</param> + <param name="displayName">the display name to give to the Level</param> + <remarks> + <para> + Create a new Level and add it to the map + </para> + </remarks> + </member> + <member name="M:log4net.Core.LevelMap.Add(log4net.Core.Level)"> + <summary> + Add a Level to the map + </summary> + <param name="level">the Level to add</param> + <remarks> + <para> + Add a Level to the map + </para> + </remarks> + </member> + <member name="M:log4net.Core.LevelMap.LookupWithDefault(log4net.Core.Level)"> + <summary> + Lookup a named level from the map + </summary> + <param name="defaultLevel">the name of the level to lookup is taken from this level. + If the level is not set on the map then this level is added</param> + <returns>the level in the map with the name specified</returns> + <remarks> + <para> + Lookup a named level from the map. The name of the level to lookup is taken + from the <see cref="P:log4net.Core.Level.Name"/> property of the <paramref name="defaultLevel"/> + argument. + </para> + <para> + If no level with the specified name is found then the + <paramref name="defaultLevel"/> argument is added to the level map + and returned. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LevelMap.Item(System.String)"> + <summary> + Lookup a <see cref="T:log4net.Core.Level"/> by name + </summary> + <param name="name">The name of the Level to lookup</param> + <returns>a Level from the map with the name specified</returns> + <remarks> + <para> + Returns the <see cref="T:log4net.Core.Level"/> from the + map with the name specified. If the no level is + found then <c>null</c> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LevelMap.AllLevels"> + <summary> + Return all possible levels as a list of Level objects. + </summary> + <returns>all possible levels as a list of Level objects</returns> + <remarks> + <para> + Return all possible levels as a list of Level objects. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LocationInfo"> + <summary> + The internal representation of caller location information. + </summary> + <remarks> + <para> + This class uses the <c>System.Diagnostics.StackTrace</c> class to generate + a call stack. The caller's information is then extracted from this stack. + </para> + <para> + The <c>System.Diagnostics.StackTrace</c> class is not supported on the + .NET Compact Framework 1.0 therefore caller location information is not + available on that framework. + </para> + <para> + The <c>System.Diagnostics.StackTrace</c> class has this to say about Release builds: + </para> + <para> + "StackTrace information will be most informative with Debug build configurations. + By default, Debug builds include debug symbols, while Release builds do not. The + debug symbols contain most of the file, method name, line number, and column + information used in constructing StackFrame and StackTrace objects. StackTrace + might not report as many method calls as expected, due to code transformations + that occur during optimization." + </para> + <para> + This means that in a Release build the caller information may be incomplete or may + not exist at all! Therefore caller location information cannot be relied upon in a Release build. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Core.LocationInfo.NA"> + <summary> + When location information is not available the constant + <c>NA</c> is returned. Current value of this string + constant is <b>?</b>. + </summary> + </member> + <member name="M:log4net.Core.LocationInfo.#ctor(System.Type)"> + <summary> + Constructor + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LocationInfo"/> + class based on the current thread. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LocationInfo.#ctor(System.String,System.String,System.String,System.String)"> + <summary> + Constructor + </summary> + <param name="className">The fully qualified class name.</param> + <param name="methodName">The method name.</param> + <param name="fileName">The file name.</param> + <param name="lineNumber">The line number of the method within the file.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LocationInfo"/> + class with the specified data. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LocationInfo.ClassName"> + <summary> + Gets the fully qualified class name of the caller making the logging + request. + </summary> + <value> + The fully qualified class name of the caller making the logging + request. + </value> + <remarks> + <para> + Gets the fully qualified class name of the caller making the logging + request. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LocationInfo.FileName"> + <summary> + Gets the file name of the caller. + </summary> + <value> + The file name of the caller. + </value> + <remarks> + <para> + Gets the file name of the caller. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LocationInfo.LineNumber"> + <summary> + Gets the line number of the caller. + </summary> + <value> + The line number of the caller. + </value> + <remarks> + <para> + Gets the line number of the caller. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LocationInfo.MethodName"> + <summary> + Gets the method name of the caller. + </summary> + <value> + The method name of the caller. + </value> + <remarks> + <para> + Gets the method name of the caller. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LocationInfo.FullInfo"> + <summary> + Gets all available caller information + </summary> + <value> + All available caller information, in the format + <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c> + </value> + <remarks> + <para> + Gets all available caller information, in the format + <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c> + </para> + </remarks> + </member> + <member name="T:log4net.Core.LoggerManager"> + <summary> + Static manager that controls the creation of repositories + </summary> + <remarks> + <para> + Static manager that controls the creation of repositories + </para> + <para> + This class is used by the wrapper managers (e.g. <see cref="T:log4net.LogManager"/>) + to provide access to the <see cref="T:log4net.Core.ILogger"/> objects. + </para> + <para> + This manager also holds the <see cref="T:log4net.Core.IRepositorySelector"/> that is used to + lookup and create repositories. The selector can be set either programmatically using + the <see cref="P:log4net.Core.LoggerManager.RepositorySelector"/> property, or by setting the <c>log4net.RepositorySelector</c> + AppSetting in the applications config file to the fully qualified type name of the + selector to use. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.LoggerManager.#ctor"> + <summary> + Private constructor to prevent instances. Only static methods should be used. + </summary> + <remarks> + <para> + Private constructor to prevent instances. Only static methods should be used. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.#cctor"> + <summary> + Hook the shutdown event + </summary> + <remarks> + <para> + On the full .NET runtime, the static constructor hooks up the + <c>AppDomain.ProcessExit</c> and <c>AppDomain.DomainUnload</c>> events. + These are used to shutdown the log4net system as the application exits. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.RegisterAppDomainEvents"> + <summary> + Register for ProcessExit and DomainUnload events on the AppDomain + </summary> + <remarks> + <para> + This needs to be in a separate method because the events make + a LinkDemand for the ControlAppDomain SecurityPermission. Because + this is a LinkDemand it is demanded at JIT time. Therefore we cannot + catch the exception in the method itself, we have to catch it in the + caller. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetLoggerRepository(System.String)"> + <summary> + Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <param name="repository">the repository to lookup in</param> + <returns>Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the <paramref name="repository"/> argument. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetLoggerRepository(System.Reflection.Assembly)"> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns> + </member> + <member name="M:log4net.Core.LoggerManager.GetRepository(System.String)"> + <summary> + Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <param name="repository">the repository to lookup in</param> + <returns>Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the <paramref name="repository"/> argument. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns> + <remarks> + <para> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.Exists(System.String,System.String)"> + <summary> + Returns the named logger if it exists. + </summary> + <param name="repository">The repository to lookup in.</param> + <param name="name">The fully qualified logger name to look for.</param> + <returns> + The logger found, or <c>null</c> if the named logger does not exist in the + specified repository. + </returns> + <remarks> + <para> + If the named logger exists (in the specified repository) then it + returns a reference to the logger, otherwise it returns + <c>null</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.Exists(System.Reflection.Assembly,System.String)"> + <summary> + Returns the named logger if it exists. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <param name="name">The fully qualified logger name to look for.</param> + <returns> + The logger found, or <c>null</c> if the named logger does not exist in the + specified assembly's repository. + </returns> + <remarks> + <para> + If the named logger exists (in the specified assembly's repository) then it + returns a reference to the logger, otherwise it returns + <c>null</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetCurrentLoggers(System.String)"> + <summary> + Returns all the currently defined loggers in the specified repository. + </summary> + <param name="repository">The repository to lookup in.</param> + <returns>All the defined loggers.</returns> + <remarks> + <para> + The root logger is <b>not</b> included in the returned array. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetCurrentLoggers(System.Reflection.Assembly)"> + <summary> + Returns all the currently defined loggers in the specified assembly's repository. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <returns>All the defined loggers.</returns> + <remarks> + <para> + The root logger is <b>not</b> included in the returned array. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetLogger(System.String,System.String)"> + <summary> + Retrieves or creates a named logger. + </summary> + <param name="repository">The repository to lookup in.</param> + <param name="name">The name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + <remarks> + <para> + Retrieves a logger named as the <paramref name="name"/> + parameter. If the named logger already exists, then the + existing instance will be returned. Otherwise, a new instance is + created. + </para> + <para> + By default, loggers do not have a set level but inherit + it from the hierarchy. This is one of the central features of + log4net. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetLogger(System.Reflection.Assembly,System.String)"> + <summary> + Retrieves or creates a named logger. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <param name="name">The name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + <remarks> + <para> + Retrieves a logger named as the <paramref name="name"/> + parameter. If the named logger already exists, then the + existing instance will be returned. Otherwise, a new instance is + created. + </para> + <para> + By default, loggers do not have a set level but inherit + it from the hierarchy. This is one of the central features of + log4net. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetLogger(System.String,System.Type)"> + <summary> + Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>. + </summary> + <param name="repository">The repository to lookup in.</param> + <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + <remarks> + <para> + Gets the logger for the fully qualified name of the type specified. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetLogger(System.Reflection.Assembly,System.Type)"> + <summary> + Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>. + </summary> + <param name="repositoryAssembly">the assembly to use to lookup the repository</param> + <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + <remarks> + <para> + Gets the logger for the fully qualified name of the type specified. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.Shutdown"> + <summary> + Shuts down the log4net system. + </summary> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in all the + default repositories. + </para> + <para> + Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para> + The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.ShutdownRepository(System.String)"> + <summary> + Shuts down the repository for the repository specified. + </summary> + <param name="repository">The repository to shutdown.</param> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in the + repository for the <paramref name="repository"/> specified. + </para> + <para> + Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para> + The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.ShutdownRepository(System.Reflection.Assembly)"> + <summary> + Shuts down the repository for the repository specified. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in the + repository for the repository. The repository is looked up using + the <paramref name="repositoryAssembly"/> specified. + </para> + <para> + Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para> + The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.ResetConfiguration(System.String)"> + <summary> + Resets all values contained in this repository instance to their defaults. + </summary> + <param name="repository">The repository to reset.</param> + <remarks> + <para> + Resets all values contained in the repository instance to their + defaults. This removes all appenders from all loggers, sets + the level of all non-root loggers to <c>null</c>, + sets their additivity flag to <c>true</c> and sets the level + of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover, + message disabling is set its default "off" value. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.ResetConfiguration(System.Reflection.Assembly)"> + <summary> + Resets all values contained in this repository instance to their defaults. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param> + <remarks> + <para> + Resets all values contained in the repository instance to their + defaults. This removes all appenders from all loggers, sets + the level of all non-root loggers to <c>null</c>, + sets their additivity flag to <c>true</c> and sets the level + of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover, + message disabling is set its default "off" value. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.CreateDomain(System.String)"> + <summary> + Creates a repository with the specified name. + </summary> + <param name="repository">The name of the repository, this must be unique amongst repositories.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a + <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object. + </para> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An <see cref="T:System.Exception"/> will be thrown if the repository already exists. + </para> + </remarks> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.Core.LoggerManager.CreateRepository(System.String)"> + <summary> + Creates a repository with the specified name. + </summary> + <param name="repository">The name of the repository, this must be unique amongst repositories.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a + <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object. + </para> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An <see cref="T:System.Exception"/> will be thrown if the repository already exists. + </para> + </remarks> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.Core.LoggerManager.CreateDomain(System.String,System.Type)"> + <summary> + Creates a repository with the specified name and repository type. + </summary> + <param name="repository">The name of the repository, this must be unique to the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An Exception will be thrown if the repository already exists. + </para> + </remarks> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.Core.LoggerManager.CreateRepository(System.String,System.Type)"> + <summary> + Creates a repository with the specified name and repository type. + </summary> + <param name="repository">The name of the repository, this must be unique to the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An Exception will be thrown if the repository already exists. + </para> + </remarks> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.Core.LoggerManager.CreateDomain(System.Reflection.Assembly,System.Type)"> + <summary> + Creates a repository for the specified assembly and repository type. + </summary> + <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.CreateRepository(System.Reflection.Assembly,System.Type)"> + <summary> + Creates a repository for the specified assembly and repository type. + </summary> + <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetAllRepositories"> + <summary> + Gets an array of all currently defined repositories. + </summary> + <returns>An array of all the known <see cref="T:log4net.Repository.ILoggerRepository"/> objects.</returns> + <remarks> + <para> + Gets an array of all currently defined repositories. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.GetVersionInfo"> + <summary> + Internal method to get pertinent version info. + </summary> + <returns>A string of version info.</returns> + </member> + <member name="M:log4net.Core.LoggerManager.OnDomainUnload(System.Object,System.EventArgs)"> + <summary> + Called when the <see cref="E:System.AppDomain.DomainUnload"/> event fires + </summary> + <param name="sender">the <see cref="T:System.AppDomain"/> that is exiting</param> + <param name="e">null</param> + <remarks> + <para> + Called when the <see cref="E:System.AppDomain.DomainUnload"/> event fires. + </para> + <para> + When the event is triggered the log4net system is <see cref="M:log4net.Core.LoggerManager.Shutdown"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggerManager.OnProcessExit(System.Object,System.EventArgs)"> + <summary> + Called when the <see cref="E:System.AppDomain.ProcessExit"/> event fires + </summary> + <param name="sender">the <see cref="T:System.AppDomain"/> that is exiting</param> + <param name="e">null</param> + <remarks> + <para> + Called when the <see cref="E:System.AppDomain.ProcessExit"/> event fires. + </para> + <para> + When the event is triggered the log4net system is <see cref="M:log4net.Core.LoggerManager.Shutdown"/>. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggerManager.s_repositorySelector"> + <summary> + Initialize the default repository selector + </summary> + </member> + <member name="P:log4net.Core.LoggerManager.RepositorySelector"> + <summary> + Gets or sets the repository selector used by the <see cref="T:log4net.LogManager"/>. + </summary> + <value> + The repository selector used by the <see cref="T:log4net.LogManager"/>. + </value> + <remarks> + <para> + The repository selector (<see cref="T:log4net.Core.IRepositorySelector"/>) is used by + the <see cref="T:log4net.LogManager"/> to create and select repositories + (<see cref="T:log4net.Repository.ILoggerRepository"/>). + </para> + <para> + The caller to <see cref="T:log4net.LogManager"/> supplies either a string name + or an assembly (if not supplied the assembly is inferred using + <see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>). + </para> + <para> + This context is used by the selector to lookup a specific repository. + </para> + <para> + For the full .NET Framework, the default repository is <c>DefaultRepositorySelector</c>; + for the .NET Compact Framework <c>CompactRepositorySelector</c> is the default + repository. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LoggerWrapperImpl"> + <summary> + Implementation of the <see cref="T:log4net.Core.ILoggerWrapper"/> interface. + </summary> + <remarks> + <para> + This class should be used as the base for all wrapper implementations. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.LoggerWrapperImpl.#ctor(log4net.Core.ILogger)"> + <summary> + Constructs a new wrapper for the specified logger. + </summary> + <param name="logger">The logger to wrap.</param> + <remarks> + <para> + Constructs a new wrapper for the specified logger. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggerWrapperImpl.m_logger"> + <summary> + The logger that this object is wrapping + </summary> + </member> + <member name="P:log4net.Core.LoggerWrapperImpl.Logger"> + <summary> + Gets the implementation behind this wrapper object. + </summary> + <value> + The <see cref="T:log4net.Core.ILogger"/> object that this object is implementing. + </value> + <remarks> + <para> + The <c>Logger</c> object may not be the same object as this object + because of logger decorators. + </para> + <para> + This gets the actual underlying objects that is used to process + the log events. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LoggingEventData"> + <summary> + Portable data structure used by <see cref="T:log4net.Core.LoggingEvent"/> + </summary> + <remarks> + <para> + Portable data structure used by <see cref="T:log4net.Core.LoggingEvent"/> + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Core.LoggingEventData.LoggerName"> + <summary> + The logger name. + </summary> + <remarks> + <para> + The logger name. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.Level"> + <summary> + Level of logging event. + </summary> + <remarks> + <para> + Level of logging event. Level cannot be Serializable + because it is a flyweight. Due to its special serialization it + cannot be declared final either. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.Message"> + <summary> + The application supplied message. + </summary> + <remarks> + <para> + The application supplied message of logging event. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.ThreadName"> + <summary> + The name of thread + </summary> + <remarks> + <para> + The name of thread in which this logging event was generated + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.TimeStamp"> + <summary> + The time the event was logged + </summary> + <remarks> + <para> + The TimeStamp is stored in the local time zone for this computer. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.LocationInfo"> + <summary> + Location information for the caller. + </summary> + <remarks> + <para> + Location information for the caller. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.UserName"> + <summary> + String representation of the user + </summary> + <remarks> + <para> + String representation of the user's windows name, + like DOMAIN\username + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.Identity"> + <summary> + String representation of the identity. + </summary> + <remarks> + <para> + String representation of the current thread's principal identity. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.ExceptionString"> + <summary> + The string representation of the exception + </summary> + <remarks> + <para> + The string representation of the exception + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.Domain"> + <summary> + String representation of the AppDomain. + </summary> + <remarks> + <para> + String representation of the AppDomain. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEventData.Properties"> + <summary> + Additional event specific properties + </summary> + <remarks> + <para> + A logger or an appender may attach additional + properties to specific events. These properties + have a string key and an object value. + </para> + </remarks> + </member> + <member name="T:log4net.Core.FixFlags"> + <summary> + Flags passed to the <see cref="P:log4net.Core.LoggingEvent.Fix"/> property + </summary> + <remarks> + <para> + Flags passed to the <see cref="P:log4net.Core.LoggingEvent.Fix"/> property + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Core.FixFlags.Mdc"> + <summary> + Fix the MDC + </summary> + </member> + <member name="F:log4net.Core.FixFlags.Ndc"> + <summary> + Fix the NDC + </summary> + </member> + <member name="F:log4net.Core.FixFlags.Message"> + <summary> + Fix the rendered message + </summary> + </member> + <member name="F:log4net.Core.FixFlags.ThreadName"> + <summary> + Fix the thread name + </summary> + </member> + <member name="F:log4net.Core.FixFlags.LocationInfo"> + <summary> + Fix the callers location information + </summary> + <remarks> + CAUTION: Very slow to generate + </remarks> + </member> + <member name="F:log4net.Core.FixFlags.UserName"> + <summary> + Fix the callers windows user name + </summary> + <remarks> + CAUTION: Slow to generate + </remarks> + </member> + <member name="F:log4net.Core.FixFlags.Domain"> + <summary> + Fix the domain friendly name + </summary> + </member> + <member name="F:log4net.Core.FixFlags.Identity"> + <summary> + Fix the callers principal name + </summary> + <remarks> + CAUTION: May be slow to generate + </remarks> + </member> + <member name="F:log4net.Core.FixFlags.Exception"> + <summary> + Fix the exception text + </summary> + </member> + <member name="F:log4net.Core.FixFlags.Properties"> + <summary> + Fix the event properties + </summary> + </member> + <member name="F:log4net.Core.FixFlags.None"> + <summary> + No fields fixed + </summary> + </member> + <member name="F:log4net.Core.FixFlags.All"> + <summary> + All fields fixed + </summary> + </member> + <member name="F:log4net.Core.FixFlags.Partial"> + <summary> + Partial fields fixed + </summary> + <remarks> + <para> + This set of partial fields gives good performance. The following fields are fixed: + </para> + <list type="bullet"> + <item><description><see cref="F:log4net.Core.FixFlags.Message"/></description></item> + <item><description><see cref="F:log4net.Core.FixFlags.ThreadName"/></description></item> + <item><description><see cref="F:log4net.Core.FixFlags.Exception"/></description></item> + <item><description><see cref="F:log4net.Core.FixFlags.Domain"/></description></item> + <item><description><see cref="F:log4net.Core.FixFlags.Properties"/></description></item> + </list> + </remarks> + </member> + <member name="T:log4net.Core.LoggingEvent"> + <summary> + The internal representation of logging events. + </summary> + <remarks> + <para> + When an affirmative decision is made to log then a + <see cref="T:log4net.Core.LoggingEvent"/> instance is created. This instance + is passed around to the different log4net components. + </para> + <para> + This class is of concern to those wishing to extend log4net. + </para> + <para> + Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/> + are considered volatile, that is the values are correct at the + time the event is delivered to appenders, but will not be consistent + at any time afterwards. If an event is to be stored and then processed + at a later time these volatile values must be fixed by calling + <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty + for incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it + is essential to maintaining data consistency. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Douglas de la Torre</author> + <author>Daniel Cazzulino</author> + </member> + <member name="F:log4net.Core.LoggingEvent.HostNameProperty"> + <summary> + The key into the Properties map for the host name value. + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.IdentityProperty"> + <summary> + The key into the Properties map for the thread identity value. + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.UserNameProperty"> + <summary> + The key into the Properties map for the user name value. + </summary> + </member> + <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,System.String,log4net.Core.Level,System.Object,System.Exception)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class + from the supplied parameters. + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <param name="repository">The repository this event is logged in.</param> + <param name="loggerName">The name of the logger of this event.</param> + <param name="level">The level of this event.</param> + <param name="message">The message of this event.</param> + <param name="exception">The exception for this event.</param> + <remarks> + <para> + Except <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>, <see cref="P:log4net.Core.LoggingEvent.Level"/> and <see cref="P:log4net.Core.LoggingEvent.LoggerName"/>, + all fields of <c>LoggingEvent</c> are filled when actually needed. Call + <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> to cache all data locally + to prevent inconsistencies. + </para> + <para>This method is called by the log4net framework + to create a logging event. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,log4net.Core.LoggingEventData,log4net.Core.FixFlags)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class + using specific data. + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <param name="repository">The repository this event is logged in.</param> + <param name="data">Data used to initialize the logging event.</param> + <param name="fixedData">The fields in the <paranref name="data"/> struct that have already been fixed.</param> + <remarks> + <para> + This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/> + to be created independently of the log4net framework. This can + be useful if you require a custom serialization scheme. + </para> + <para> + Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an + instance of the <see cref="T:log4net.Core.LoggingEventData"/> class. + </para> + <para> + The <paramref name="fixedData"/> parameter should be used to specify which fields in the + <paramref name="data"/> struct have been preset. Fields not specified in the <paramref name="fixedData"/> + will be captured from the environment if requested or fixed. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,log4net.Core.LoggingEventData)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class + using specific data. + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <param name="repository">The repository this event is logged in.</param> + <param name="data">Data used to initialize the logging event.</param> + <remarks> + <para> + This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/> + to be created independently of the log4net framework. This can + be useful if you require a custom serialization scheme. + </para> + <para> + Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an + instance of the <see cref="T:log4net.Core.LoggingEventData"/> class. + </para> + <para> + This constructor sets this objects <see cref="P:log4net.Core.LoggingEvent.Fix"/> flags to <see cref="F:log4net.Core.FixFlags.All"/>, + this assumes that all the data relating to this event is passed in via the <paramref name="data"/> + parameter and no other data should be captured from the environment. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.#ctor(log4net.Core.LoggingEventData)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class + using specific data. + </summary> + <param name="data">Data used to initialize the logging event.</param> + <remarks> + <para> + This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/> + to be created independently of the log4net framework. This can + be useful if you require a custom serialization scheme. + </para> + <para> + Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an + instance of the <see cref="T:log4net.Core.LoggingEventData"/> class. + </para> + <para> + This constructor sets this objects <see cref="P:log4net.Core.LoggingEvent.Fix"/> flags to <see cref="F:log4net.Core.FixFlags.All"/>, + this assumes that all the data relating to this event is passed in via the <paramref name="data"/> + parameter and no other data should be captured from the environment. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Serialization constructor + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param> + <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class + with serialized data. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.EnsureRepository(log4net.Repository.ILoggerRepository)"> + <summary> + Ensure that the repository is set. + </summary> + <param name="repository">the value for the repository</param> + </member> + <member name="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"> + <summary> + Write the rendered message to a TextWriter + </summary> + <param name="writer">the writer to write the message to</param> + <remarks> + <para> + Unlike the <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property this method + does store the message data in the internal cache. Therefore + if called only once this method should be faster than the + <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property, however if the message is + to be accessed multiple times then the property will be more efficient. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided. + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param> + <param name="context">The destination for this serialization.</param> + <remarks> + <para> + The data in this event must be fixed before it can be serialized. + </para> + <para> + The <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> method must be called during the + <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method call if this event + is to be used outside that method. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.GetLoggingEventData"> + <summary> + Gets the portable data for this <see cref="T:log4net.Core.LoggingEvent"/>. + </summary> + <returns>The <see cref="T:log4net.Core.LoggingEventData"/> for this event.</returns> + <remarks> + <para> + A new <see cref="T:log4net.Core.LoggingEvent"/> can be constructed using a + <see cref="T:log4net.Core.LoggingEventData"/> instance. + </para> + <para> + Does a <see cref="F:log4net.Core.FixFlags.Partial"/> fix of the data + in the logging event before returning the event data. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"> + <summary> + Gets the portable data for this <see cref="T:log4net.Core.LoggingEvent"/>. + </summary> + <param name="fixFlags">The set of data to ensure is fixed in the LoggingEventData</param> + <returns>The <see cref="T:log4net.Core.LoggingEventData"/> for this event.</returns> + <remarks> + <para> + A new <see cref="T:log4net.Core.LoggingEvent"/> can be constructed using a + <see cref="T:log4net.Core.LoggingEventData"/> instance. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.GetExceptionStrRep"> + <summary> + Returns this event's exception's rendered using the + <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </summary> + <returns> + This event's exception's rendered using the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </returns> + <remarks> + <para> + <b>Obsolete. Use <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/> instead.</b> + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.GetExceptionString"> + <summary> + Returns this event's exception's rendered using the + <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </summary> + <returns> + This event's exception's rendered using the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </returns> + <remarks> + <para> + Returns this event's exception's rendered using the + <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.FixVolatileData"> + <summary> + Fix instance fields that hold volatile data. + </summary> + <remarks> + <para> + Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/> + are considered volatile, that is the values are correct at the + time the event is delivered to appenders, but will not be consistent + at any time afterwards. If an event is to be stored and then processed + at a later time these volatile values must be fixed by calling + <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty + incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it + is essential to maintaining data consistency. + </para> + <para> + Calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> is equivalent to + calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> passing the parameter + <c>false</c>. + </para> + <para> + See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> for more + information. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"> + <summary> + Fixes instance fields that hold volatile data. + </summary> + <param name="fastButLoose">Set to <c>true</c> to not fix data that takes a long time to fix.</param> + <remarks> + <para> + Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/> + are considered volatile, that is the values are correct at the + time the event is delivered to appenders, but will not be consistent + at any time afterwards. If an event is to be stored and then processed + at a later time these volatile values must be fixed by calling + <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty + for incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it + is essential to maintaining data consistency. + </para> + <para> + The <paramref name="fastButLoose"/> param controls the data that + is fixed. Some of the data that can be fixed takes a long time to + generate, therefore if you do not require those settings to be fixed + they can be ignored by setting the <paramref name="fastButLoose"/> param + to <c>true</c>. This setting will ignore the <see cref="P:log4net.Core.LoggingEvent.LocationInformation"/> + and <see cref="P:log4net.Core.LoggingEvent.UserName"/> settings. + </para> + <para> + Set <paramref name="fastButLoose"/> to <c>false</c> to ensure that all + settings are fixed. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"> + <summary> + Fix the fields specified by the <see cref="T:log4net.Core.FixFlags"/> parameter + </summary> + <param name="flags">the fields to fix</param> + <remarks> + <para> + Only fields specified in the <paramref name="flags"/> will be fixed. + Fields will not be fixed if they have previously been fixed. + It is not possible to 'unfix' a field. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"> + <summary> + Lookup a composite property in this event + </summary> + <param name="key">the key for the property to lookup</param> + <returns>the value for the property</returns> + <remarks> + <para> + This event has composite properties that combine together properties from + several different contexts in the following order: + <list type="definition"> + <item> + <term>this events properties</term> + <description> + This event has <see cref="P:log4net.Core.LoggingEvent.Properties"/> that can be set. These + properties are specific to this event only. + </description> + </item> + <item> + <term>the thread properties</term> + <description> + The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current + thread. These properties are shared by all events logged on this thread. + </description> + </item> + <item> + <term>the global properties</term> + <description> + The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These + properties are shared by all the threads in the AppDomain. + </description> + </item> + </list> + </para> + </remarks> + </member> + <member name="M:log4net.Core.LoggingEvent.GetProperties"> + <summary> + Get all the composite properties in this event + </summary> + <returns>the <see cref="T:log4net.Util.PropertiesDictionary"/> containing all the properties</returns> + <remarks> + <para> + See <see cref="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"/> for details of the composite properties + stored by the event. + </para> + <para> + This method returns a single <see cref="T:log4net.Util.PropertiesDictionary"/> containing all the + properties defined for this event. + </para> + </remarks> + </member> + <member name="F:log4net.Core.LoggingEvent.m_data"> + <summary> + The internal logging event data. + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.m_compositeProperties"> + <summary> + The internal logging event data. + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.m_eventProperties"> + <summary> + The internal logging event data. + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.m_callerStackBoundaryDeclaringType"> + <summary> + The fully qualified Type of the calling + logger class in the stack frame (i.e. the declaring type of the method). + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.m_message"> + <summary> + The application supplied message of logging event. + </summary> + </member> + <member name="F:log4net.Core.LoggingEvent.m_thrownException"> + <summary> + The exception that was thrown. + </summary> + <remarks> + This is not serialized. The string representation + is serialized instead. + </remarks> + </member> + <member name="F:log4net.Core.LoggingEvent.m_repository"> + <summary> + The repository that generated the logging event + </summary> + <remarks> + This is not serialized. + </remarks> + </member> + <member name="F:log4net.Core.LoggingEvent.m_fixFlags"> + <summary> + The fix state for this event + </summary> + <remarks> + These flags indicate which fields have been fixed. + Not serialized. + </remarks> + </member> + <member name="F:log4net.Core.LoggingEvent.m_cacheUpdatable"> + <summary> + Indicated that the internal cache is updateable (ie not fixed) + </summary> + <remarks> + This is a seperate flag to m_fixFlags as it allows incrementel fixing and simpler + changes in the caching strategy. + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.StartTime"> + <summary> + Gets the time when the current process started. + </summary> + <value> + This is the time when this process started. + </value> + <remarks> + <para> + The TimeStamp is stored in the local time zone for this computer. + </para> + <para> + Tries to get the start time for the current process. + Failing that it returns the time of the first call to + this property. + </para> + <para> + Note that AppDomains may be loaded and unloaded within the + same process without the process terminating and therefore + without the process start time being reset. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.Level"> + <summary> + Gets the <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event. + </summary> + <value> + The <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event. + </value> + <remarks> + <para> + Gets the <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.TimeStamp"> + <summary> + Gets the time of the logging event. + </summary> + <value> + The time of the logging event. + </value> + <remarks> + <para> + The TimeStamp is stored in the local time zone for this computer. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.LoggerName"> + <summary> + Gets the name of the logger that logged the event. + </summary> + <value> + The name of the logger that logged the event. + </value> + <remarks> + <para> + Gets the name of the logger that logged the event. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.LocationInformation"> + <summary> + Gets the location information for this logging event. + </summary> + <value> + The location information for this logging event. + </value> + <remarks> + <para> + The collected information is cached for future use. + </para> + <para> + See the <see cref="T:log4net.Core.LocationInfo"/> class for more information on + supported frameworks and the different behavior in Debug and + Release builds. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.MessageObject"> + <summary> + Gets the message object used to initialize this event. + </summary> + <value> + The message object used to initialize this event. + </value> + <remarks> + <para> + Gets the message object used to initialize this event. + Note that this event may not have a valid message object. + If the event is serialized the message object will not + be transferred. To get the text of the message the + <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property must be used + not this property. + </para> + <para> + If there is no defined message object for this event then + null will be returned. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.ExceptionObject"> + <summary> + Gets the exception object used to initialize this event. + </summary> + <value> + The exception object used to initialize this event. + </value> + <remarks> + <para> + Gets the exception object used to initialize this event. + Note that this event may not have a valid exception object. + If the event is serialized the exception object will not + be transferred. To get the text of the exception the + <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/> method must be used + not this property. + </para> + <para> + If there is no defined exception object for this event then + null will be returned. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.Repository"> + <summary> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that this event was created in. + </summary> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that this event was created in. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.RenderedMessage"> + <summary> + Gets the message, rendered through the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </summary> + <value> + The message rendered through the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>. + </value> + <remarks> + <para> + The collected information is cached for future use. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.ThreadName"> + <summary> + Gets the name of the current thread. + </summary> + <value> + The name of the current thread, or the thread ID when + the name is not available. + </value> + <remarks> + <para> + The collected information is cached for future use. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.UserName"> + <summary> + Gets the name of the current user. + </summary> + <value> + The name of the current user, or <c>NOT AVAILABLE</c> when the + underlying runtime has no support for retrieving the name of the + current user. + </value> + <remarks> + <para> + Calls <c>WindowsIdentity.GetCurrent().Name</c> to get the name of + the current windows user. + </para> + <para> + To improve performance, we could cache the string representation of + the name, and reuse that as long as the identity stayed constant. + Once the identity changed, we would need to re-assign and re-render + the string. + </para> + <para> + However, the <c>WindowsIdentity.GetCurrent()</c> call seems to + return different objects every time, so the current implementation + doesn't do this type of caching. + </para> + <para> + Timing for these operations: + </para> + <list type="table"> + <listheader> + <term>Method</term> + <description>Results</description> + </listheader> + <item> + <term><c>WindowsIdentity.GetCurrent()</c></term> + <description>10000 loops, 00:00:00.2031250 seconds</description> + </item> + <item> + <term><c>WindowsIdentity.GetCurrent().Name</c></term> + <description>10000 loops, 00:00:08.0468750 seconds</description> + </item> + </list> + <para> + This means we could speed things up almost 40 times by caching the + value of the <c>WindowsIdentity.GetCurrent().Name</c> property, since + this takes (8.04-0.20) = 7.84375 seconds. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.Identity"> + <summary> + Gets the identity of the current thread principal. + </summary> + <value> + The string name of the identity of the current thread principal. + </value> + <remarks> + <para> + Calls <c>System.Threading.Thread.CurrentPrincipal.Identity.Name</c> to get + the name of the current thread principal. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.Domain"> + <summary> + Gets the AppDomain friendly name. + </summary> + <value> + The AppDomain friendly name. + </value> + <remarks> + <para> + Gets the AppDomain friendly name. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.Properties"> + <summary> + Additional event specific properties. + </summary> + <value> + Additional event specific properties. + </value> + <remarks> + <para> + A logger or an appender may attach additional + properties to specific events. These properties + have a string key and an object value. + </para> + <para> + This property is for events that have been added directly to + this event. The aggregate properties (which include these + event properties) can be retrieved using <see cref="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"/> + and <see cref="M:log4net.Core.LoggingEvent.GetProperties"/>. + </para> + <para> + Once the properties have been fixed <see cref="P:log4net.Core.LoggingEvent.Fix"/> this property + returns the combined cached properties. This ensures that updates to + this property are always reflected in the underlying storage. When + returning the combined properties there may be more keys in the + Dictionary than expected. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LoggingEvent.Fix"> + <summary> + The fixed fields in this event + </summary> + <value> + The set of fields that are fixed in this event + </value> + <remarks> + <para> + Fields will not be fixed if they have previously been fixed. + It is not possible to 'unfix' a field. + </para> + </remarks> + </member> + <member name="T:log4net.Core.LogImpl"> + <summary> + Implementation of <see cref="T:log4net.ILog"/> wrapper interface. + </summary> + <remarks> + <para> + This implementation of the <see cref="T:log4net.ILog"/> interface + forwards to the <see cref="T:log4net.Core.ILogger"/> held by the base class. + </para> + <para> + This logger has methods to allow the caller to log at the following + levels: + </para> + <list type="definition"> + <item> + <term>DEBUG</term> + <description> + The <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object[])"/> methods log messages + at the <c>DEBUG</c> level. That is the level with that name defined in the + repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value + for this level is <see cref="F:log4net.Core.Level.Debug"/>. The <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> + property tests if this level is enabled for logging. + </description> + </item> + <item> + <term>INFO</term> + <description> + The <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object[])"/> methods log messages + at the <c>INFO</c> level. That is the level with that name defined in the + repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value + for this level is <see cref="F:log4net.Core.Level.Info"/>. The <see cref="P:log4net.Core.LogImpl.IsInfoEnabled"/> + property tests if this level is enabled for logging. + </description> + </item> + <item> + <term>WARN</term> + <description> + The <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object[])"/> methods log messages + at the <c>WARN</c> level. That is the level with that name defined in the + repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value + for this level is <see cref="F:log4net.Core.Level.Warn"/>. The <see cref="P:log4net.Core.LogImpl.IsWarnEnabled"/> + property tests if this level is enabled for logging. + </description> + </item> + <item> + <term>ERROR</term> + <description> + The <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object[])"/> methods log messages + at the <c>ERROR</c> level. That is the level with that name defined in the + repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value + for this level is <see cref="F:log4net.Core.Level.Error"/>. The <see cref="P:log4net.Core.LogImpl.IsErrorEnabled"/> + property tests if this level is enabled for logging. + </description> + </item> + <item> + <term>FATAL</term> + <description> + The <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object[])"/> methods log messages + at the <c>FATAL</c> level. That is the level with that name defined in the + repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value + for this level is <see cref="F:log4net.Core.Level.Fatal"/>. The <see cref="P:log4net.Core.LogImpl.IsFatalEnabled"/> + property tests if this level is enabled for logging. + </description> + </item> + </list> + <para> + The values for these levels and their semantic meanings can be changed by + configuring the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/> for the repository. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.ILog"> + <summary> + The ILog interface is use by application to log messages into + the log4net framework. + </summary> + <remarks> + <para> + Use the <see cref="T:log4net.LogManager"/> to obtain logger instances + that implement this interface. The <see cref="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"/> + static method is used to get logger instances. + </para> + <para> + This class contains methods for logging at different levels and also + has properties for determining if those logging levels are + enabled in the current configuration. + </para> + <para> + This interface can be implemented in different ways. This documentation + specifies reasonable behavior that a caller can expect from the actual + implementation, however different implementations reserve the right to + do things differently. + </para> + </remarks> + <example>Simple example of logging messages + <code lang="C#"> + ILog log = LogManager.GetLogger("application-log"); + + log.Info("Application Start"); + log.Debug("This is a debug message"); + + if (log.IsDebugEnabled) + { + log.Debug("This is another debug message"); + } + </code> + </example> + <seealso cref="T:log4net.LogManager"/> + <seealso cref="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.ILog.Debug(System.Object)"> + <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level.</overloads> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <param name="message">The message object to log.</param> + <remarks> + <para> + This method first checks if this logger is <c>DEBUG</c> + enabled by comparing the level of this logger with the + <see cref="F:log4net.Core.Level.Debug"/> level. If this logger is + <c>DEBUG</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of + the additivity flag. + </para> + <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.Debug(System.Object,System.Exception)"> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level including + the stack trace of the <see cref="T:System.Exception"/> passed + as a parameter. + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + See the <see cref="M:log4net.ILog.Debug(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.DebugFormat(System.String,System.Object[])"> + <overloads>Log a formatted string with the <see cref="F:log4net.Core.Level.Debug"/> level.</overloads> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.DebugFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.DebugFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.DebugFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.DebugFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.ILog.Info(System.Object)"> + <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Info"/> level.</overloads> + <summary> + Logs a message object with the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <remarks> + <para> + This method first checks if this logger is <c>INFO</c> + enabled by comparing the level of this logger with the + <see cref="F:log4net.Core.Level.Info"/> level. If this logger is + <c>INFO</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + <param name="message">The message object to log.</param> + <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.Info(System.Object,System.Exception)"> + <summary> + Logs a message object with the <c>INFO</c> level including + the stack trace of the <see cref="T:System.Exception"/> passed + as a parameter. + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + See the <see cref="M:log4net.ILog.Info(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.InfoFormat(System.String,System.Object[])"> + <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.</overloads> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.InfoFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.InfoFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.InfoFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.InfoFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsInfoEnabled"/> + </member> + <member name="M:log4net.ILog.Warn(System.Object)"> + <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level.</overloads> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <remarks> + <para> + This method first checks if this logger is <c>WARN</c> + enabled by comparing the level of this logger with the + <see cref="F:log4net.Core.Level.Warn"/> level. If this logger is + <c>WARN</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + <param name="message">The message object to log.</param> + <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.Warn(System.Object,System.Exception)"> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level including + the stack trace of the <see cref="T:System.Exception"/> passed + as a parameter. + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + See the <see cref="M:log4net.ILog.Warn(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.WarnFormat(System.String,System.Object[])"> + <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.</overloads> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.WarnFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.WarnFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.WarnFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.WarnFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsWarnEnabled"/> + </member> + <member name="M:log4net.ILog.Error(System.Object)"> + <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Error"/> level.</overloads> + <summary> + Logs a message object with the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <param name="message">The message object to log.</param> + <remarks> + <para> + This method first checks if this logger is <c>ERROR</c> + enabled by comparing the level of this logger with the + <see cref="F:log4net.Core.Level.Error"/> level. If this logger is + <c>ERROR</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.Error(System.Object,System.Exception)"> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Error"/> level including + the stack trace of the <see cref="T:System.Exception"/> passed + as a parameter. + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + See the <see cref="M:log4net.ILog.Error(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object[])"> + <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.</overloads> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsErrorEnabled"/> + </member> + <member name="M:log4net.ILog.Fatal(System.Object)"> + <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level.</overloads> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <remarks> + <para> + This method first checks if this logger is <c>FATAL</c> + enabled by comparing the level of this logger with the + <see cref="F:log4net.Core.Level.Fatal"/> level. If this logger is + <c>FATAL</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + <param name="message">The message object to log.</param> + <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="M:log4net.ILog.Fatal(System.Object,System.Exception)"> + <summary> + Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level including + the stack trace of the <see cref="T:System.Exception"/> passed + as a parameter. + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + See the <see cref="M:log4net.ILog.Fatal(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="M:log4net.ILog.FatalFormat(System.String,System.Object[])"> + <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.</overloads> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="M:log4net.ILog.FatalFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="M:log4net.ILog.FatalFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="M:log4net.ILog.FatalFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="M:log4net.ILog.FatalFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <c>String.Format</c> method. See + <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> + <seealso cref="P:log4net.ILog.IsFatalEnabled"/> + </member> + <member name="P:log4net.ILog.IsDebugEnabled"> + <summary> + Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Debug"/> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Debug"/> events, <c>false</c> otherwise. + </value> + <remarks> + <para> + This function is intended to lessen the computational cost of + disabled log debug statements. + </para> + <para> For some ILog interface <c>log</c>, when you write:</para> + <code lang="C#"> + log.Debug("This is entry number: " + i ); + </code> + <para> + You incur the cost constructing the message, string construction and concatenation in + this case, regardless of whether the message is logged or not. + </para> + <para> + If you are worried about speed (who isn't), then you should write: + </para> + <code lang="C#"> + if (log.IsDebugEnabled) + { + log.Debug("This is entry number: " + i ); + } + </code> + <para> + This way you will not incur the cost of parameter + construction if debugging is disabled for <c>log</c>. On + the other hand, if the <c>log</c> is debug enabled, you + will incur the cost of evaluating whether the logger is debug + enabled twice. Once in <see cref="P:log4net.ILog.IsDebugEnabled"/> and once in + the <see cref="M:log4net.ILog.Debug(System.Object)"/>. This is an insignificant overhead + since evaluating a logger takes about 1% of the time it + takes to actually log. This is the preferred style of logging. + </para> + <para>Alternatively if your logger is available statically then the is debug + enabled state can be stored in a static variable like this: + </para> + <code lang="C#"> + private static readonly bool isDebugEnabled = log.IsDebugEnabled; + </code> + <para> + Then when you come to log you can write: + </para> + <code lang="C#"> + if (isDebugEnabled) + { + log.Debug("This is entry number: " + i ); + } + </code> + <para> + This way the debug enabled state is only queried once + when the class is loaded. Using a <c>private static readonly</c> + variable is the most efficient because it is a run time constant + and can be heavily optimized by the JIT compiler. + </para> + <para> + Of course if you use a static readonly variable to + hold the enabled state of the logger then you cannot + change the enabled state at runtime to vary the logging + that is produced. You have to decide if you need absolute + speed or runtime flexibility. + </para> + </remarks> + <seealso cref="M:log4net.ILog.Debug(System.Object)"/> + <seealso cref="M:log4net.ILog.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> + </member> + <member name="P:log4net.ILog.IsInfoEnabled"> + <summary> + Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Info"/> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Info"/> events, <c>false</c> otherwise. + </value> + <remarks> + For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>. + </remarks> + <seealso cref="M:log4net.ILog.Info(System.Object)"/> + <seealso cref="M:log4net.ILog.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="P:log4net.ILog.IsWarnEnabled"> + <summary> + Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Warn"/> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Warn"/> events, <c>false</c> otherwise. + </value> + <remarks> + For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>. + </remarks> + <seealso cref="M:log4net.ILog.Warn(System.Object)"/> + <seealso cref="M:log4net.ILog.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="P:log4net.ILog.IsErrorEnabled"> + <summary> + Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Error"/> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Error"/> events, <c>false</c> otherwise. + </value> + <remarks> + For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>. + </remarks> + <seealso cref="M:log4net.ILog.Error(System.Object)"/> + <seealso cref="M:log4net.ILog.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="P:log4net.ILog.IsFatalEnabled"> + <summary> + Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Fatal"/> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Fatal"/> events, <c>false</c> otherwise. + </value> + <remarks> + For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>. + </remarks> + <seealso cref="M:log4net.ILog.Fatal(System.Object)"/> + <seealso cref="M:log4net.ILog.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="M:log4net.Core.LogImpl.#ctor(log4net.Core.ILogger)"> + <summary> + Construct a new wrapper for the specified logger. + </summary> + <param name="logger">The logger to wrap.</param> + <remarks> + <para> + Construct a new wrapper for the specified logger. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.ReloadLevels(log4net.Repository.ILoggerRepository)"> + <summary> + Virtual method called when the configuration of the repository changes + </summary> + <param name="repository">the repository holding the levels</param> + <remarks> + <para> + Virtual method called when the configuration of the repository changes + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Debug(System.Object)"> + <summary> + Logs a message object with the <c>DEBUG</c> level. + </summary> + <param name="message">The message object to log.</param> + <remarks> + <para> + This method first checks if this logger is <c>DEBUG</c> + enabled by comparing the level of this logger with the + <c>DEBUG</c> level. If this logger is + <c>DEBUG</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para> + <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.Core.LogImpl.Debug(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Debug(System.Object,System.Exception)"> + <summary> + Logs a message object with the <c>DEBUG</c> level + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Logs a message object with the <c>DEBUG</c> level including + the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> passed + as a parameter. + </para> + <para> + See the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> + </member> + <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>DEBUG</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <c>DEBUG</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>DEBUG</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>DEBUG</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>DEBUG</c> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Info(System.Object)"> + <summary> + Logs a message object with the <c>INFO</c> level. + </summary> + <param name="message">The message object to log.</param> + <remarks> + <para> + This method first checks if this logger is <c>INFO</c> + enabled by comparing the level of this logger with the + <c>INFO</c> level. If this logger is + <c>INFO</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger + and also higher in the hierarchy depending on the value of + the additivity flag. + </para> + <para> + <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> + to this method will print the name of the <see cref="T:System.Exception"/> + but no stack trace. To print a stack trace use the + <see cref="M:log4net.Core.LogImpl.Info(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Info(System.Object,System.Exception)"> + <summary> + Logs a message object with the <c>INFO</c> level. + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Logs a message object with the <c>INFO</c> level including + the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> + passed as a parameter. + </para> + <para> + See the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.Core.LogImpl.Info(System.Object)"/> + </member> + <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>INFO</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <c>INFO</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>INFO</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>INFO</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>INFO</c> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Warn(System.Object)"> + <summary> + Logs a message object with the <c>WARN</c> level. + </summary> + <param name="message">the message object to log</param> + <remarks> + <para> + This method first checks if this logger is <c>WARN</c> + enabled by comparing the level of this logger with the + <c>WARN</c> level. If this logger is + <c>WARN</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger and + also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para> + <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this + method will print the name of the <see cref="T:System.Exception"/> but no + stack trace. To print a stack trace use the + <see cref="M:log4net.Core.LogImpl.Warn(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Warn(System.Object,System.Exception)"> + <summary> + Logs a message object with the <c>WARN</c> level + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Logs a message object with the <c>WARN</c> level including + the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> + passed as a parameter. + </para> + <para> + See the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> + </member> + <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>WARN</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <c>WARN</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>WARN</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>WARN</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>WARN</c> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Error(System.Object)"> + <summary> + Logs a message object with the <c>ERROR</c> level. + </summary> + <param name="message">The message object to log.</param> + <remarks> + <para> + This method first checks if this logger is <c>ERROR</c> + enabled by comparing the level of this logger with the + <c>ERROR</c> level. If this logger is + <c>ERROR</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger and + also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para> + <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this + method will print the name of the <see cref="T:System.Exception"/> but no + stack trace. To print a stack trace use the + <see cref="M:log4net.Core.LogImpl.Error(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Error(System.Object,System.Exception)"> + <summary> + Logs a message object with the <c>ERROR</c> level + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Logs a message object with the <c>ERROR</c> level including + the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> + passed as a parameter. + </para> + <para> + See the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.Core.LogImpl.Error(System.Object)"/> + </member> + <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>ERROR</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <c>ERROR</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>ERROR</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>ERROR</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>ERROR</c> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Fatal(System.Object)"> + <summary> + Logs a message object with the <c>FATAL</c> level. + </summary> + <param name="message">The message object to log.</param> + <remarks> + <para> + This method first checks if this logger is <c>FATAL</c> + enabled by comparing the level of this logger with the + <c>FATAL</c> level. If this logger is + <c>FATAL</c> enabled, then it converts the message object + (passed as parameter) to a string by invoking the appropriate + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then + proceeds to call all the registered appenders in this logger and + also higher in the hierarchy depending on the value of the + additivity flag. + </para> + <para> + <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this + method will print the name of the <see cref="T:System.Exception"/> but no + stack trace. To print a stack trace use the + <see cref="M:log4net.Core.LogImpl.Fatal(System.Object,System.Exception)"/> form instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.Fatal(System.Object,System.Exception)"> + <summary> + Logs a message object with the <c>FATAL</c> level + </summary> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Logs a message object with the <c>FATAL</c> level including + the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> + passed as a parameter. + </para> + <para> + See the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> form for more detailed information. + </para> + </remarks> + <seealso cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> + </member> + <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>FATAL</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object)"> + <summary> + Logs a formatted message string with the <c>FATAL</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>FATAL</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object,System.Object,System.Object)"> + <summary> + Logs a formatted message string with the <c>FATAL</c> level. + </summary> + <param name="format">A String containing zero or more format items</param> + <param name="arg0">An Object to format</param> + <param name="arg1">An Object to format</param> + <param name="arg2">An Object to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/> + format provider. To specify a localized provider use the + <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Logs a formatted message string with the <c>FATAL</c> level. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param> + <param name="format">A String containing zero or more format items</param> + <param name="args">An Object array containing zero or more objects to format</param> + <remarks> + <para> + The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See + <c>String.Format</c> for details of the syntax of the format string and the behavior + of the formatting. + </para> + <para> + This method does not take an <see cref="T:System.Exception"/> object to include in the + log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> + methods instead. + </para> + </remarks> + </member> + <member name="M:log4net.Core.LogImpl.LoggerRepositoryConfigurationChanged(System.Object,System.EventArgs)"> + <summary> + Event handler for the <see cref="E:log4net.Repository.ILoggerRepository.ConfigurationChanged"/> event + </summary> + <param name="sender">the repository</param> + <param name="e">Empty</param> + </member> + <member name="F:log4net.Core.LogImpl.ThisDeclaringType"> + <summary> + The fully qualified name of this declaring type not the type of any subclass. + </summary> + </member> + <member name="P:log4net.Core.LogImpl.IsDebugEnabled"> + <summary> + Checks if this logger is enabled for the <c>DEBUG</c> + level. + </summary> + <value> + <c>true</c> if this logger is enabled for <c>DEBUG</c> events, + <c>false</c> otherwise. + </value> + <remarks> + <para> + This function is intended to lessen the computational cost of + disabled log debug statements. + </para> + <para> + For some <c>log</c> Logger object, when you write: + </para> + <code lang="C#"> + log.Debug("This is entry number: " + i ); + </code> + <para> + You incur the cost constructing the message, concatenation in + this case, regardless of whether the message is logged or not. + </para> + <para> + If you are worried about speed, then you should write: + </para> + <code lang="C#"> + if (log.IsDebugEnabled()) + { + log.Debug("This is entry number: " + i ); + } + </code> + <para> + This way you will not incur the cost of parameter + construction if debugging is disabled for <c>log</c>. On + the other hand, if the <c>log</c> is debug enabled, you + will incur the cost of evaluating whether the logger is debug + enabled twice. Once in <c>IsDebugEnabled</c> and once in + the <c>Debug</c>. This is an insignificant overhead + since evaluating a logger takes about 1% of the time it + takes to actually log. + </para> + </remarks> + </member> + <member name="P:log4net.Core.LogImpl.IsInfoEnabled"> + <summary> + Checks if this logger is enabled for the <c>INFO</c> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <c>INFO</c> events, + <c>false</c> otherwise. + </value> + <remarks> + <para> + See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples + of using this method. + </para> + </remarks> + <seealso cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> + </member> + <member name="P:log4net.Core.LogImpl.IsWarnEnabled"> + <summary> + Checks if this logger is enabled for the <c>WARN</c> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <c>WARN</c> events, + <c>false</c> otherwise. + </value> + <remarks> + <para> + See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples + of using this method. + </para> + </remarks> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="P:log4net.Core.LogImpl.IsErrorEnabled"> + <summary> + Checks if this logger is enabled for the <c>ERROR</c> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <c>ERROR</c> events, + <c>false</c> otherwise. + </value> + <remarks> + <para> + See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples of using this method. + </para> + </remarks> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="P:log4net.Core.LogImpl.IsFatalEnabled"> + <summary> + Checks if this logger is enabled for the <c>FATAL</c> level. + </summary> + <value> + <c>true</c> if this logger is enabled for <c>FATAL</c> events, + <c>false</c> otherwise. + </value> + <remarks> + <para> + See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples of using this method. + </para> + </remarks> + <seealso cref="P:log4net.ILog.IsDebugEnabled"/> + </member> + <member name="T:log4net.Core.SecurityContext"> + <summary> + A SecurityContext used by log4net when interacting with protected resources + </summary> + <remarks> + <para> + A SecurityContext used by log4net when interacting with protected resources + for example with operating system services. This can be used to impersonate + a principal that has been granted privileges on the system resources. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Core.SecurityContext.Impersonate(System.Object)"> + <summary> + Impersonate this SecurityContext + </summary> + <param name="state">State supplied by the caller</param> + <returns>An <see cref="T:System.IDisposable"/> instance that will + revoke the impersonation of this SecurityContext, or <c>null</c></returns> + <remarks> + <para> + Impersonate this security context. Further calls on the current + thread should now be made in the security context provided + by this object. When the <see cref="T:System.IDisposable"/> result + <see cref="M:System.IDisposable.Dispose"/> method is called the security + context of the thread should be reverted to the state it was in + before <see cref="M:log4net.Core.SecurityContext.Impersonate(System.Object)"/> was called. + </para> + </remarks> + </member> + <member name="T:log4net.Core.SecurityContextProvider"> + <summary> + The <see cref="T:log4net.Core.SecurityContextProvider"/> providers default <see cref="T:log4net.Core.SecurityContext"/> instances. + </summary> + <remarks> + <para> + A configured component that interacts with potentially protected system + resources uses a <see cref="T:log4net.Core.SecurityContext"/> to provide the elevated + privileges required. If the <see cref="T:log4net.Core.SecurityContext"/> object has + been not been explicitly provided to the component then the component + will request one from this <see cref="T:log4net.Core.SecurityContextProvider"/>. + </para> + <para> + By default the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is + an instance of <see cref="T:log4net.Core.SecurityContextProvider"/> which returns only + <see cref="T:log4net.Util.NullSecurityContext"/> objects. This is a reasonable default + where the privileges required are not know by the system. + </para> + <para> + This default behavior can be overridden by subclassing the <see cref="T:log4net.Core.SecurityContextProvider"/> + and overriding the <see cref="M:log4net.Core.SecurityContextProvider.CreateSecurityContext(System.Object)"/> method to return + the desired <see cref="T:log4net.Core.SecurityContext"/> objects. The default provider + can be replaced by programmatically setting the value of the + <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> property. + </para> + <para> + An alternative is to use the <c>log4net.Config.SecurityContextProviderAttribute</c> + This attribute can be applied to an assembly in the same way as the + <c>log4net.Config.XmlConfiguratorAttribute"</c>. The attribute takes + the type to use as the <see cref="T:log4net.Core.SecurityContextProvider"/> as an argument. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Core.SecurityContextProvider.s_defaultProvider"> + <summary> + The default provider + </summary> + </member> + <member name="M:log4net.Core.SecurityContextProvider.#ctor"> + <summary> + Protected default constructor to allow subclassing + </summary> + <remarks> + <para> + Protected default constructor to allow subclassing + </para> + </remarks> + </member> + <member name="M:log4net.Core.SecurityContextProvider.CreateSecurityContext(System.Object)"> + <summary> + Create a SecurityContext for a consumer + </summary> + <param name="consumer">The consumer requesting the SecurityContext</param> + <returns>An impersonation context</returns> + <remarks> + <para> + The default implementation is to return a <see cref="T:log4net.Util.NullSecurityContext"/>. + </para> + <para> + Subclasses should override this method to provide their own + behavior. + </para> + </remarks> + </member> + <member name="P:log4net.Core.SecurityContextProvider.DefaultProvider"> + <summary> + Gets or sets the default SecurityContextProvider + </summary> + <value> + The default SecurityContextProvider + </value> + <remarks> + <para> + The default provider is used by configured components that + require a <see cref="T:log4net.Core.SecurityContext"/> and have not had one + given to them. + </para> + <para> + By default this is an instance of <see cref="T:log4net.Core.SecurityContextProvider"/> + that returns <see cref="T:log4net.Util.NullSecurityContext"/> objects. + </para> + <para> + The default provider can be set programmatically by setting + the value of this property to a sub class of <see cref="T:log4net.Core.SecurityContextProvider"/> + that has the desired behavior. + </para> + </remarks> + </member> + <member name="T:log4net.Core.WrapperCreationHandler"> + <summary> + Delegate used to handle creation of new wrappers. + </summary> + <param name="logger">The logger to wrap in a wrapper.</param> + <remarks> + <para> + Delegate used to handle creation of new wrappers. This delegate + is called from the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/> + method to construct the wrapper for the specified logger. + </para> + <para> + The delegate to use is supplied to the <see cref="T:log4net.Core.WrapperMap"/> + constructor. + </para> + </remarks> + </member> + <member name="T:log4net.Core.WrapperMap"> + <summary> + Maps between logger objects and wrapper objects. + </summary> + <remarks> + <para> + This class maintains a mapping between <see cref="T:log4net.Core.ILogger"/> objects and + <see cref="T:log4net.Core.ILoggerWrapper"/> objects. Use the <see cref="M:log4net.Core.WrapperMap.GetWrapper(log4net.Core.ILogger)"/> method to + lookup the <see cref="T:log4net.Core.ILoggerWrapper"/> for the specified <see cref="T:log4net.Core.ILogger"/>. + </para> + <para> + New wrapper instances are created by the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/> + method. The default behavior is for this method to delegate construction + of the wrapper to the <see cref="T:log4net.Core.WrapperCreationHandler"/> delegate supplied + to the constructor. This allows specialization of the behavior without + requiring subclassing of this type. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Core.WrapperMap.#ctor(log4net.Core.WrapperCreationHandler)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Core.WrapperMap"/> + </summary> + <param name="createWrapperHandler">The handler to use to create the wrapper objects.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Core.WrapperMap"/> class with + the specified handler to create the wrapper objects. + </para> + </remarks> + </member> + <member name="M:log4net.Core.WrapperMap.GetWrapper(log4net.Core.ILogger)"> + <summary> + Gets the wrapper object for the specified logger. + </summary> + <returns>The wrapper object for the specified logger</returns> + <remarks> + <para> + If the logger is null then the corresponding wrapper is null. + </para> + <para> + Looks up the wrapper it it has previously been requested and + returns it. If the wrapper has never been requested before then + the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/> virtual method is + called. + </para> + </remarks> + </member> + <member name="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"> + <summary> + Creates the wrapper object for the specified logger. + </summary> + <param name="logger">The logger to wrap in a wrapper.</param> + <returns>The wrapper object for the logger.</returns> + <remarks> + <para> + This implementation uses the <see cref="T:log4net.Core.WrapperCreationHandler"/> + passed to the constructor to create the wrapper. This method + can be overridden in a subclass. + </para> + </remarks> + </member> + <member name="M:log4net.Core.WrapperMap.RepositoryShutdown(log4net.Repository.ILoggerRepository)"> + <summary> + Called when a monitored repository shutdown event is received. + </summary> + <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that is shutting down</param> + <remarks> + <para> + This method is called when a <see cref="T:log4net.Repository.ILoggerRepository"/> that this + <see cref="T:log4net.Core.WrapperMap"/> is holding loggers for has signaled its shutdown + event <see cref="E:log4net.Repository.ILoggerRepository.ShutdownEvent"/>. The default + behavior of this method is to release the references to the loggers + and their wrappers generated for this repository. + </para> + </remarks> + </member> + <member name="M:log4net.Core.WrapperMap.ILoggerRepository_Shutdown(System.Object,System.EventArgs)"> + <summary> + Event handler for repository shutdown event. + </summary> + <param name="sender">The sender of the event.</param> + <param name="e">The event args.</param> + </member> + <member name="F:log4net.Core.WrapperMap.m_repositories"> + <summary> + Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings + </summary> + </member> + <member name="F:log4net.Core.WrapperMap.m_createWrapperHandler"> + <summary> + The handler to use to create the extension wrapper objects. + </summary> + </member> + <member name="F:log4net.Core.WrapperMap.m_shutdownHandler"> + <summary> + Internal reference to the delegate used to register for repository shutdown events. + </summary> + </member> + <member name="P:log4net.Core.WrapperMap.Repositories"> + <summary> + Gets the map of logger repositories. + </summary> + <value> + Map of logger repositories. + </value> + <remarks> + <para> + Gets the hashtable that is keyed on <see cref="T:log4net.Repository.ILoggerRepository"/>. The + values are hashtables keyed on <see cref="T:log4net.Core.ILogger"/> with the + value being the corresponding <see cref="T:log4net.Core.ILoggerWrapper"/>. + </para> + </remarks> + </member> + <member name="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"> + <summary> + Formats a <see cref="T:System.DateTime"/> as <c>"HH:mm:ss,fff"</c>. + </summary> + <remarks> + <para> + Formats a <see cref="T:System.DateTime"/> in the format <c>"HH:mm:ss,fff"</c> for example, <c>"15:49:37,459"</c>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.DateFormatter.IDateFormatter"> + <summary> + Render a <see cref="T:System.DateTime"/> as a string. + </summary> + <remarks> + <para> + Interface to abstract the rendering of a <see cref="T:System.DateTime"/> + instance into a string. + </para> + <para> + The <see cref="M:log4net.DateFormatter.IDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"/> method is used to render the + date to a text writer. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.DateFormatter.IDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"> + <summary> + Formats the specified date as a string. + </summary> + <param name="dateToFormat">The date to format.</param> + <param name="writer">The writer to write to.</param> + <remarks> + <para> + Format the <see cref="T:System.DateTime"/> as a string and write it + to the <see cref="T:System.IO.TextWriter"/> provided. + </para> + </remarks> + </member> + <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.AbsoluteTimeDateFormat"> + <summary> + String constant used to specify AbsoluteTimeDateFormat in layouts. Current value is <b>ABSOLUTE</b>. + </summary> + </member> + <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.DateAndTimeDateFormat"> + <summary> + String constant used to specify DateTimeDateFormat in layouts. Current value is <b>DATE</b>. + </summary> + </member> + <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.Iso8601TimeDateFormat"> + <summary> + String constant used to specify ISO8601DateFormat in layouts. Current value is <b>ISO8601</b>. + </summary> + </member> + <member name="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"> + <summary> + Renders the date into a string. Format is <c>"HH:mm:ss"</c>. + </summary> + <param name="dateToFormat">The date to render into a string.</param> + <param name="buffer">The string builder to write to.</param> + <remarks> + <para> + Subclasses should override this method to render the date + into a string using a precision up to the second. This method + will be called at most once per second and the result will be + reused if it is needed again during the same second. + </para> + </remarks> + </member> + <member name="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"> + <summary> + Renders the date into a string. Format is "HH:mm:ss,fff". + </summary> + <param name="dateToFormat">The date to render into a string.</param> + <param name="writer">The writer to write to.</param> + <remarks> + <para> + Uses the <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> method to generate the + time string up to the seconds and then appends the current + milliseconds. The results from <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> are + cached and <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> is called at most once + per second. + </para> + <para> + Sub classes should override <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> + rather than <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"/>. + </para> + </remarks> + </member> + <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeToTheSecond"> + <summary> + Last stored time with precision up to the second. + </summary> + </member> + <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeBuf"> + <summary> + Last stored time with precision up to the second, formatted + as a string. + </summary> + </member> + <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeString"> + <summary> + Last stored time with precision up to the second, formatted + as a string. + </summary> + </member> + <member name="T:log4net.DateFormatter.DateTimeDateFormatter"> + <summary> + Formats a <see cref="T:System.DateTime"/> as <c>"dd MMM yyyy HH:mm:ss,fff"</c> + </summary> + <remarks> + <para> + Formats a <see cref="T:System.DateTime"/> in the format + <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, + <c>"06 Nov 1994 15:49:37,459"</c>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Angelika Schnagl</author> + </member> + <member name="M:log4net.DateFormatter.DateTimeDateFormatter.#ctor"> + <summary> + Default constructor. + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.DateFormatter.DateTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"> + <summary> + Formats the date without the milliseconds part + </summary> + <param name="dateToFormat">The date to format.</param> + <param name="buffer">The string builder to write to.</param> + <remarks> + <para> + Formats a DateTime in the format <c>"dd MMM yyyy HH:mm:ss"</c> + for example, <c>"06 Nov 1994 15:49:37"</c>. + </para> + <para> + The base class will append the <c>",fff"</c> milliseconds section. + This method will only be called at most once per second. + </para> + </remarks> + </member> + <member name="F:log4net.DateFormatter.DateTimeDateFormatter.m_dateTimeFormatInfo"> + <summary> + The format info for the invariant culture. + </summary> + </member> + <member name="T:log4net.DateFormatter.Iso8601DateFormatter"> + <summary> + Formats the <see cref="T:System.DateTime"/> as <c>"yyyy-MM-dd HH:mm:ss,fff"</c>. + </summary> + <remarks> + <para> + Formats the <see cref="T:System.DateTime"/> specified as a string: <c>"yyyy-MM-dd HH:mm:ss,fff"</c>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.DateFormatter.Iso8601DateFormatter.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.DateFormatter.Iso8601DateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"> + <summary> + Formats the date without the milliseconds part + </summary> + <param name="dateToFormat">The date to format.</param> + <param name="buffer">The string builder to write to.</param> + <remarks> + <para> + Formats the date specified as a string: <c>"yyyy-MM-dd HH:mm:ss"</c>. + </para> + <para> + The base class will append the <c>",fff"</c> milliseconds section. + This method will only be called at most once per second. + </para> + </remarks> + </member> + <member name="T:log4net.DateFormatter.SimpleDateFormatter"> + <summary> + Formats the <see cref="T:System.DateTime"/> using the <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method. + </summary> + <remarks> + <para> + Formats the <see cref="T:System.DateTime"/> using the <see cref="T:System.DateTime"/> <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.DateFormatter.SimpleDateFormatter.#ctor(System.String)"> + <summary> + Constructor + </summary> + <param name="format">The format string.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> class + with the specified format string. + </para> + <para> + The format string must be compatible with the options + that can be supplied to <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>. + </para> + </remarks> + </member> + <member name="M:log4net.DateFormatter.SimpleDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"> + <summary> + Formats the date using <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>. + </summary> + <param name="dateToFormat">The date to convert to a string.</param> + <param name="writer">The writer to write to.</param> + <remarks> + <para> + Uses the date format string supplied to the constructor to call + the <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method to format the date. + </para> + </remarks> + </member> + <member name="F:log4net.DateFormatter.SimpleDateFormatter.m_formatString"> + <summary> + The format string used to format the <see cref="T:System.DateTime"/>. + </summary> + <remarks> + <para> + The format string must be compatible with the options + that can be supplied to <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Filter.DenyAllFilter"> + <summary> + This filter drops all <see cref="T:log4net.Core.LoggingEvent"/>. + </summary> + <remarks> + <para> + You can add this filter to the end of a filter chain to + switch from the default "accept all unless instructed otherwise" + filtering behavior to a "deny all unless instructed otherwise" + behavior. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Filter.FilterSkeleton"> + <summary> + Subclass this type to implement customized logging event filtering + </summary> + <remarks> + <para> + Users should extend this class to implement customized logging + event filtering. Note that <see cref="T:log4net.Repository.Hierarchy.Logger"/> and + <see cref="T:log4net.Appender.AppenderSkeleton"/>, the parent class of all standard + appenders, have built-in filtering rules. It is suggested that you + first use and understand the built-in rules before rushing to write + your own custom filters. + </para> + <para> + This abstract class assumes and also imposes that filters be + organized in a linear chain. The <see cref="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"/> + method of each filter is called sequentially, in the order of their + addition to the chain. + </para> + <para> + The <see cref="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"/> method must return one + of the integer constants <see cref="F:log4net.Filter.FilterDecision.Deny"/>, + <see cref="F:log4net.Filter.FilterDecision.Neutral"/> or <see cref="F:log4net.Filter.FilterDecision.Accept"/>. + </para> + <para> + If the value <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned, then the log event is dropped + immediately without consulting with the remaining filters. + </para> + <para> + If the value <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned, then the next filter + in the chain is consulted. If there are no more filters in the + chain, then the log event is logged. Thus, in the presence of no + filters, the default behavior is to log all logging events. + </para> + <para> + If the value <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, then the log + event is logged without consulting the remaining filters. + </para> + <para> + The philosophy of log4net filters is largely inspired from the + Linux ipchains. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Filter.IFilter"> + <summary> + Implement this interface to provide customized logging event filtering + </summary> + <remarks> + <para> + Users should implement this interface to implement customized logging + event filtering. Note that <see cref="T:log4net.Repository.Hierarchy.Logger"/> and + <see cref="T:log4net.Appender.AppenderSkeleton"/>, the parent class of all standard + appenders, have built-in filtering rules. It is suggested that you + first use and understand the built-in rules before rushing to write + your own custom filters. + </para> + <para> + This abstract class assumes and also imposes that filters be + organized in a linear chain. The <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/> + method of each filter is called sequentially, in the order of their + addition to the chain. + </para> + <para> + The <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/> method must return one + of the integer constants <see cref="F:log4net.Filter.FilterDecision.Deny"/>, + <see cref="F:log4net.Filter.FilterDecision.Neutral"/> or <see cref="F:log4net.Filter.FilterDecision.Accept"/>. + </para> + <para> + If the value <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned, then the log event is dropped + immediately without consulting with the remaining filters. + </para> + <para> + If the value <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned, then the next filter + in the chain is consulted. If there are no more filters in the + chain, then the log event is logged. Thus, in the presence of no + filters, the default behavior is to log all logging events. + </para> + <para> + If the value <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, then the log + event is logged without consulting the remaining filters. + </para> + <para> + The philosophy of log4net filters is largely inspired from the + Linux ipchains. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Decide if the logging event should be logged through an appender. + </summary> + <param name="loggingEvent">The LoggingEvent to decide upon</param> + <returns>The decision of the filter</returns> + <remarks> + <para> + If the decision is <see cref="F:log4net.Filter.FilterDecision.Deny"/>, then the event will be + dropped. If the decision is <see cref="F:log4net.Filter.FilterDecision.Neutral"/>, then the next + filter, if any, will be invoked. If the decision is <see cref="F:log4net.Filter.FilterDecision.Accept"/> then + the event will be logged without consulting with other filters in + the chain. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.IFilter.Next"> + <summary> + Property to get and set the next filter + </summary> + <value> + The next filter in the chain + </value> + <remarks> + <para> + Filters are typically composed into chains. This property allows the next filter in + the chain to be accessed. + </para> + </remarks> + </member> + <member name="F:log4net.Filter.FilterSkeleton.m_next"> + <summary> + Points to the next filter in the filter chain. + </summary> + <remarks> + <para> + See <see cref="P:log4net.Filter.FilterSkeleton.Next"/> for more information. + </para> + </remarks> + </member> + <member name="M:log4net.Filter.FilterSkeleton.ActivateOptions"> + <summary> + Initialize the filter with the options set + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Filter.FilterSkeleton.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="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> must be called again. + </para> + <para> + Typically filter's options become active immediately on set, + however this method must still be called. + </para> + </remarks> + </member> + <member name="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"> + <summary> + Decide if the <see cref="T:log4net.Core.LoggingEvent"/> should be logged through an appender. + </summary> + <param name="loggingEvent">The <see cref="T:log4net.Core.LoggingEvent"/> to decide upon</param> + <returns>The decision of the filter</returns> + <remarks> + <para> + If the decision is <see cref="F:log4net.Filter.FilterDecision.Deny"/>, then the event will be + dropped. If the decision is <see cref="F:log4net.Filter.FilterDecision.Neutral"/>, then the next + filter, if any, will be invoked. If the decision is <see cref="F:log4net.Filter.FilterDecision.Accept"/> then + the event will be logged without consulting with other filters in + the chain. + </para> + <para> + This method is marked <c>abstract</c> and must be implemented + in a subclass. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.FilterSkeleton.Next"> + <summary> + Property to get and set the next filter + </summary> + <value> + The next filter in the chain + </value> + <remarks> + <para> + Filters are typically composed into chains. This property allows the next filter in + the chain to be accessed. + </para> + </remarks> + </member> + <member name="M:log4net.Filter.DenyAllFilter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Filter.DenyAllFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Always returns the integer constant <see cref="F:log4net.Filter.FilterDecision.Deny"/> + </summary> + <param name="loggingEvent">the LoggingEvent to filter</param> + <returns>Always returns <see cref="F:log4net.Filter.FilterDecision.Deny"/></returns> + <remarks> + <para> + Ignores the event being logged and just returns + <see cref="F:log4net.Filter.FilterDecision.Deny"/>. This can be used to change the default filter + chain behavior from <see cref="F:log4net.Filter.FilterDecision.Accept"/> to <see cref="F:log4net.Filter.FilterDecision.Deny"/>. This filter + should only be used as the last filter in the chain + as any further filters will be ignored! + </para> + </remarks> + </member> + <member name="T:log4net.Filter.FilterDecision"> + <summary> + The return result from <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/> + </summary> + <remarks> + <para> + The return result from <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/> + </para> + </remarks> + </member> + <member name="F:log4net.Filter.FilterDecision.Deny"> + <summary> + The log event must be dropped immediately without + consulting with the remaining filters, if any, in the chain. + </summary> + </member> + <member name="F:log4net.Filter.FilterDecision.Neutral"> + <summary> + This filter is neutral with respect to the log event. + The remaining filters, if any, should be consulted for a final decision. + </summary> + </member> + <member name="F:log4net.Filter.FilterDecision.Accept"> + <summary> + The log event must be logged immediately without + consulting with the remaining filters, if any, in the chain. + </summary> + </member> + <member name="T:log4net.Filter.LevelMatchFilter"> + <summary> + This is a very simple filter based on <see cref="T:log4net.Core.Level"/> matching. + </summary> + <remarks> + <para> + The filter admits two options <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> and + <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. If there is an exact match between the value + of the <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> option and the <see cref="T:log4net.Core.Level"/> of the + <see cref="T:log4net.Core.LoggingEvent"/>, then the <see cref="M:log4net.Filter.LevelMatchFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in + case the <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/> option value is set + to <c>true</c>, if it is <c>false</c> then + <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. If the <see cref="T:log4net.Core.Level"/> does not match then + the result will be <see cref="F:log4net.Filter.FilterDecision.Neutral"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Filter.LevelMatchFilter.m_acceptOnMatch"> + <summary> + flag to indicate if the filter should <see cref="F:log4net.Filter.FilterDecision.Accept"/> on a match + </summary> + </member> + <member name="F:log4net.Filter.LevelMatchFilter.m_levelToMatch"> + <summary> + the <see cref="T:log4net.Core.Level"/> to match against + </summary> + </member> + <member name="M:log4net.Filter.LevelMatchFilter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Filter.LevelMatchFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Tests if the <see cref="T:log4net.Core.Level"/> of the logging event matches that of the filter + </summary> + <param name="loggingEvent">the event to filter</param> + <returns>see remarks</returns> + <remarks> + <para> + If the <see cref="T:log4net.Core.Level"/> of the event matches the level of the + filter then the result of the function depends on the + value of <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. If it is true then + the function will return <see cref="F:log4net.Filter.FilterDecision.Accept"/>, it it is false then it + will return <see cref="F:log4net.Filter.FilterDecision.Deny"/>. If the <see cref="T:log4net.Core.Level"/> does not match then + the result will be <see cref="F:log4net.Filter.FilterDecision.Neutral"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"> + <summary> + <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> + </summary> + <remarks> + <para> + The <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/> property is a flag that determines + the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the + flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the + logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Deny"/> the event. + </para> + <para> + The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LevelMatchFilter.LevelToMatch"> + <summary> + The <see cref="T:log4net.Core.Level"/> that the filter will match + </summary> + <remarks> + <para> + The level that this filter will attempt to match against the + <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then + the result depends on the value of <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Filter.LevelRangeFilter"> + <summary> + This is a simple filter based on <see cref="T:log4net.Core.Level"/> matching. + </summary> + <remarks> + <para> + The filter admits three options <see cref="P:log4net.Filter.LevelRangeFilter.LevelMin"/> and <see cref="P:log4net.Filter.LevelRangeFilter.LevelMax"/> + that determine the range of priorities that are matched, and + <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>. If there is a match between the range + of priorities and the <see cref="T:log4net.Core.Level"/> of the <see cref="T:log4net.Core.LoggingEvent"/>, then the + <see cref="M:log4net.Filter.LevelRangeFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in case the <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> + option value is set to <c>true</c>, if it is <c>false</c> + then <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. If there is no match, <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Filter.LevelRangeFilter.m_acceptOnMatch"> + <summary> + Flag to indicate the behavior when matching a <see cref="T:log4net.Core.Level"/> + </summary> + </member> + <member name="F:log4net.Filter.LevelRangeFilter.m_levelMin"> + <summary> + the minimum <see cref="T:log4net.Core.Level"/> value to match + </summary> + </member> + <member name="F:log4net.Filter.LevelRangeFilter.m_levelMax"> + <summary> + the maximum <see cref="T:log4net.Core.Level"/> value to match + </summary> + </member> + <member name="M:log4net.Filter.LevelRangeFilter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Filter.LevelRangeFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Check if the event should be logged. + </summary> + <param name="loggingEvent">the logging event to check</param> + <returns>see remarks</returns> + <remarks> + <para> + If the <see cref="T:log4net.Core.Level"/> of the logging event is outside the range + matched by this filter then <see cref="F:log4net.Filter.FilterDecision.Deny"/> + is returned. If the <see cref="T:log4net.Core.Level"/> is matched then the value of + <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> is checked. If it is true then + <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, otherwise + <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"> + <summary> + <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LevelRangeFilter.LevelMin"/> and <see cref="P:log4net.Filter.LevelRangeFilter.LevelMax"/> + </summary> + <remarks> + <para> + The <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> property is a flag that determines + the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the + flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the + logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Neutral"/> the event. + </para> + <para> + The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LevelRangeFilter.LevelMin"> + <summary> + Set the minimum matched <see cref="T:log4net.Core.Level"/> + </summary> + <remarks> + <para> + The minimum level that this filter will attempt to match against the + <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then + the result depends on the value of <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LevelRangeFilter.LevelMax"> + <summary> + Sets the maximum matched <see cref="T:log4net.Core.Level"/> + </summary> + <remarks> + <para> + The maximum level that this filter will attempt to match against the + <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then + the result depends on the value of <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Filter.LoggerMatchFilter"> + <summary> + Simple filter to match a string in the event's logger name. + </summary> + <remarks> + <para> + The works very similar to the <see cref="T:log4net.Filter.LevelMatchFilter"/>. It admits two + options <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> and <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/>. If the + <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the <see cref="T:log4net.Core.LoggingEvent"/> starts + with the value of the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> option, then the + <see cref="M:log4net.Filter.LoggerMatchFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in + case the <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> option value is set to <c>true</c>, + if it is <c>false</c> then <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. + </para> + </remarks> + <author>Daniel Cazzulino</author> + </member> + <member name="F:log4net.Filter.LoggerMatchFilter.m_acceptOnMatch"> + <summary> + Flag to indicate the behavior when we have a match + </summary> + </member> + <member name="F:log4net.Filter.LoggerMatchFilter.m_loggerToMatch"> + <summary> + The logger name string to substring match against the event + </summary> + </member> + <member name="M:log4net.Filter.LoggerMatchFilter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Filter.LoggerMatchFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Check if this filter should allow the event to be logged + </summary> + <param name="loggingEvent">the event being logged</param> + <returns>see remarks</returns> + <remarks> + <para> + The rendered message is matched against the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/>. + If the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> equals the beginning of + the incoming <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> (<see cref="M:System.String.StartsWith(System.String)"/>) + then a match will have occurred. If no match occurs + this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/> + allowing other filters to check the event. If a match occurs then + the value of <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> is checked. If it is + true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise + <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"> + <summary> + <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> + </summary> + <remarks> + <para> + The <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> property is a flag that determines + the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the + flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the + logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Deny"/> the event. + </para> + <para> + The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"> + <summary> + The <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> that the filter will match + </summary> + <remarks> + <para> + This filter will attempt to match this value against logger name in + the following way. The match will be done against the beginning of the + logger name (using <see cref="M:System.String.StartsWith(System.String)"/>). The match is + case sensitive. If a match is found then + the result depends on the value of <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Filter.MdcFilter"> + <summary> + Simple filter to match a keyed string in the <see cref="T:log4net.MDC"/> + </summary> + <remarks> + <para> + Simple filter to match a keyed string in the <see cref="T:log4net.MDC"/> + </para> + <para> + As the MDC has been replaced with layered properties the + <see cref="T:log4net.Filter.PropertyFilter"/> should be used instead. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Filter.PropertyFilter"> + <summary> + Simple filter to match a string an event property + </summary> + <remarks> + <para> + Simple filter to match a string in the value for a + specific event property + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="T:log4net.Filter.StringMatchFilter"> + <summary> + Simple filter to match a string in the rendered message + </summary> + <remarks> + <para> + Simple filter to match a string in the rendered message + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Filter.StringMatchFilter.m_acceptOnMatch"> + <summary> + Flag to indicate the behavior when we have a match + </summary> + </member> + <member name="F:log4net.Filter.StringMatchFilter.m_stringToMatch"> + <summary> + The string to substring match against the message + </summary> + </member> + <member name="F:log4net.Filter.StringMatchFilter.m_stringRegexToMatch"> + <summary> + A string regex to match + </summary> + </member> + <member name="F:log4net.Filter.StringMatchFilter.m_regexToMatch"> + <summary> + A regex object to match (generated from m_stringRegexToMatch) + </summary> + </member> + <member name="M:log4net.Filter.StringMatchFilter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Filter.StringMatchFilter.ActivateOptions"> + <summary> + Initialize and precompile the Regex if required + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Filter.StringMatchFilter.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="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Filter.StringMatchFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Check if this filter should allow the event to be logged + </summary> + <param name="loggingEvent">the event being logged</param> + <returns>see remarks</returns> + <remarks> + <para> + The rendered message is matched against the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/>. + If the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> occurs as a substring within + the message then a match will have occurred. If no match occurs + this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/> + allowing other filters to check the event. If a match occurs then + the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> is checked. If it is + true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise + <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"> + <summary> + <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/> + </summary> + <remarks> + <para> + The <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> property is a flag that determines + the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the + flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the + logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Neutral"/> the event. + </para> + <para> + The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.StringMatchFilter.StringToMatch"> + <summary> + Sets the static string to match + </summary> + <remarks> + <para> + The string that will be substring matched against + the rendered message. If the message contains this + string then the filter will match. If a match is found then + the result depends on the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/>. + </para> + <para> + One of <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/> + must be specified. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.StringMatchFilter.RegexToMatch"> + <summary> + Sets the regular expression to match + </summary> + <remarks> + <para> + The regular expression pattern that will be matched against + the rendered message. If the message matches this + pattern then the filter will match. If a match is found then + the result depends on the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/>. + </para> + <para> + One of <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/> + must be specified. + </para> + </remarks> + </member> + <member name="F:log4net.Filter.PropertyFilter.m_key"> + <summary> + The key to use to lookup the string from the event properties + </summary> + </member> + <member name="M:log4net.Filter.PropertyFilter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Filter.PropertyFilter.Decide(log4net.Core.LoggingEvent)"> + <summary> + Check if this filter should allow the event to be logged + </summary> + <param name="loggingEvent">the event being logged</param> + <returns>see remarks</returns> + <remarks> + <para> + The event property for the <see cref="P:log4net.Filter.PropertyFilter.Key"/> is matched against + the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/>. + If the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> occurs as a substring within + the property value then a match will have occurred. If no match occurs + this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/> + allowing other filters to check the event. If a match occurs then + the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> is checked. If it is + true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise + <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Filter.PropertyFilter.Key"> + <summary> + The key to lookup in the event properties and then match against. + </summary> + <remarks> + <para> + The key name to use to lookup in the properties map of the + <see cref="T:log4net.Core.LoggingEvent"/>. The match will be performed against + the value of this property if it exists. + </para> + </remarks> + </member> + <member name="T:log4net.Filter.NdcFilter"> + <summary> + Simple filter to match a string in the <see cref="T:log4net.NDC"/> + </summary> + <remarks> + <para> + Simple filter to match a string in the <see cref="T:log4net.NDC"/> + </para> + <para> + As the MDC has been replaced with named stacks stored in the + properties collections the <see cref="T:log4net.Filter.PropertyFilter"/> should + be used instead. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Filter.NdcFilter.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Sets the <see cref="P:log4net.Filter.PropertyFilter.Key"/> to <c>"NDC"</c>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.AppDomainPatternConverter"> + <summary> + Write the event appdomain name to the output + </summary> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.LoggingEvent.Domain"/> to the output writer. + </para> + </remarks> + <author>Daniel Cazzulino</author> + <author>Nicko Cadell</author> + </member> + <member name="T:log4net.Layout.Pattern.PatternLayoutConverter"> + <summary> + Abstract class that provides the formatting functionality that + derived classes need. + </summary> + <remarks> + Conversion specifiers in a conversion patterns are parsed to + individual PatternConverters. Each of which is responsible for + converting a logging event in a converter specific manner. + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="T:log4net.Util.PatternConverter"> + <summary> + Abstract class that provides the formatting functionality that + derived classes need. + </summary> + <remarks> + <para> + Conversion specifiers in a conversion patterns are parsed to + individual PatternConverters. Each of which is responsible for + converting a logging event in a converter specific manner. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Util.PatternConverter.c_renderBufferSize"> + <summary> + Initial buffer size + </summary> + </member> + <member name="F:log4net.Util.PatternConverter.c_renderBufferMaxCapacity"> + <summary> + Maximum buffer size before it is recycled + </summary> + </member> + <member name="M:log4net.Util.PatternConverter.#ctor"> + <summary> + Protected constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.PatternConverter"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Evaluate this pattern converter and write the output to a writer. + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">The state object on which the pattern converter should be executed.</param> + <remarks> + <para> + Derived pattern converters must override this method in order to + convert conversion specifiers in the appropriate way. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternConverter.SetNext(log4net.Util.PatternConverter)"> + <summary> + Set the next pattern converter in the chains + </summary> + <param name="patternConverter">the pattern converter that should follow this converter in the chain</param> + <returns>the next converter</returns> + <remarks> + <para> + The PatternConverter can merge with its neighbor during this method (or a sub class). + Therefore the return value may or may not be the value of the argument passed in. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternConverter.Format(System.IO.TextWriter,System.Object)"> + <summary> + Write the pattern converter to the writer with appropriate formatting + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">The state object on which the pattern converter should be executed.</param> + <remarks> + <para> + This method calls <see cref="M:log4net.Util.PatternConverter.Convert(System.IO.TextWriter,System.Object)"/> to allow the subclass to perform + appropriate conversion of the pattern converter. If formatting options have + been specified via the <see cref="P:log4net.Util.PatternConverter.FormattingInfo"/> then this method will + apply those formattings before writing the output. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternConverter.SpacePad(System.IO.TextWriter,System.Int32)"> + <summary> + Fast space padding method. + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> to which the spaces will be appended.</param> + <param name="length">The number of spaces to be padded.</param> + <remarks> + <para> + Fast space padding method. + </para> + </remarks> + </member> + <member name="F:log4net.Util.PatternConverter.m_option"> + <summary> + The option string to the converter + </summary> + </member> + <member name="M:log4net.Util.PatternConverter.WriteDictionary(System.IO.TextWriter,log4net.Repository.ILoggerRepository,System.Collections.IDictionary)"> + <summary> + Write an dictionary to a <see cref="T:System.IO.TextWriter"/> + </summary> + <param name="writer">the writer to write to</param> + <param name="repository">a <see cref="T:log4net.Repository.ILoggerRepository"/> to use for object conversion</param> + <param name="value">the value to write to the writer</param> + <remarks> + <para> + Writes the <see cref="T:System.Collections.IDictionary"/> to a writer in the form: + </para> + <code> + {key1=value1, key2=value2, key3=value3} + </code> + <para> + If the <see cref="T:log4net.Repository.ILoggerRepository"/> specified + is not null then it is used to render the key and value to text, otherwise + the object's ToString method is called. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternConverter.WriteObject(System.IO.TextWriter,log4net.Repository.ILoggerRepository,System.Object)"> + <summary> + Write an object to a <see cref="T:System.IO.TextWriter"/> + </summary> + <param name="writer">the writer to write to</param> + <param name="repository">a <see cref="T:log4net.Repository.ILoggerRepository"/> to use for object conversion</param> + <param name="value">the value to write to the writer</param> + <remarks> + <para> + Writes the Object to a writer. If the <see cref="T:log4net.Repository.ILoggerRepository"/> specified + is not null then it is used to render the object to text, otherwise + the object's ToString method is called. + </para> + </remarks> + </member> + <member name="P:log4net.Util.PatternConverter.Next"> + <summary> + Get the next pattern converter in the chain + </summary> + <value> + the next pattern converter in the chain + </value> + <remarks> + <para> + Get the next pattern converter in the chain + </para> + </remarks> + </member> + <member name="P:log4net.Util.PatternConverter.FormattingInfo"> + <summary> + Gets or sets the formatting info for this converter + </summary> + <value> + The formatting info for this converter + </value> + <remarks> + <para> + Gets or sets the formatting info for this converter + </para> + </remarks> + </member> + <member name="P:log4net.Util.PatternConverter.Option"> + <summary> + Gets or sets the option value for this converter + </summary> + <summary> + The option for this converter + </summary> + <remarks> + <para> + Gets or sets the option value for this converter + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Layout.Pattern.PatternLayoutConverter"/> class. + </summary> + </member> + <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Derived pattern converters must override this method in order to + convert conversion specifiers in the correct way. + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">The <see cref="T:log4net.Core.LoggingEvent"/> on which the pattern converter should be executed.</param> + </member> + <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Derived pattern converters must override this method in order to + convert conversion specifiers in the correct way. + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">The state object on which the pattern converter should be executed.</param> + </member> + <member name="F:log4net.Layout.Pattern.PatternLayoutConverter.m_ignoresException"> + <summary> + Flag indicating if this converter handles exceptions + </summary> + <remarks> + <c>false</c> if this converter handles exceptions + </remarks> + </member> + <member name="P:log4net.Layout.Pattern.PatternLayoutConverter.IgnoresException"> + <summary> + Flag indicating if this converter handles the logging event exception + </summary> + <value><c>false</c> if this converter handles the logging event exception</value> + <remarks> + <para> + If this converter handles the exception object contained within + <see cref="T:log4net.Core.LoggingEvent"/>, then this property should be set to + <c>false</c>. Otherwise, if the layout ignores the exception + object, then the property should be set to <c>true</c>. + </para> + <para> + Set this value to override a this default setting. The default + value is <c>true</c>, this converter does not handle the exception. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.AppDomainPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the event appdomain name to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.LoggingEvent.Domain"/> to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.DatePatternConverter"> + <summary> + Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format + the date of a <see cref="T:log4net.Core.LoggingEvent"/>. + </summary> + <remarks> + <para> + Render the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the writer as a string. + </para> + <para> + The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines + the formatting of the date. The following values are allowed: + <list type="definition"> + <listheader> + <term>Option value</term> + <description>Output</description> + </listheader> + <item> + <term>ISO8601</term> + <description> + Uses the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> formatter. + Formats using the <c>"yyyy-MM-dd HH:mm:ss,fff"</c> pattern. + </description> + </item> + <item> + <term>DATE</term> + <description> + Uses the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> formatter. + Formats using the <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, <c>"06 Nov 1994 15:49:37,459"</c>. + </description> + </item> + <item> + <term>ABSOLUTE</term> + <description> + Uses the <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/> formatter. + Formats using the <c>"HH:mm:ss,yyyy"</c> for example, <c>"15:49:37,459"</c>. + </description> + </item> + <item> + <term>other</term> + <description> + Any other pattern string uses the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> formatter. + This formatter passes the pattern string to the <see cref="T:System.DateTime"/> + <see cref="M:System.DateTime.ToString(System.String)"/> method. + For details on valid patterns see + <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.asp">DateTimeFormatInfo Class</a>. + </description> + </item> + </list> + </para> + <para> + The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> is in the local time zone and is rendered in that zone. + To output the time in Universal time see <see cref="T:log4net.Layout.Pattern.UtcDatePatternConverter"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Layout.Pattern.DatePatternConverter.m_dateFormatter"> + <summary> + The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string + </summary> + <remarks> + <para> + The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"> + <summary> + Initialize the converter pattern based on the <see cref="P:log4net.Util.PatternConverter.Option"/> property. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.Pattern.DatePatternConverter.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="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.DatePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Convert the pattern into the rendered message + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Pass the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the <see cref="T:log4net.DateFormatter.IDateFormatter"/> + for it to render it to the writer. + </para> + <para> + The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> passed is in the local time zone. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.ExceptionPatternConverter"> + <summary> + Write the exception text to the output + </summary> + <remarks> + <para> + If an exception object is stored in the logging event + it will be rendered into the pattern output with a + trailing newline. + </para> + <para> + If there is no exception then nothing will be output + and no trailing newline will be appended. + It is typical to put a newline before the exception + and to have the exception as the last data in the pattern. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.ExceptionPatternConverter.#ctor"> + <summary> + Default constructor + </summary> + </member> + <member name="M:log4net.Layout.Pattern.ExceptionPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the exception text to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + If an exception object is stored in the logging event + it will be rendered into the pattern output with a + trailing newline. + </para> + <para> + If there is no exception then nothing will be output + and no trailing newline will be appended. + It is typical to put a newline before the exception + and to have the exception as the last data in the pattern. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.FileLocationPatternConverter"> + <summary> + Writes the caller location file name to the output + </summary> + <remarks> + <para> + Writes the value of the <see cref="P:log4net.Core.LocationInfo.FileName"/> for + the event to the output writer. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.FileLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the caller location file name to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the value of the <see cref="P:log4net.Core.LocationInfo.FileName"/> for + the <paramref name="loggingEvent"/> to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.FullLocationPatternConverter"> + <summary> + Write the caller location info to the output + </summary> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.LocationInfo.FullInfo"/> to the output writer. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.FullLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the caller location info to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.LocationInfo.FullInfo"/> to the output writer. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.IdentityPatternConverter"> + <summary> + Writes the event identity to the output + </summary> + <remarks> + <para> + Writes the value of the <see cref="P:log4net.Core.LoggingEvent.Identity"/> to + the output writer. + </para> + </remarks> + <author>Daniel Cazzulino</author> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.IdentityPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Writes the event identity to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the value of the <paramref name="loggingEvent"/> + <see cref="P:log4net.Core.LoggingEvent.Identity"/> to + the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.LevelPatternConverter"> + <summary> + Write the event level to the output + </summary> + <remarks> + <para> + Writes the display name of the event <see cref="P:log4net.Core.LoggingEvent.Level"/> + to the writer. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.LevelPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the event level to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.Level.DisplayName"/> of the <paramref name="loggingEvent"/> <see cref="P:log4net.Core.LoggingEvent.Level"/> + to the <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.LineLocationPatternConverter"> + <summary> + Write the caller location line number to the output + </summary> + <remarks> + <para> + Writes the value of the <see cref="P:log4net.Core.LocationInfo.LineNumber"/> for + the event to the output writer. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.LineLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the caller location line number to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the value of the <see cref="P:log4net.Core.LocationInfo.LineNumber"/> for + the <paramref name="loggingEvent"/> to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.LoggerPatternConverter"> + <summary> + Converter for logger name + </summary> + <remarks> + <para> + Outputs the <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the event. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="T:log4net.Layout.Pattern.NamedPatternConverter"> + <summary> + Converter to output and truncate <c>'.'</c> separated strings + </summary> + <remarks> + <para> + This abstract class supports truncating a <c>'.'</c> separated string + to show a specified number of elements from the right hand side. + This is used to truncate class names that are fully qualified. + </para> + <para> + Subclasses should override the <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"/> method to + return the fully qualified string. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"> + <summary> + Initialize the converter + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.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="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"> + <summary> + Get the fully qualified string data + </summary> + <param name="loggingEvent">the event being logged</param> + <returns>the fully qualified name</returns> + <remarks> + <para> + Overridden by subclasses to get the fully qualified name before the + precision is applied to it. + </para> + <para> + Return the fully qualified <c>'.'</c> (dot/period) separated string. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.NamedPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Convert the pattern to the rendered message + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + Render the <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"/> to the precision + specified by the <see cref="P:log4net.Util.PatternConverter.Option"/> property. + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.LoggerPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"> + <summary> + Gets the fully qualified name of the logger + </summary> + <param name="loggingEvent">the event being logged</param> + <returns>The fully qualified logger name</returns> + <remarks> + <para> + Returns the <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the <paramref name="loggingEvent"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.MessagePatternConverter"> + <summary> + Writes the event message to the output + </summary> + <remarks> + <para> + Uses the <see cref="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"/> method + to write out the event message. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.MessagePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Writes the event message to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Uses the <see cref="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"/> method + to write out the event message. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.MethodLocationPatternConverter"> + <summary> + Write the method name to the output + </summary> + <remarks> + <para> + Writes the caller location <see cref="P:log4net.Core.LocationInfo.MethodName"/> to + the output. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.MethodLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the method name to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the caller location <see cref="P:log4net.Core.LocationInfo.MethodName"/> to + the output. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.NdcPatternConverter"> + <summary> + Converter to include event NDC + </summary> + <remarks> + <para> + Outputs the value of the event property named <c>NDC</c>. + </para> + <para> + The <see cref="T:log4net.Layout.Pattern.PropertyPatternConverter"/> should be used instead. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.NdcPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the event NDC to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + As the thread context stacks are now stored in named event properties + this converter simply looks up the value of the <c>NDC</c> property. + </para> + <para> + The <see cref="T:log4net.Layout.Pattern.PropertyPatternConverter"/> should be used instead. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.PropertyPatternConverter"> + <summary> + Property pattern converter + </summary> + <remarks> + <para> + Writes out the value of a named property. The property name + should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/> + property. + </para> + <para> + If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c> + then all the properties are written as key value pairs. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.PropertyPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the property value to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes out the value of a named property. The property name + should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/> + property. + </para> + <para> + If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c> + then all the properties are written as key value pairs. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.RelativeTimePatternConverter"> + <summary> + Converter to output the relative time of the event + </summary> + <remarks> + <para> + Converter to output the time of the event relative to the start of the program. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.RelativeTimePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the relative time to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes out the relative time of the event in milliseconds. + That is the number of milliseconds between the event <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> + and the <see cref="P:log4net.Core.LoggingEvent.StartTime"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Pattern.RelativeTimePatternConverter.TimeDifferenceInMillis(System.DateTime,System.DateTime)"> + <summary> + Helper method to get the time difference between two DateTime objects + </summary> + <param name="start">start time (in the current local time zone)</param> + <param name="end">end time (in the current local time zone)</param> + <returns>the time difference in milliseconds</returns> + </member> + <member name="T:log4net.Layout.Pattern.ThreadPatternConverter"> + <summary> + Converter to include event thread name + </summary> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.LoggingEvent.ThreadName"/> to the output. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.ThreadPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the ThreadName to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Writes the <see cref="P:log4net.Core.LoggingEvent.ThreadName"/> to the <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.TypeNamePatternConverter"> + <summary> + Pattern converter for the class name + </summary> + <remarks> + <para> + Outputs the <see cref="P:log4net.Core.LocationInfo.ClassName"/> of the event. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.TypeNamePatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"> + <summary> + Gets the fully qualified name of the class + </summary> + <param name="loggingEvent">the event being logged</param> + <returns>The fully qualified type name for the caller location</returns> + <remarks> + <para> + Returns the <see cref="P:log4net.Core.LocationInfo.ClassName"/> of the <paramref name="loggingEvent"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Pattern.UserNamePatternConverter"> + <summary> + Converter to include event user name + </summary> + <author>Douglas de la Torre</author> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.UserNamePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Convert the pattern to the rendered message + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + </member> + <member name="T:log4net.Layout.Pattern.UtcDatePatternConverter"> + <summary> + Write the TimeStamp to the output + </summary> + <remarks> + <para> + Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format + the date of a <see cref="T:log4net.Core.LoggingEvent"/>. + </para> + <para> + Uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> + in Universal time. + </para> + <para> + See the <see cref="T:log4net.Layout.Pattern.DatePatternConverter"/> for details on the date pattern syntax. + </para> + </remarks> + <seealso cref="T:log4net.Layout.Pattern.DatePatternConverter"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.Pattern.UtcDatePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Write the TimeStamp to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Pass the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the <see cref="T:log4net.DateFormatter.IDateFormatter"/> + for it to render it to the writer. + </para> + <para> + The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> passed is in the local time zone, this is converted + to Universal time before it is rendered. + </para> + </remarks> + <seealso cref="T:log4net.Layout.Pattern.DatePatternConverter"/> + </member> + <member name="T:log4net.Layout.ExceptionLayout"> + <summary> + A Layout that renders only the Exception text from the logging event + </summary> + <remarks> + <para> + A Layout that renders only the Exception text from the logging event. + </para> + <para> + This Layout should only be used with appenders that utilize multiple + layouts (e.g. <see cref="T:log4net.Appender.AdoNetAppender"/>). + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Layout.LayoutSkeleton"> + <summary> + Extend this abstract class to create your own log layout format. + </summary> + <remarks> + <para> + This is the base implementation of the <see cref="T:log4net.Layout.ILayout"/> + interface. Most layout objects should extend this class. + </para> + </remarks> + <remarks> + <note type="inheritinfo"> + <para> + Subclasses must implement the <see cref="M:log4net.Layout.LayoutSkeleton.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> + method. + </para> + <para> + Subclasses should set the <see cref="P:log4net.Layout.LayoutSkeleton.IgnoresException"/> in their default + constructor. + </para> + </note> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Layout.ILayout"> + <summary> + Interface implemented by layout objects + </summary> + <remarks> + <para> + An <see cref="T:log4net.Layout.ILayout"/> object is used to format a <see cref="T:log4net.Core.LoggingEvent"/> + as text. The <see cref="M:log4net.Layout.ILayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> method is called by an + appender to transform the <see cref="T:log4net.Core.LoggingEvent"/> into a string. + </para> + <para> + The layout can also supply <see cref="P:log4net.Layout.ILayout.Header"/> and <see cref="P:log4net.Layout.ILayout.Footer"/> + text that is appender before any events and after all the events respectively. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Layout.ILayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Implement this method to create your own layout format. + </summary> + <param name="writer">The TextWriter to write the formatted event to</param> + <param name="loggingEvent">The event to format</param> + <remarks> + <para> + This method is called by an appender to format + the <paramref name="loggingEvent"/> as text and output to a writer. + </para> + <para> + If the caller does not have a <see cref="T:System.IO.TextWriter"/> and prefers the + event to be formatted as a <see cref="T:System.String"/> then the following + code can be used to format the event into a <see cref="T:System.IO.StringWriter"/>. + </para> + <code lang="C#"> + StringWriter writer = new StringWriter(); + Layout.Format(writer, loggingEvent); + string formattedEvent = writer.ToString(); + </code> + </remarks> + </member> + <member name="P:log4net.Layout.ILayout.ContentType"> + <summary> + The content type output by this layout. + </summary> + <value>The content type</value> + <remarks> + <para> + The content type output by this layout. + </para> + <para> + This is a MIME type e.g. <c>"text/plain"</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.ILayout.Header"> + <summary> + The header for the layout format. + </summary> + <value>the layout header</value> + <remarks> + <para> + The Header text will be appended before any logging events + are formatted and appended. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.ILayout.Footer"> + <summary> + The footer for the layout format. + </summary> + <value>the layout footer</value> + <remarks> + <para> + The Footer text will be appended after all the logging events + have been formatted and appended. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.ILayout.IgnoresException"> + <summary> + Flag indicating if this layout handle exceptions + </summary> + <value><c>false</c> if this layout handles exceptions</value> + <remarks> + <para> + If this layout handles the exception object contained within + <see cref="T:log4net.Core.LoggingEvent"/>, then the layout should return + <c>false</c>. Otherwise, if the layout ignores the exception + object, then the layout should return <c>true</c>. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.LayoutSkeleton.m_header"> + <summary> + The header text + </summary> + <remarks> + <para> + See <see cref="P:log4net.Layout.LayoutSkeleton.Header"/> for more information. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.LayoutSkeleton.m_footer"> + <summary> + The footer text + </summary> + <remarks> + <para> + See <see cref="P:log4net.Layout.LayoutSkeleton.Footer"/> for more information. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.LayoutSkeleton.m_ignoresException"> + <summary> + Flag indicating if this layout handles exceptions + </summary> + <remarks> + <para> + <c>false</c> if this layout handles exceptions + </para> + </remarks> + </member> + <member name="M:log4net.Layout.LayoutSkeleton.#ctor"> + <summary> + Empty default constructor + </summary> + <remarks> + <para> + Empty default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Layout.LayoutSkeleton.ActivateOptions"> + <summary> + Activate component options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.LayoutSkeleton.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="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> must be called again. + </para> + <para> + This method must be implemented by the subclass. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.LayoutSkeleton.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Implement this method to create your own layout format. + </summary> + <param name="writer">The TextWriter to write the formatted event to</param> + <param name="loggingEvent">The event to format</param> + <remarks> + <para> + This method is called by an appender to format + the <paramref name="loggingEvent"/> as text. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.LayoutSkeleton.ContentType"> + <summary> + The content type output by this layout. + </summary> + <value>The content type is <c>"text/plain"</c></value> + <remarks> + <para> + The content type output by this layout. + </para> + <para> + This base class uses the value <c>"text/plain"</c>. + To change this value a subclass must override this + property. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.LayoutSkeleton.Header"> + <summary> + The header for the layout format. + </summary> + <value>the layout header</value> + <remarks> + <para> + The Header text will be appended before any logging events + are formatted and appended. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.LayoutSkeleton.Footer"> + <summary> + The footer for the layout format. + </summary> + <value>the layout footer</value> + <remarks> + <para> + The Footer text will be appended after all the logging events + have been formatted and appended. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.LayoutSkeleton.IgnoresException"> + <summary> + Flag indicating if this layout handles exceptions + </summary> + <value><c>false</c> if this layout handles exceptions</value> + <remarks> + <para> + If this layout handles the exception object contained within + <see cref="T:log4net.Core.LoggingEvent"/>, then the layout should return + <c>false</c>. Otherwise, if the layout ignores the exception + object, then the layout should return <c>true</c>. + </para> + <para> + Set this value to override a this default setting. The default + value is <c>true</c>, this layout does not handle the exception. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.ExceptionLayout.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Constructs a ExceptionLayout + </para> + </remarks> + </member> + <member name="M:log4net.Layout.ExceptionLayout.ActivateOptions"> + <summary> + Activate component options + </summary> + <remarks> + <para> + Part of the <see cref="T:log4net.Core.IOptionHandler"/> component activation + framework. + </para> + <para> + This method does nothing as options become effective immediately. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.ExceptionLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Gets the exception text from the logging event + </summary> + <param name="writer">The TextWriter to write the formatted event to</param> + <param name="loggingEvent">the event being logged</param> + <remarks> + <para> + Write the exception string to the <see cref="T:System.IO.TextWriter"/>. + The exception string is retrieved from <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.IRawLayout"> + <summary> + Interface for raw layout objects + </summary> + <remarks> + <para> + Interface used to format a <see cref="T:log4net.Core.LoggingEvent"/> + to an object. + </para> + <para> + This interface should not be confused with the + <see cref="T:log4net.Layout.ILayout"/> interface. This interface is used in + only certain specialized situations where a raw object is + required rather than a formatted string. The <see cref="T:log4net.Layout.ILayout"/> + is not generally useful than this interface. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Layout.IRawLayout.Format(log4net.Core.LoggingEvent)"> + <summary> + Implement this method to create your own layout format. + </summary> + <param name="loggingEvent">The event to format</param> + <returns>returns the formatted event</returns> + <remarks> + <para> + Implement this method to create your own layout format. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.Layout2RawLayoutAdapter"> + <summary> + Adapts any <see cref="T:log4net.Layout.ILayout"/> to a <see cref="T:log4net.Layout.IRawLayout"/> + </summary> + <remarks> + <para> + Where an <see cref="T:log4net.Layout.IRawLayout"/> is required this adapter + allows a <see cref="T:log4net.Layout.ILayout"/> to be specified. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Layout.Layout2RawLayoutAdapter.m_layout"> + <summary> + The layout to adapt + </summary> + </member> + <member name="M:log4net.Layout.Layout2RawLayoutAdapter.#ctor(log4net.Layout.ILayout)"> + <summary> + Construct a new adapter + </summary> + <param name="layout">the layout to adapt</param> + <remarks> + <para> + Create the adapter for the specified <paramref name="layout"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.Layout2RawLayoutAdapter.Format(log4net.Core.LoggingEvent)"> + <summary> + Format the logging event as an object. + </summary> + <param name="loggingEvent">The event to format</param> + <returns>returns the formatted event</returns> + <remarks> + <para> + Format the logging event as an object. + </para> + <para> + Uses the <see cref="T:log4net.Layout.ILayout"/> object supplied to + the constructor to perform the formatting. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.PatternLayout"> + <summary> + A flexible layout configurable with pattern string. + </summary> + <remarks> + <para> + The goal of this class is to <see cref="M:log4net.Layout.PatternLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> a + <see cref="T:log4net.Core.LoggingEvent"/> as a string. The results + depend on the <i>conversion pattern</i>. + </para> + <para> + The conversion pattern is closely related to the conversion + pattern of the printf function in C. A conversion pattern is + composed of literal text and format control expressions called + <i>conversion specifiers</i>. + </para> + <para> + <i>You are free to insert any literal text within the conversion + pattern.</i> + </para> + <para> + Each conversion specifier starts with a percent sign (%) and is + followed by optional <i>format modifiers</i> and a <i>conversion + pattern name</i>. The conversion pattern name specifies the type of + data, e.g. logger, level, date, thread name. The format + modifiers control such things as field width, padding, left and + right justification. The following is a simple example. + </para> + <para> + Let the conversion pattern be <b>"%-5level [%thread]: %message%newline"</b> and assume + that the log4net environment was set to use a PatternLayout. Then the + statements + </para> + <code lang="C#"> + ILog log = LogManager.GetLogger(typeof(TestApp)); + log.Debug("Message 1"); + log.Warn("Message 2"); + </code> + <para>would yield the output</para> + <code> + DEBUG [main]: Message 1 + WARN [main]: Message 2 + </code> + <para> + Note that there is no explicit separator between text and + conversion specifiers. The pattern parser knows when it has reached + the end of a conversion specifier when it reads a conversion + character. In the example above the conversion specifier + <b>%-5level</b> means the level of the logging event should be left + justified to a width of five characters. + </para> + <para> + The recognized conversion pattern names are: + </para> + <list type="table"> + <listheader> + <term>Conversion Pattern Name</term> + <description>Effect</description> + </listheader> + <item> + <term>a</term> + <description>Equivalent to <b>appdomain</b></description> + </item> + <item> + <term>appdomain</term> + <description> + Used to output the friendly name of the AppDomain where the + logging event was generated. + </description> + </item> + <item> + <term>c</term> + <description>Equivalent to <b>logger</b></description> + </item> + <item> + <term>C</term> + <description>Equivalent to <b>type</b></description> + </item> + <item> + <term>class</term> + <description>Equivalent to <b>type</b></description> + </item> + <item> + <term>d</term> + <description>Equivalent to <b>date</b></description> + </item> + <item> + <term>date</term> + <description> + <para> + Used to output the date of the logging event in the local time zone. + To output the date in universal time use the <c>%utcdate</c> pattern. + The date conversion + specifier may be followed by a <i>date format specifier</i> enclosed + between braces. For example, <b>%date{HH:mm:ss,fff}</b> or + <b>%date{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is + given then ISO8601 format is + assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>). + </para> + <para> + The date format specifier admits the same syntax as the + time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + <para> + For better results it is recommended to use the log4net date + formatters. These can be specified using one of the strings + "ABSOLUTE", "DATE" and "ISO8601" for specifying + <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>, + <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively + <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example, + <b>%date{ISO8601}</b> or <b>%date{ABSOLUTE}</b>. + </para> + <para> + These dedicated date formatters perform significantly + better than <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + </description> + </item> + <item> + <term>exception</term> + <description> + <para> + Used to output the exception passed in with the log message. + </para> + <para> + If an exception object is stored in the logging event + it will be rendered into the pattern output with a + trailing newline. + If there is no exception then nothing will be output + and no trailing newline will be appended. + It is typical to put a newline before the exception + and to have the exception as the last data in the pattern. + </para> + </description> + </item> + <item> + <term>F</term> + <description>Equivalent to <b>file</b></description> + </item> + <item> + <term>file</term> + <description> + <para> + Used to output the file name where the logging request was + issued. + </para> + <para> + <b>WARNING</b> Generating caller location information is + extremely slow. Its use should be avoided unless execution speed + is not an issue. + </para> + <para> + See the note below on the availability of caller location information. + </para> + </description> + </item> + <item> + <term>identity</term> + <description> + <para> + Used to output the user name for the currently active user + (Principal.Identity.Name). + </para> + <para> + <b>WARNING</b> Generating caller information is + extremely slow. Its use should be avoided unless execution speed + is not an issue. + </para> + </description> + </item> + <item> + <term>l</term> + <description>Equivalent to <b>location</b></description> + </item> + <item> + <term>L</term> + <description>Equivalent to <b>line</b></description> + </item> + <item> + <term>location</term> + <description> + <para> + Used to output location information of the caller which generated + the logging event. + </para> + <para> + The location information depends on the CLI implementation but + usually consists of the fully qualified name of the calling + method followed by the callers source the file name and line + number between parentheses. + </para> + <para> + The location information can be very useful. However, its + generation is <b>extremely</b> slow. Its use should be avoided + unless execution speed is not an issue. + </para> + <para> + See the note below on the availability of caller location information. + </para> + </description> + </item> + <item> + <term>level</term> + <description> + <para> + Used to output the level of the logging event. + </para> + </description> + </item> + <item> + <term>line</term> + <description> + <para> + Used to output the line number from where the logging request + was issued. + </para> + <para> + <b>WARNING</b> Generating caller location information is + extremely slow. Its use should be avoided unless execution speed + is not an issue. + </para> + <para> + See the note below on the availability of caller location information. + </para> + </description> + </item> + <item> + <term>logger</term> + <description> + <para> + Used to output the logger of the logging event. The + logger conversion specifier can be optionally followed by + <i>precision specifier</i>, that is a decimal constant in + brackets. + </para> + <para> + If a precision specifier is given, then only the corresponding + number of right most components of the logger name will be + printed. By default the logger name is printed in full. + </para> + <para> + For example, for the logger name "a.b.c" the pattern + <b>%logger{2}</b> will output "b.c". + </para> + </description> + </item> + <item> + <term>m</term> + <description>Equivalent to <b>message</b></description> + </item> + <item> + <term>M</term> + <description>Equivalent to <b>method</b></description> + </item> + <item> + <term>message</term> + <description> + <para> + Used to output the application supplied message associated with + the logging event. + </para> + </description> + </item> + <item> + <term>mdc</term> + <description> + <para> + The MDC (old name for the ThreadContext.Properties) is now part of the + combined event properties. This pattern is supported for compatibility + but is equivalent to <b>property</b>. + </para> + </description> + </item> + <item> + <term>method</term> + <description> + <para> + Used to output the method name where the logging request was + issued. + </para> + <para> + <b>WARNING</b> Generating caller location information is + extremely slow. Its use should be avoided unless execution speed + is not an issue. + </para> + <para> + See the note below on the availability of caller location information. + </para> + </description> + </item> + <item> + <term>n</term> + <description>Equivalent to <b>newline</b></description> + </item> + <item> + <term>newline</term> + <description> + <para> + Outputs the platform dependent line separator character or + characters. + </para> + <para> + This conversion pattern offers the same performance as using + non-portable line separator strings such as "\n", or "\r\n". + Thus, it is the preferred way of specifying a line separator. + </para> + </description> + </item> + <item> + <term>ndc</term> + <description> + <para> + Used to output the NDC (nested diagnostic context) associated + with the thread that generated the logging event. + </para> + </description> + </item> + <item> + <term>p</term> + <description>Equivalent to <b>level</b></description> + </item> + <item> + <term>P</term> + <description>Equivalent to <b>property</b></description> + </item> + <item> + <term>properties</term> + <description>Equivalent to <b>property</b></description> + </item> + <item> + <term>property</term> + <description> + <para> + Used to output the an event specific property. The key to + lookup must be specified within braces and directly following the + pattern specifier, e.g. <b>%property{user}</b> would include the value + from the property that is keyed by the string 'user'. Each property value + that is to be included in the log must be specified separately. + Properties are added to events by loggers or appenders. By default + the <c>log4net:HostName</c> property is set to the name of machine on + which the event was originally logged. + </para> + <para> + If no key is specified, e.g. <b>%property</b> then all the keys and their + values are printed in a comma separated list. + </para> + <para> + The properties of an event are combined from a number of different + contexts. These are listed below in the order in which they are searched. + </para> + <list type="definition"> + <item> + <term>the event properties</term> + <description> + The event has <see cref="P:log4net.Core.LoggingEvent.Properties"/> that can be set. These + properties are specific to this event only. + </description> + </item> + <item> + <term>the thread properties</term> + <description> + The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current + thread. These properties are shared by all events logged on this thread. + </description> + </item> + <item> + <term>the global properties</term> + <description> + The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These + properties are shared by all the threads in the AppDomain. + </description> + </item> + </list> + + </description> + </item> + <item> + <term>r</term> + <description>Equivalent to <b>timestamp</b></description> + </item> + <item> + <term>t</term> + <description>Equivalent to <b>thread</b></description> + </item> + <item> + <term>timestamp</term> + <description> + <para> + Used to output the number of milliseconds elapsed since the start + of the application until the creation of the logging event. + </para> + </description> + </item> + <item> + <term>thread</term> + <description> + <para> + Used to output the name of the thread that generated the + logging event. Uses the thread number if no name is available. + </para> + </description> + </item> + <item> + <term>type</term> + <description> + <para> + Used to output the fully qualified type name of the caller + issuing the logging request. This conversion specifier + can be optionally followed by <i>precision specifier</i>, that + is a decimal constant in brackets. + </para> + <para> + If a precision specifier is given, then only the corresponding + number of right most components of the class name will be + printed. By default the class name is output in fully qualified form. + </para> + <para> + For example, for the class name "log4net.Layout.PatternLayout", the + pattern <b>%type{1}</b> will output "PatternLayout". + </para> + <para> + <b>WARNING</b> Generating the caller class information is + slow. Thus, its use should be avoided unless execution speed is + not an issue. + </para> + <para> + See the note below on the availability of caller location information. + </para> + </description> + </item> + <item> + <term>u</term> + <description>Equivalent to <b>identity</b></description> + </item> + <item> + <term>username</term> + <description> + <para> + Used to output the WindowsIdentity for the currently + active user. + </para> + <para> + <b>WARNING</b> Generating caller WindowsIdentity information is + extremely slow. Its use should be avoided unless execution speed + is not an issue. + </para> + </description> + </item> + <item> + <term>utcdate</term> + <description> + <para> + Used to output the date of the logging event in universal time. + The date conversion + specifier may be followed by a <i>date format specifier</i> enclosed + between braces. For example, <b>%utcdate{HH:mm:ss,fff}</b> or + <b>%utcdate{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is + given then ISO8601 format is + assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>). + </para> + <para> + The date format specifier admits the same syntax as the + time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + <para> + For better results it is recommended to use the log4net date + formatters. These can be specified using one of the strings + "ABSOLUTE", "DATE" and "ISO8601" for specifying + <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>, + <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively + <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example, + <b>%utcdate{ISO8601}</b> or <b>%utcdate{ABSOLUTE}</b>. + </para> + <para> + These dedicated date formatters perform significantly + better than <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + </description> + </item> + <item> + <term>w</term> + <description>Equivalent to <b>username</b></description> + </item> + <item> + <term>x</term> + <description>Equivalent to <b>ndc</b></description> + </item> + <item> + <term>X</term> + <description>Equivalent to <b>mdc</b></description> + </item> + <item> + <term>%</term> + <description> + <para> + The sequence %% outputs a single percent sign. + </para> + </description> + </item> + </list> + <para> + The single letter patterns are deprecated in favor of the + longer more descriptive pattern names. + </para> + <para> + By default the relevant information is output as is. However, + with the aid of format modifiers it is possible to change the + minimum field width, the maximum field width and justification. + </para> + <para> + The optional format modifier is placed between the percent sign + and the conversion pattern name. + </para> + <para> + The first optional format modifier is the <i>left justification + flag</i> which is just the minus (-) character. Then comes the + optional <i>minimum field width</i> modifier. This is a decimal + constant that represents the minimum number of characters to + output. If the data item requires fewer characters, it is padded on + either the left or the right until the minimum width is + reached. The default is to pad on the left (right justify) but you + can specify right padding with the left justification flag. The + padding character is space. If the data item is larger than the + minimum field width, the field is expanded to accommodate the + data. The value is never truncated. + </para> + <para> + This behavior can be changed using the <i>maximum field + width</i> modifier which is designated by a period followed by a + decimal constant. If the data item is longer than the maximum + field, then the extra characters are removed from the + <i>beginning</i> of the data item and not from the end. For + example, it the maximum field width is eight and the data item is + ten characters long, then the first two characters of the data item + are dropped. This behavior deviates from the printf function in C + where truncation is done from the end. + </para> + <para> + Below are various format modifier examples for the logger + conversion specifier. + </para> + <div class="tablediv"> + <table class="dtTABLE" cellspacing="0"> + <tr> + <th>Format modifier</th> + <th>left justify</th> + <th>minimum width</th> + <th>maximum width</th> + <th>comment</th> + </tr> + <tr> + <td align="center">%20logger</td> + <td align="center">false</td> + <td align="center">20</td> + <td align="center">none</td> + <td> + <para> + Left pad with spaces if the logger name is less than 20 + characters long. + </para> + </td> + </tr> + <tr> + <td align="center">%-20logger</td> + <td align="center">true</td> + <td align="center">20</td> + <td align="center">none</td> + <td> + <para> + Right pad with spaces if the logger + name is less than 20 characters long. + </para> + </td> + </tr> + <tr> + <td align="center">%.30logger</td> + <td align="center">NA</td> + <td align="center">none</td> + <td align="center">30</td> + <td> + <para> + Truncate from the beginning if the logger + name is longer than 30 characters. + </para> + </td> + </tr> + <tr> + <td align="center"><nobr>%20.30logger</nobr></td> + <td align="center">false</td> + <td align="center">20</td> + <td align="center">30</td> + <td> + <para> + Left pad with spaces if the logger name is shorter than 20 + characters. However, if logger name is longer than 30 characters, + then truncate from the beginning. + </para> + </td> + </tr> + <tr> + <td align="center">%-20.30logger</td> + <td align="center">true</td> + <td align="center">20</td> + <td align="center">30</td> + <td> + <para> + Right pad with spaces if the logger name is shorter than 20 + characters. However, if logger name is longer than 30 characters, + then truncate from the beginning. + </para> + </td> + </tr> + </table> + </div> + <para> + <b>Note about caller location information.</b><br/> + The following patterns <c>%type %file %line %method %location %class %C %F %L %l %M</c> + all generate caller location information. + Location information uses the <c>System.Diagnostics.StackTrace</c> class to generate + a call stack. The caller's information is then extracted from this stack. + </para> + <note type="caution"> + <para> + The <c>System.Diagnostics.StackTrace</c> class is not supported on the + .NET Compact Framework 1.0 therefore caller location information is not + available on that framework. + </para> + </note> + <note type="caution"> + <para> + The <c>System.Diagnostics.StackTrace</c> class has this to say about Release builds: + </para> + <para> + "StackTrace information will be most informative with Debug build configurations. + By default, Debug builds include debug symbols, while Release builds do not. The + debug symbols contain most of the file, method name, line number, and column + information used in constructing StackFrame and StackTrace objects. StackTrace + might not report as many method calls as expected, due to code transformations + that occur during optimization." + </para> + <para> + This means that in a Release build the caller information may be incomplete or may + not exist at all! Therefore caller location information cannot be relied upon in a Release build. + </para> + </note> + <para> + Additional pattern converters may be registered with a specific <see cref="T:log4net.Layout.PatternLayout"/> + instance using the <see cref="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"/> method. + </para> + </remarks> + <example> + This is a more detailed pattern. + <code><b>%timestamp [%thread] %level %logger %ndc - %message%newline</b></code> + </example> + <example> + A similar pattern except that the relative time is + right padded if less than 6 digits, thread name is right padded if + less than 15 characters and truncated if longer and the logger + name is left padded if shorter than 30 characters and truncated if + longer. + <code><b>%-6timestamp [%15.15thread] %-5level %30.30logger %ndc - %message%newline</b></code> + </example> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Douglas de la Torre</author> + <author>Daniel Cazzulino</author> + </member> + <member name="F:log4net.Layout.PatternLayout.DefaultConversionPattern"> + <summary> + Default pattern string for log output. + </summary> + <remarks> + <para> + Default pattern string for log output. + Currently set to the string <b>"%message%newline"</b> + which just prints the application supplied message. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.PatternLayout.DetailConversionPattern"> + <summary> + A detailed conversion pattern + </summary> + <remarks> + <para> + A conversion pattern which includes Time, Thread, Logger, and Nested Context. + Current value is <b>%timestamp [%thread] %level %logger %ndc - %message%newline</b>. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.PatternLayout.s_globalRulesRegistry"> + <summary> + Internal map of converter identifiers to converter types. + </summary> + <remarks> + <para> + This static map is overridden by the m_converterRegistry instance map + </para> + </remarks> + </member> + <member name="F:log4net.Layout.PatternLayout.m_pattern"> + <summary> + the pattern + </summary> + </member> + <member name="F:log4net.Layout.PatternLayout.m_head"> + <summary> + the head of the pattern converter chain + </summary> + </member> + <member name="F:log4net.Layout.PatternLayout.m_instanceRulesRegistry"> + <summary> + patterns defined on this PatternLayout only + </summary> + </member> + <member name="M:log4net.Layout.PatternLayout.#cctor"> + <summary> + Initialize the global registry + </summary> + <remarks> + <para> + Defines the builtin global rules. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.#ctor"> + <summary> + Constructs a PatternLayout using the DefaultConversionPattern + </summary> + <remarks> + <para> + The default pattern just produces the application supplied message. + </para> + <para> + Note to Inheritors: This constructor calls the virtual method + <see cref="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"/>. If you override this method be + aware that it will be called before your is called constructor. + </para> + <para> + As per the <see cref="T:log4net.Core.IOptionHandler"/> contract the <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> + method must be called after the properties on this object have been + configured. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.#ctor(System.String)"> + <summary> + Constructs a PatternLayout using the supplied conversion pattern + </summary> + <param name="pattern">the pattern to use</param> + <remarks> + <para> + Note to Inheritors: This constructor calls the virtual method + <see cref="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"/>. If you override this method be + aware that it will be called before your is called constructor. + </para> + <para> + When using this constructor the <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> method + need not be called. This may not be the case when using a subclass. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"> + <summary> + Create the pattern parser instance + </summary> + <param name="pattern">the pattern to parse</param> + <returns>The <see cref="T:log4net.Util.PatternParser"/> that will format the event</returns> + <remarks> + <para> + Creates the <see cref="T:log4net.Util.PatternParser"/> used to parse the conversion string. Sets the + global and instance rules on the <see cref="T:log4net.Util.PatternParser"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.ActivateOptions"> + <summary> + Initialize layout options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.PatternLayout.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="M:log4net.Layout.PatternLayout.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Produces a formatted string as specified by the conversion pattern. + </summary> + <param name="loggingEvent">the event being logged</param> + <param name="writer">The TextWriter to write the formatted event to</param> + <remarks> + <para> + Parse the <see cref="T:log4net.Core.LoggingEvent"/> using the patter format + specified in the <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/> property. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.AddConverter(log4net.Layout.PatternLayout.ConverterInfo)"> + <summary> + Add a converter to this PatternLayout + </summary> + <param name="converterInfo">the converter info</param> + <remarks> + <para> + This version of the method is used by the configurator. + Programmatic users should use the alternative <see cref="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"/> method. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"> + <summary> + Add a converter to this PatternLayout + </summary> + <param name="name">the name of the conversion pattern for this converter</param> + <param name="type">the type of the converter</param> + <remarks> + <para> + Add a named pattern converter to this instance. This + converter will be used in the formatting of the event. + This method must be called before <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/>. + </para> + <para> + The <paramref name="type"/> specified must extend the + <see cref="T:log4net.Util.PatternConverter"/> type. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.PatternLayout.ConversionPattern"> + <summary> + The pattern formatting string + </summary> + <remarks> + <para> + The <b>ConversionPattern</b> option. This is the string which + controls formatting and consists of a mix of literal content and + conversion specifiers. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.PatternLayout.ConverterInfo"> + <summary> + Wrapper class used to map converter names to converter types + </summary> + <remarks> + <para> + Pattern converter info class used during configuration to + pass to the <see cref="M:log4net.Layout.PatternLayout.AddConverter(log4net.Layout.PatternLayout.ConverterInfo)"/> + method. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.PatternLayout.ConverterInfo.#ctor"> + <summary> + default constructor + </summary> + </member> + <member name="P:log4net.Layout.PatternLayout.ConverterInfo.Name"> + <summary> + Gets or sets the name of the conversion pattern + </summary> + <remarks> + <para> + The name of the pattern in the format string + </para> + </remarks> + </member> + <member name="P:log4net.Layout.PatternLayout.ConverterInfo.Type"> + <summary> + Gets or sets the type of the converter + </summary> + <remarks> + <para> + The value specified must extend the + <see cref="T:log4net.Util.PatternConverter"/> type. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.RawLayoutConverter"> + <summary> + Type converter for the <see cref="T:log4net.Layout.IRawLayout"/> interface + </summary> + <remarks> + <para> + Used to convert objects to the <see cref="T:log4net.Layout.IRawLayout"/> interface. + Supports converting from the <see cref="T:log4net.Layout.ILayout"/> interface to + the <see cref="T:log4net.Layout.IRawLayout"/> interface using the <see cref="T:log4net.Layout.Layout2RawLayoutAdapter"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Util.TypeConverters.IConvertFrom"> + <summary> + Interface supported by type converters + </summary> + <remarks> + <para> + This interface supports conversion from arbitrary types + to a single target type. See <see cref="T:log4net.Util.TypeConverters.TypeConverterAttribute"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.TypeConverters.IConvertFrom.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Test if the <paramref name="sourceType"/> can be converted to the + type supported by this converter. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.IConvertFrom.ConvertFrom(System.Object)"> + <summary> + Convert the source object to the type supported by this object + </summary> + <param name="source">the object to convert</param> + <returns>the converted object</returns> + <remarks> + <para> + Converts the <paramref name="source"/> to the type supported + by this converter. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.RawLayoutConverter.CanConvertFrom(System.Type)"> + <summary> + Can the sourceType be converted to an <see cref="T:log4net.Layout.IRawLayout"/> + </summary> + <param name="sourceType">the source to be to be converted</param> + <returns><c>true</c> if the source type can be converted to <see cref="T:log4net.Layout.IRawLayout"/></returns> + <remarks> + <para> + Test if the <paramref name="sourceType"/> can be converted to a + <see cref="T:log4net.Layout.IRawLayout"/>. Only <see cref="T:log4net.Layout.ILayout"/> is supported + as the <paramref name="sourceType"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.RawLayoutConverter.ConvertFrom(System.Object)"> + <summary> + Convert the value to a <see cref="T:log4net.Layout.IRawLayout"/> object + </summary> + <param name="source">the value to convert</param> + <returns>the <see cref="T:log4net.Layout.IRawLayout"/> object</returns> + <remarks> + <para> + Convert the <paramref name="source"/> object to a + <see cref="T:log4net.Layout.IRawLayout"/> object. If the <paramref name="source"/> object + is a <see cref="T:log4net.Layout.ILayout"/> then the <see cref="T:log4net.Layout.Layout2RawLayoutAdapter"/> + is used to adapt between the two interfaces, otherwise an + exception is thrown. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.RawPropertyLayout"> + <summary> + Extract the value of a property from the <see cref="T:log4net.Core.LoggingEvent"/> + </summary> + <remarks> + <para> + Extract the value of a property from the <see cref="T:log4net.Core.LoggingEvent"/> + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Layout.RawPropertyLayout.#ctor"> + <summary> + Constructs a RawPropertyLayout + </summary> + </member> + <member name="M:log4net.Layout.RawPropertyLayout.Format(log4net.Core.LoggingEvent)"> + <summary> + Lookup the property for <see cref="P:log4net.Layout.RawPropertyLayout.Key"/> + </summary> + <param name="loggingEvent">The event to format</param> + <returns>returns property value</returns> + <remarks> + <para> + Looks up and returns the object value of the property + named <see cref="P:log4net.Layout.RawPropertyLayout.Key"/>. If there is no property defined + with than name then <c>null</c> will be returned. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.RawPropertyLayout.Key"> + <summary> + The name of the value to lookup in the LoggingEvent Properties collection. + </summary> + <value> + Value to lookup in the LoggingEvent Properties collection + </value> + <remarks> + <para> + String name of the property to lookup in the <see cref="T:log4net.Core.LoggingEvent"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.RawTimeStampLayout"> + <summary> + Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/> + </summary> + <remarks> + <para> + Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/> + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Layout.RawTimeStampLayout.#ctor"> + <summary> + Constructs a RawTimeStampLayout + </summary> + </member> + <member name="M:log4net.Layout.RawTimeStampLayout.Format(log4net.Core.LoggingEvent)"> + <summary> + Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>. + </summary> + <param name="loggingEvent">The event to format</param> + <returns>returns the time stamp</returns> + <remarks> + <para> + Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>. + </para> + <para> + The time stamp is in local time. To format the time stamp + in universal time use <see cref="T:log4net.Layout.RawUtcTimeStampLayout"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.RawUtcTimeStampLayout"> + <summary> + Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/> + </summary> + <remarks> + <para> + Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/> + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Layout.RawUtcTimeStampLayout.#ctor"> + <summary> + Constructs a RawUtcTimeStampLayout + </summary> + </member> + <member name="M:log4net.Layout.RawUtcTimeStampLayout.Format(log4net.Core.LoggingEvent)"> + <summary> + Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>. + </summary> + <param name="loggingEvent">The event to format</param> + <returns>returns the time stamp</returns> + <remarks> + <para> + Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>. + </para> + <para> + The time stamp is in universal time. To format the time stamp + in local time use <see cref="T:log4net.Layout.RawTimeStampLayout"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.SimpleLayout"> + <summary> + A very simple layout + </summary> + <remarks> + <para> + SimpleLayout consists of the level of the log statement, + followed by " - " and then the log message itself. For example, + <code> + DEBUG - Hello world + </code> + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Layout.SimpleLayout.#ctor"> + <summary> + Constructs a SimpleLayout + </summary> + </member> + <member name="M:log4net.Layout.SimpleLayout.ActivateOptions"> + <summary> + Initialize layout options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.SimpleLayout.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="M:log4net.Layout.SimpleLayout.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.SimpleLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <summary> + Produces a simple formatted output. + </summary> + <param name="loggingEvent">the event being logged</param> + <param name="writer">The TextWriter to write the formatted event to</param> + <remarks> + <para> + Formats the event as the level of the even, + followed by " - " and then the log message itself. The + output is terminated by a newline. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.XmlLayout"> + <summary> + Layout that formats the log events as XML elements. + </summary> + <remarks> + <para> + The output of the <see cref="T:log4net.Layout.XmlLayout"/> consists of a series of + log4net:event elements. It does not output a complete well-formed XML + file. The output is designed to be included as an <em>external entity</em> + in a separate file to form a correct XML file. + </para> + <para> + For example, if <c>abc</c> is the name of the file where + the <see cref="T:log4net.Layout.XmlLayout"/> output goes, then a well-formed XML file would + be: + </para> + <code lang="XML"> + <?xml version="1.0" ?> + + <!DOCTYPE log4net:events SYSTEM "log4net-events.dtd" [<!ENTITY data SYSTEM "abc">]> + + <log4net:events version="1.2" xmlns:log4net="http://logging.apache.org/log4net/schemas/log4net-events-1.2> + &data; + </log4net:events> + </code> + <para> + This approach enforces the independence of the <see cref="T:log4net.Layout.XmlLayout"/> + and the appender where it is embedded. + </para> + <para> + The <c>version</c> attribute helps components to correctly + interpret output generated by <see cref="T:log4net.Layout.XmlLayout"/>. The value of + this attribute should be "1.2" for release 1.2 and later. + </para> + <para> + Alternatively the <c>Header</c> and <c>Footer</c> properties can be + configured to output the correct XML header, open tag and close tag. + When setting the <c>Header</c> and <c>Footer</c> properties it is essential + that the underlying data store not be appendable otherwise the data + will become invalid XML. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Layout.XmlLayoutBase"> + <summary> + Layout that formats the log events as XML elements. + </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="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Layout.XmlLayoutBase.#ctor"> + <summary> + Protected constructor to support subclasses + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Layout.XmlLayoutBase"/> class + with no location info. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.XmlLayoutBase.#ctor(System.Boolean)"> + <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> + </member> + <member name="M:log4net.Layout.XmlLayoutBase.ActivateOptions"> + <summary> + Initialize layout options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.XmlLayoutBase.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="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.XmlLayoutBase.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"> + <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="T:log4net.Core.LoggingEvent"/> and write it to the <see cref="T:System.IO.TextWriter"/>. + </para> + <para> + This method creates an <see cref="T:System.Xml.XmlTextWriter"/> that writes to the + <paramref name="writer"/>. The <see cref="T:System.Xml.XmlTextWriter"/> is passed + to the <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method. Subclasses should override the + <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method rather than this method. + </para> + </remarks> + </member> + <member name="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"> + <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="T:log4net.Core.LoggingEvent"/> as XML. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.XmlLayoutBase.m_locationInfo"> + <summary> + Flag to indicate if location information should be included in + the XML events. + </summary> + </member> + <member name="F:log4net.Layout.XmlLayoutBase.m_protectCloseTextWriter"> + <summary> + Writer adapter that ignores Close + </summary> + </member> + <member name="F:log4net.Layout.XmlLayoutBase.m_invalidCharReplacement"> + <summary> + The string to replace invalid chars with + </summary> + </member> + <member name="P:log4net.Layout.XmlLayoutBase.LocationInfo"> + <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="P:log4net.Layout.XmlLayoutBase.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> + </member> + <member name="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"> + <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> + </member> + <member name="P:log4net.Layout.XmlLayoutBase.ContentType"> + <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> + </member> + <member name="M:log4net.Layout.XmlLayout.#ctor"> + <summary> + Constructs an XmlLayout + </summary> + </member> + <member name="M:log4net.Layout.XmlLayout.#ctor(System.Boolean)"> + <summary> + Constructs an XmlLayout. + </summary> + <remarks> + <para> + The <b>LocationInfo</b> 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. + </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> + </member> + <member name="M:log4net.Layout.XmlLayout.ActivateOptions"> + <summary> + Initialize layout options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Layout.XmlLayout.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="M:log4net.Layout.XmlLayout.ActivateOptions"/> must be called again. + </para> + <para> + Builds a cache of the element names + </para> + </remarks> + </member> + <member name="M:log4net.Layout.XmlLayout.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"> + <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> + Override the base class <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method + to write the <see cref="T:log4net.Core.LoggingEvent"/> to the <see cref="T:System.Xml.XmlWriter"/>. + </para> + </remarks> + </member> + <member name="F:log4net.Layout.XmlLayout.m_prefix"> + <summary> + The prefix to use for all generated element names + </summary> + </member> + <member name="P:log4net.Layout.XmlLayout.Prefix"> + <summary> + The prefix to use for all element names + </summary> + <remarks> + <para> + The default prefix is <b>log4net</b>. Set this property + to change the prefix. If the prefix is set to an empty string + then no prefix will be written. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.XmlLayout.Base64EncodeMessage"> + <summary> + Set whether or not to base64 encode the message. + </summary> + <remarks> + <para> + By default the log message will be written as text to the xml + output. This can cause problems when the message contains binary + data. By setting this to true the contents of the message will be + base64 encoded. If this is set then invalid character replacement + (see <see cref="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"/>) will not be performed + on the log message. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.XmlLayout.Base64EncodeProperties"> + <summary> + Set whether or not to base64 encode the property values. + </summary> + <remarks> + <para> + By default the properties will be written as text to the xml + output. This can cause problems when one or more properties contain + binary data. By setting this to true the values of the properties + will be base64 encoded. If this is set then invalid character replacement + (see <see cref="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"/>) will not be performed + on the property values. + </para> + </remarks> + </member> + <member name="T:log4net.Layout.XmlLayoutSchemaLog4j"> + <summary> + Layout that formats the log events as XML elements compatible with the log4j schema + </summary> + <remarks> + <para> + Formats the log events according to the http://logging.apache.org/log4j schema. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Layout.XmlLayoutSchemaLog4j.s_date1970"> + <summary> + The 1st of January 1970 in UTC + </summary> + </member> + <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.#ctor"> + <summary> + Constructs an XMLLayoutSchemaLog4j + </summary> + </member> + <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.#ctor(System.Boolean)"> + <summary> + Constructs an XMLLayoutSchemaLog4j. + </summary> + <remarks> + <para> + The <b>LocationInfo</b> 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. + </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> + </member> + <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"> + <summary> + Actually do the writing of the xml + </summary> + <param name="writer">the writer to use</param> + <param name="loggingEvent">the event to write</param> + <remarks> + <para> + Generate XML that is compatible with the log4j schema. + </para> + </remarks> + </member> + <member name="P:log4net.Layout.XmlLayoutSchemaLog4j.Version"> + <summary> + The version of the log4j schema to use. + </summary> + <remarks> + <para> + Only version 1.2 of the log4j schema is supported. + </para> + </remarks> + </member> + <member name="T:log4net.ObjectRenderer.DefaultRenderer"> + <summary> + The default object Renderer. + </summary> + <remarks> + <para> + The default renderer supports rendering objects and collections to strings. + </para> + <para> + See the <see cref="M:log4net.ObjectRenderer.DefaultRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)"/> method for details of the output. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.ObjectRenderer.IObjectRenderer"> + <summary> + Implement this interface in order to render objects as strings + </summary> + <remarks> + <para> + Certain types require special case conversion to + string form. This conversion is done by an object renderer. + Object renderers implement the <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> + interface. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.ObjectRenderer.IObjectRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)"> + <summary> + Render the object <paramref name="obj"/> to a string + </summary> + <param name="rendererMap">The map used to lookup renderers</param> + <param name="obj">The object to render</param> + <param name="writer">The writer to render to</param> + <remarks> + <para> + Render the object <paramref name="obj"/> to a + string. + </para> + <para> + The <paramref name="rendererMap"/> parameter is + provided to lookup and render other objects. This is + very useful where <paramref name="obj"/> contains + nested objects of unknown type. The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"/> + method can be used to render these objects. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.DefaultRenderer.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)"> + <summary> + Render the object <paramref name="obj"/> to a string + </summary> + <param name="rendererMap">The map used to lookup renderers</param> + <param name="obj">The object to render</param> + <param name="writer">The writer to render to</param> + <remarks> + <para> + Render the object <paramref name="obj"/> to a string. + </para> + <para> + The <paramref name="rendererMap"/> parameter is + provided to lookup and render other objects. This is + very useful where <paramref name="obj"/> contains + nested objects of unknown type. The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"/> + method can be used to render these objects. + </para> + <para> + The default renderer supports rendering objects to strings as follows: + </para> + <list type="table"> + <listheader> + <term>Value</term> + <description>Rendered String</description> + </listheader> + <item> + <term><c>null</c></term> + <description> + <para>"(null)"</para> + </description> + </item> + <item> + <term><see cref="T:System.Array"/></term> + <description> + <para> + For a one dimensional array this is the + array type name, an open brace, followed by a comma + separated list of the elements (using the appropriate + renderer), followed by a close brace. + </para> + <para> + For example: <c>int[] {1, 2, 3}</c>. + </para> + <para> + If the array is not one dimensional the + <c>Array.ToString()</c> is returned. + </para> + </description> + </item> + <item> + <term><see cref="T:System.Collections.IEnumerable"/>, <see cref="T:System.Collections.ICollection"/> & <see cref="T:System.Collections.IEnumerator"/></term> + <description> + <para> + Rendered as an open brace, followed by a comma + separated list of the elements (using the appropriate + renderer), followed by a close brace. + </para> + <para> + For example: <c>{a, b, c}</c>. + </para> + <para> + All collection classes that implement <see cref="T:System.Collections.ICollection"/> its subclasses, + or generic equivalents all implement the <see cref="T:System.Collections.IEnumerable"/> interface. + </para> + </description> + </item> + <item> + <term><see cref="T:System.Collections.DictionaryEntry"/></term> + <description> + <para> + Rendered as the key, an equals sign ('='), and the value (using the appropriate + renderer). + </para> + <para> + For example: <c>key=value</c>. + </para> + </description> + </item> + <item> + <term>other</term> + <description> + <para><c>Object.ToString()</c></para> + </description> + </item> + </list> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderArray(log4net.ObjectRenderer.RendererMap,System.Array,System.IO.TextWriter)"> + <summary> + Render the array argument into a string + </summary> + <param name="rendererMap">The map used to lookup renderers</param> + <param name="array">the array to render</param> + <param name="writer">The writer to render to</param> + <remarks> + <para> + For a one dimensional array this is the + array type name, an open brace, followed by a comma + separated list of the elements (using the appropriate + renderer), followed by a close brace. For example: + <c>int[] {1, 2, 3}</c>. + </para> + <para> + If the array is not one dimensional the + <c>Array.ToString()</c> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderEnumerator(log4net.ObjectRenderer.RendererMap,System.Collections.IEnumerator,System.IO.TextWriter)"> + <summary> + Render the enumerator argument into a string + </summary> + <param name="rendererMap">The map used to lookup renderers</param> + <param name="enumerator">the enumerator to render</param> + <param name="writer">The writer to render to</param> + <remarks> + <para> + Rendered as an open brace, followed by a comma + separated list of the elements (using the appropriate + renderer), followed by a close brace. For example: + <c>{a, b, c}</c>. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderDictionaryEntry(log4net.ObjectRenderer.RendererMap,System.Collections.DictionaryEntry,System.IO.TextWriter)"> + <summary> + Render the DictionaryEntry argument into a string + </summary> + <param name="rendererMap">The map used to lookup renderers</param> + <param name="entry">the DictionaryEntry to render</param> + <param name="writer">The writer to render to</param> + <remarks> + <para> + Render the key, an equals sign ('='), and the value (using the appropriate + renderer). For example: <c>key=value</c>. + </para> + </remarks> + </member> + <member name="T:log4net.ObjectRenderer.RendererMap"> + <summary> + Map class objects to an <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. + </summary> + <remarks> + <para> + Maintains a mapping between types that require special + rendering and the <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> that + is used to render them. + </para> + <para> + The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"/> method is used to render an + <c>object</c> using the appropriate renderers defined in this map. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.#ctor"> + <summary> + Default Constructor + </summary> + <remarks> + <para> + Default constructor. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"> + <summary> + Render <paramref name="obj"/> using the appropriate renderer. + </summary> + <param name="obj">the object to render to a string</param> + <returns>the object rendered as a string</returns> + <remarks> + <para> + This is a convenience method used to render an object to a string. + The alternative method <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"/> + should be used when streaming output to a <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"> + <summary> + Render <paramref name="obj"/> using the appropriate renderer. + </summary> + <param name="obj">the object to render to a string</param> + <param name="writer">The writer to render to</param> + <remarks> + <para> + Find the appropriate renderer for the type of the + <paramref name="obj"/> parameter. This is accomplished by calling the + <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/> method. Once a renderer is found, it is + applied on the object <paramref name="obj"/> and the result is returned + as a <see cref="T:System.String"/>. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.Get(System.Object)"> + <summary> + Gets the renderer for the specified object type + </summary> + <param name="obj">the object to lookup the renderer for</param> + <returns>the renderer for <paramref name="obj"/></returns> + <remarks> + <param> + Gets the renderer for the specified object type. + </param> + <param> + Syntactic sugar method that calls <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/> + with the type of the object parameter. + </param> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"> + <summary> + Gets the renderer for the specified type + </summary> + <param name="type">the type to lookup the renderer for</param> + <returns>the renderer for the specified type</returns> + <remarks> + <para> + Returns the renderer for the specified type. + If no specific renderer has been defined the + <see cref="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"/> will be returned. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.SearchTypeAndInterfaces(System.Type)"> + <summary> + Internal function to recursively search interfaces + </summary> + <param name="type">the type to lookup the renderer for</param> + <returns>the renderer for the specified type</returns> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.Clear"> + <summary> + Clear the map of renderers + </summary> + <remarks> + <para> + Clear the custom renderers defined by using + <see cref="M:log4net.ObjectRenderer.RendererMap.Put(System.Type,log4net.ObjectRenderer.IObjectRenderer)"/>. The <see cref="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"/> + cannot be removed. + </para> + </remarks> + </member> + <member name="M:log4net.ObjectRenderer.RendererMap.Put(System.Type,log4net.ObjectRenderer.IObjectRenderer)"> + <summary> + Register an <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> for <paramref name="typeToRender"/>. + </summary> + <param name="typeToRender">the type that will be rendered by <paramref name="renderer"/></param> + <param name="renderer">the renderer for <paramref name="typeToRender"/></param> + <remarks> + <para> + Register an object renderer for a specific source type. + This renderer will be returned from a call to <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/> + specifying the same <paramref name="typeToRender"/> as an argument. + </para> + </remarks> + </member> + <member name="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"> + <summary> + Get the default renderer instance + </summary> + <value>the default renderer</value> + <remarks> + <para> + Get the default renderer + </para> + </remarks> + </member> + <member name="T:log4net.Plugin.IPlugin"> + <summary> + Interface implemented by logger repository plugins. + </summary> + <remarks> + <para> + Plugins define additional behavior that can be associated + with a <see cref="T:log4net.Repository.ILoggerRepository"/>. + The <see cref="T:log4net.Plugin.PluginMap"/> held by the <see cref="P:log4net.Repository.ILoggerRepository.PluginMap"/> + property is used to store the plugins for a repository. + </para> + <para> + The <c>log4net.Config.PluginAttribute</c> can be used to + attach plugins to repositories created using configuration + attributes. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Plugin.IPlugin.Attach(log4net.Repository.ILoggerRepository)"> + <summary> + Attaches the plugin to the specified <see cref="T:log4net.Repository.ILoggerRepository"/>. + </summary> + <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param> + <remarks> + <para> + A plugin may only be attached to a single repository. + </para> + <para> + This method is called when the plugin is attached to the repository. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.IPlugin.Shutdown"> + <summary> + Is called when the plugin is to shutdown. + </summary> + <remarks> + <para> + This method is called to notify the plugin that + it should stop operating and should detach from + the repository. + </para> + </remarks> + </member> + <member name="P:log4net.Plugin.IPlugin.Name"> + <summary> + Gets the name of the plugin. + </summary> + <value> + The name of the plugin. + </value> + <remarks> + <para> + Plugins are stored in the <see cref="T:log4net.Plugin.PluginMap"/> + keyed by name. Each plugin instance attached to a + repository must be a unique name. + </para> + </remarks> + </member> + <member name="T:log4net.Plugin.PluginCollection"> + <summary> + A strongly-typed collection of <see cref="T:log4net.Plugin.IPlugin"/> objects. + </summary> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Plugin.PluginCollection.ReadOnly(log4net.Plugin.PluginCollection)"> + <summary> + Creates a read-only wrapper for a <c>PluginCollection</c> instance. + </summary> + <param name="list">list to create a readonly wrapper arround</param> + <returns> + A <c>PluginCollection</c> wrapper that is read-only. + </returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.#ctor"> + <summary> + Initializes a new instance of the <c>PluginCollection</c> class + that is empty and has the default initial capacity. + </summary> + </member> + <member name="M:log4net.Plugin.PluginCollection.#ctor(System.Int32)"> + <summary> + Initializes a new instance of the <c>PluginCollection</c> class + that has the specified initial capacity. + </summary> + <param name="capacity"> + The number of elements that the new <c>PluginCollection</c> is initially capable of storing. + </param> + </member> + <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.PluginCollection)"> + <summary> + Initializes a new instance of the <c>PluginCollection</c> class + that contains elements copied from the specified <c>PluginCollection</c>. + </summary> + <param name="c">The <c>PluginCollection</c> whose elements are copied to the new collection.</param> + </member> + <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.IPlugin[])"> + <summary> + Initializes a new instance of the <c>PluginCollection</c> class + that contains elements copied from the specified <see cref="T:log4net.Plugin.IPlugin"/> array. + </summary> + <param name="a">The <see cref="T:log4net.Plugin.IPlugin"/> array whose elements are copied to the new list.</param> + </member> + <member name="M:log4net.Plugin.PluginCollection.#ctor(System.Collections.ICollection)"> + <summary> + Initializes a new instance of the <c>PluginCollection</c> class + that contains elements copied from the specified <see cref="T:log4net.Plugin.IPlugin"/> collection. + </summary> + <param name="col">The <see cref="T:log4net.Plugin.IPlugin"/> collection whose elements are copied to the new list.</param> + </member> + <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.PluginCollection.Tag)"> + <summary> + Allow subclasses to avoid our default constructors + </summary> + <param name="tag"></param> + <exclude/> + </member> + <member name="M:log4net.Plugin.PluginCollection.CopyTo(log4net.Plugin.IPlugin[])"> + <summary> + Copies the entire <c>PluginCollection</c> to a one-dimensional + <see cref="T:log4net.Plugin.IPlugin"/> array. + </summary> + <param name="array">The one-dimensional <see cref="T:log4net.Plugin.IPlugin"/> array to copy to.</param> + </member> + <member name="M:log4net.Plugin.PluginCollection.CopyTo(log4net.Plugin.IPlugin[],System.Int32)"> + <summary> + Copies the entire <c>PluginCollection</c> to a one-dimensional + <see cref="T:log4net.Plugin.IPlugin"/> array, starting at the specified index of the target array. + </summary> + <param name="array">The one-dimensional <see cref="T:log4net.Plugin.IPlugin"/> array to copy to.</param> + <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param> + </member> + <member name="M:log4net.Plugin.PluginCollection.Add(log4net.Plugin.IPlugin)"> + <summary> + Adds a <see cref="T:log4net.Plugin.IPlugin"/> to the end of the <c>PluginCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to be added to the end of the <c>PluginCollection</c>.</param> + <returns>The index at which the value has been added.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.Clear"> + <summary> + Removes all elements from the <c>PluginCollection</c>. + </summary> + </member> + <member name="M:log4net.Plugin.PluginCollection.Clone"> + <summary> + Creates a shallow copy of the <see cref="T:log4net.Plugin.PluginCollection"/>. + </summary> + <returns>A new <see cref="T:log4net.Plugin.PluginCollection"/> with a shallow copy of the collection data.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.Contains(log4net.Plugin.IPlugin)"> + <summary> + Determines whether a given <see cref="T:log4net.Plugin.IPlugin"/> is in the <c>PluginCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to check for.</param> + <returns><c>true</c> if <paramref name="item"/> is found in the <c>PluginCollection</c>; otherwise, <c>false</c>.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.IndexOf(log4net.Plugin.IPlugin)"> + <summary> + Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Plugin.IPlugin"/> + in the <c>PluginCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to locate in the <c>PluginCollection</c>.</param> + <returns> + The zero-based index of the first occurrence of <paramref name="item"/> + in the entire <c>PluginCollection</c>, if found; otherwise, -1. + </returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.Insert(System.Int32,log4net.Plugin.IPlugin)"> + <summary> + Inserts an element into the <c>PluginCollection</c> at the specified index. + </summary> + <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param> + <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to insert.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Plugin.PluginCollection.Remove(log4net.Plugin.IPlugin)"> + <summary> + Removes the first occurrence of a specific <see cref="T:log4net.Plugin.IPlugin"/> from the <c>PluginCollection</c>. + </summary> + <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to remove from the <c>PluginCollection</c>.</param> + <exception cref="T:System.ArgumentException"> + The specified <see cref="T:log4net.Plugin.IPlugin"/> was not found in the <c>PluginCollection</c>. + </exception> + </member> + <member name="M:log4net.Plugin.PluginCollection.RemoveAt(System.Int32)"> + <summary> + Removes the element at the specified index of the <c>PluginCollection</c>. + </summary> + <param name="index">The zero-based index of the element to remove.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero.</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Plugin.PluginCollection.GetEnumerator"> + <summary> + Returns an enumerator that can iterate through the <c>PluginCollection</c>. + </summary> + <returns>An <see cref="T:log4net.Plugin.PluginCollection.Enumerator"/> for the entire <c>PluginCollection</c>.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.AddRange(log4net.Plugin.PluginCollection)"> + <summary> + Adds the elements of another <c>PluginCollection</c> to the current <c>PluginCollection</c>. + </summary> + <param name="x">The <c>PluginCollection</c> whose elements should be added to the end of the current <c>PluginCollection</c>.</param> + <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.AddRange(log4net.Plugin.IPlugin[])"> + <summary> + Adds the elements of a <see cref="T:log4net.Plugin.IPlugin"/> array to the current <c>PluginCollection</c>. + </summary> + <param name="x">The <see cref="T:log4net.Plugin.IPlugin"/> array whose elements should be added to the end of the <c>PluginCollection</c>.</param> + <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.AddRange(System.Collections.ICollection)"> + <summary> + Adds the elements of a <see cref="T:log4net.Plugin.IPlugin"/> collection to the current <c>PluginCollection</c>. + </summary> + <param name="col">The <see cref="T:log4net.Plugin.IPlugin"/> collection whose elements should be added to the end of the <c>PluginCollection</c>.</param> + <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns> + </member> + <member name="M:log4net.Plugin.PluginCollection.TrimToSize"> + <summary> + Sets the capacity to the actual number of elements. + </summary> + </member> + <member name="M:log4net.Plugin.PluginCollection.ValidateIndex(System.Int32)"> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero.</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para> + </exception> + </member> + <member name="M:log4net.Plugin.PluginCollection.ValidateIndex(System.Int32,System.Boolean)"> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero.</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para> + </exception> + </member> + <member name="P:log4net.Plugin.PluginCollection.Count"> + <summary> + Gets the number of elements actually contained in the <c>PluginCollection</c>. + </summary> + </member> + <member name="P:log4net.Plugin.PluginCollection.IsSynchronized"> + <summary> + Gets a value indicating whether access to the collection is synchronized (thread-safe). + </summary> + <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns> + </member> + <member name="P:log4net.Plugin.PluginCollection.SyncRoot"> + <summary> + Gets an object that can be used to synchronize access to the collection. + </summary> + <value> + An object that can be used to synchronize access to the collection. + </value> + </member> + <member name="P:log4net.Plugin.PluginCollection.Item(System.Int32)"> + <summary> + Gets or sets the <see cref="T:log4net.Plugin.IPlugin"/> at the specified index. + </summary> + <value> + The <see cref="T:log4net.Plugin.IPlugin"/> at the specified index. + </value> + <param name="index">The zero-based index of the element to get or set.</param> + <exception cref="T:System.ArgumentOutOfRangeException"> + <para><paramref name="index"/> is less than zero.</para> + <para>-or-</para> + <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para> + </exception> + </member> + <member name="P:log4net.Plugin.PluginCollection.IsFixedSize"> + <summary> + Gets a value indicating whether the collection has a fixed size. + </summary> + <value><c>true</c> if the collection has a fixed size; otherwise, <c>false</c>. The default is <c>false</c>.</value> + </member> + <member name="P:log4net.Plugin.PluginCollection.IsReadOnly"> + <summary> + Gets a value indicating whether the IList is read-only. + </summary> + <value><c>true</c> if the collection is read-only; otherwise, <c>false</c>. The default is <c>false</c>.</value> + </member> + <member name="P:log4net.Plugin.PluginCollection.Capacity"> + <summary> + Gets or sets the number of elements the <c>PluginCollection</c> can contain. + </summary> + <value> + The number of elements the <c>PluginCollection</c> can contain. + </value> + </member> + <member name="T:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator"> + <summary> + Supports type-safe iteration over a <see cref="T:log4net.Plugin.PluginCollection"/>. + </summary> + <exclude/> + </member> + <member name="M:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.MoveNext"> + <summary> + Advances the enumerator to the next element in the collection. + </summary> + <returns> + <c>true</c> if the enumerator was successfully advanced to the next element; + <c>false</c> if the enumerator has passed the end of the collection. + </returns> + <exception cref="T:System.InvalidOperationException"> + The collection was modified after the enumerator was created. + </exception> + </member> + <member name="M:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.Reset"> + <summary> + Sets the enumerator to its initial position, before the first element in the collection. + </summary> + </member> + <member name="P:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.Current"> + <summary> + Gets the current element in the collection. + </summary> + </member> + <member name="T:log4net.Plugin.PluginCollection.Tag"> + <summary> + Type visible only to our subclasses + Used to access protected constructor + </summary> + <exclude/> + </member> + <member name="F:log4net.Plugin.PluginCollection.Tag.Default"> + <summary> + A value + </summary> + </member> + <member name="T:log4net.Plugin.PluginCollection.Enumerator"> + <summary> + Supports simple iteration over a <see cref="T:log4net.Plugin.PluginCollection"/>. + </summary> + <exclude/> + </member> + <member name="M:log4net.Plugin.PluginCollection.Enumerator.#ctor(log4net.Plugin.PluginCollection)"> + <summary> + Initializes a new instance of the <c>Enumerator</c> class. + </summary> + <param name="tc"></param> + </member> + <member name="M:log4net.Plugin.PluginCollection.Enumerator.MoveNext"> + <summary> + Advances the enumerator to the next element in the collection. + </summary> + <returns> + <c>true</c> if the enumerator was successfully advanced to the next element; + <c>false</c> if the enumerator has passed the end of the collection. + </returns> + <exception cref="T:System.InvalidOperationException"> + The collection was modified after the enumerator was created. + </exception> + </member> + <member name="M:log4net.Plugin.PluginCollection.Enumerator.Reset"> + <summary> + Sets the enumerator to its initial position, before the first element in the collection. + </summary> + </member> + <member name="P:log4net.Plugin.PluginCollection.Enumerator.Current"> + <summary> + Gets the current element in the collection. + </summary> + <value> + The current element in the collection. + </value> + </member> + <member name="T:log4net.Plugin.PluginCollection.ReadOnlyPluginCollection"> + <exclude/> + </member> + <member name="T:log4net.Plugin.PluginMap"> + <summary> + Map of repository plugins. + </summary> + <remarks> + <para> + This class is a name keyed map of the plugins that are + attached to a repository. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Plugin.PluginMap.#ctor(log4net.Repository.ILoggerRepository)"> + <summary> + Constructor + </summary> + <param name="repository">The repository that the plugins should be attached to.</param> + <remarks> + <para> + Initialize a new instance of the <see cref="T:log4net.Plugin.PluginMap"/> class with a + repository that the plugins should be attached to. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.PluginMap.Add(log4net.Plugin.IPlugin)"> + <summary> + Adds a <see cref="T:log4net.Plugin.IPlugin"/> to the map. + </summary> + <param name="plugin">The <see cref="T:log4net.Plugin.IPlugin"/> to add to the map.</param> + <remarks> + <para> + The <see cref="T:log4net.Plugin.IPlugin"/> will be attached to the repository when added. + </para> + <para> + If there already exists a plugin with the same name + attached to the repository then the old plugin will + be <see cref="M:log4net.Plugin.IPlugin.Shutdown"/> and replaced with + the new plugin. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.PluginMap.Remove(log4net.Plugin.IPlugin)"> + <summary> + Removes a <see cref="T:log4net.Plugin.IPlugin"/> from the map. + </summary> + <param name="plugin">The <see cref="T:log4net.Plugin.IPlugin"/> to remove from the map.</param> + <remarks> + <para> + Remove a specific plugin from this map. + </para> + </remarks> + </member> + <member name="P:log4net.Plugin.PluginMap.Item(System.String)"> + <summary> + Gets a <see cref="T:log4net.Plugin.IPlugin"/> by name. + </summary> + <param name="name">The name of the <see cref="T:log4net.Plugin.IPlugin"/> to lookup.</param> + <returns> + The <see cref="T:log4net.Plugin.IPlugin"/> from the map with the name specified, or + <c>null</c> if no plugin is found. + </returns> + <remarks> + <para> + Lookup a plugin by name. If the plugin is not found <c>null</c> + will be returned. + </para> + </remarks> + </member> + <member name="P:log4net.Plugin.PluginMap.AllPlugins"> + <summary> + Gets all possible plugins as a list of <see cref="T:log4net.Plugin.IPlugin"/> objects. + </summary> + <value>All possible plugins as a list of <see cref="T:log4net.Plugin.IPlugin"/> objects.</value> + <remarks> + <para> + Get a collection of all the plugins defined in this map. + </para> + </remarks> + </member> + <member name="T:log4net.Plugin.PluginSkeleton"> + <summary> + Base implementation of <see cref="T:log4net.Plugin.IPlugin"/> + </summary> + <remarks> + <para> + Default abstract implementation of the <see cref="T:log4net.Plugin.IPlugin"/> + interface. This base class can be used by implementors + of the <see cref="T:log4net.Plugin.IPlugin"/> interface. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Plugin.PluginSkeleton.#ctor(System.String)"> + <summary> + Constructor + </summary> + <param name="name">the name of the plugin</param> + <remarks> + Initializes a new Plugin with the specified name. + </remarks> + </member> + <member name="M:log4net.Plugin.PluginSkeleton.Attach(log4net.Repository.ILoggerRepository)"> + <summary> + Attaches this plugin to a <see cref="T:log4net.Repository.ILoggerRepository"/>. + </summary> + <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param> + <remarks> + <para> + A plugin may only be attached to a single repository. + </para> + <para> + This method is called when the plugin is attached to the repository. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.PluginSkeleton.Shutdown"> + <summary> + Is called when the plugin is to shutdown. + </summary> + <remarks> + <para> + This method is called to notify the plugin that + it should stop operating and should detach from + the repository. + </para> + </remarks> + </member> + <member name="F:log4net.Plugin.PluginSkeleton.m_name"> + <summary> + The name of this plugin. + </summary> + </member> + <member name="F:log4net.Plugin.PluginSkeleton.m_repository"> + <summary> + The repository this plugin is attached to. + </summary> + </member> + <member name="P:log4net.Plugin.PluginSkeleton.Name"> + <summary> + Gets or sets the name of the plugin. + </summary> + <value> + The name of the plugin. + </value> + <remarks> + <para> + Plugins are stored in the <see cref="T:log4net.Plugin.PluginMap"/> + keyed by name. Each plugin instance attached to a + repository must be a unique name. + </para> + <para> + The name of the plugin must not change one the + plugin has been attached to a repository. + </para> + </remarks> + </member> + <member name="P:log4net.Plugin.PluginSkeleton.LoggerRepository"> + <summary> + The repository for this plugin + </summary> + <value> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin is attached to. + </value> + <remarks> + <para> + Gets or sets the <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin is + attached to. + </para> + </remarks> + </member> + <member name="T:log4net.Plugin.RemoteLoggingServerPlugin"> + <summary> + Plugin that listens for events from the <see cref="T:log4net.Appender.RemotingAppender"/> + </summary> + <remarks> + <para> + This plugin publishes an instance of <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/> + on a specified <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/>. This listens for logging events delivered from + a remote <see cref="T:log4net.Appender.RemotingAppender"/>. + </para> + <para> + When an event is received it is relogged within the attached repository + as if it had been raised locally. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin"/> class. + </para> + <para> + The <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/> property must be set. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.#ctor(System.String)"> + <summary> + Construct with sink Uri. + </summary> + <param name="sinkUri">The name to publish the sink under in the remoting infrastructure. + See <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/> for more details.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin"/> class + with specified name. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.Attach(log4net.Repository.ILoggerRepository)"> + <summary> + Attaches this plugin to a <see cref="T:log4net.Repository.ILoggerRepository"/>. + </summary> + <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param> + <remarks> + <para> + A plugin may only be attached to a single repository. + </para> + <para> + This method is called when the plugin is attached to the repository. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.Shutdown"> + <summary> + Is called when the plugin is to shutdown. + </summary> + <remarks> + <para> + When the plugin is shutdown the remote logging + sink is disconnected. + </para> + </remarks> + </member> + <member name="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"> + <summary> + Gets or sets the URI of this sink. + </summary> + <value> + The URI of this sink. + </value> + <remarks> + <para> + This is the name under which the object is marshaled. + <see cref="M:System.Runtime.Remoting.RemotingServices.Marshal(System.MarshalByRefObject,System.String,System.Type)"/> + </para> + </remarks> + </member> + <member name="T:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl"> + <summary> + Delivers <see cref="T:log4net.Core.LoggingEvent"/> objects to a remote sink. + </summary> + <remarks> + <para> + Internal class used to listen for logging events + and deliver them to the local repository. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.#ctor(log4net.Repository.ILoggerRepository)"> + <summary> + Constructor + </summary> + <param name="repository">The repository to log to.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl"/> for the + specified <see cref="T:log4net.Repository.ILoggerRepository"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.LogEvents(log4net.Core.LoggingEvent[])"> + <summary> + Logs the events to the repository. + </summary> + <param name="events">The events to log.</param> + <remarks> + <para> + The events passed are logged to the <see cref="T:log4net.Repository.ILoggerRepository"/> + </para> + </remarks> + </member> + <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.InitializeLifetimeService"> + <summary> + Obtains a lifetime service object to control the lifetime + policy for this instance. + </summary> + <returns><c>null</c> to indicate that this instance should live forever.</returns> + <remarks> + <para> + Obtains a lifetime service object to control the lifetime + policy for this instance. This object should live forever + therefore this implementation returns <c>null</c>. + </para> + </remarks> + </member> + <member name="F:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.m_repository"> + <summary> + The underlying <see cref="T:log4net.Repository.ILoggerRepository"/> that events should + be logged to. + </summary> + </member> + <member name="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"> + <summary> + Default implementation of <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> + </summary> + <remarks> + <para> + This default implementation of the <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> + interface is used to create the default subclass + of the <see cref="T:log4net.Repository.Hierarchy.Logger"/> object. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Repository.Hierarchy.ILoggerFactory"> + <summary> + Interface abstracts creation of <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances + </summary> + <remarks> + <para> + This interface is used by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to + create new <see cref="T:log4net.Repository.Hierarchy.Logger"/> objects. + </para> + <para> + The <see cref="M:log4net.Repository.Hierarchy.ILoggerFactory.CreateLogger(System.String)"/> method is called + to create a named <see cref="T:log4net.Repository.Hierarchy.Logger"/>. + </para> + <para> + Implement this interface to create new subclasses of <see cref="T:log4net.Repository.Hierarchy.Logger"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.Hierarchy.ILoggerFactory.CreateLogger(System.String)"> + <summary> + Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance + </summary> + <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param> + <returns>The <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance for the specified name.</returns> + <remarks> + <para> + Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance with the + specified name. + </para> + <para> + Called by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to create + new named <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances. + </para> + <para> + If the <paramref name="name"/> is <c>null</c> then the root logger + must be returned. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.CreateLogger(System.String)"> + <summary> + Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance + </summary> + <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param> + <returns>The <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance for the specified name.</returns> + <remarks> + <para> + Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance with the + specified name. + </para> + <para> + Called by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to create + new named <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances. + </para> + <para> + If the <paramref name="name"/> is <c>null</c> then the root logger + must be returned. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl"> + <summary> + Default internal subclass of <see cref="T:log4net.Repository.Hierarchy.Logger"/> + </summary> + <remarks> + <para> + This subclass has no additional behavior over the + <see cref="T:log4net.Repository.Hierarchy.Logger"/> class but does allow instances + to be created. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.Logger"> + <summary> + Implementation of <see cref="T:log4net.Core.ILogger"/> used by <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> + </summary> + <remarks> + <para> + Internal class used to provide implementation of <see cref="T:log4net.Core.ILogger"/> + interface. Applications should use <see cref="T:log4net.LogManager"/> to get + logger instances. + </para> + <para> + This is one of the central classes in the log4net implementation. One of the + distinctive features of log4net are hierarchical loggers and their + evaluation. The <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> organizes the <see cref="T:log4net.Repository.Hierarchy.Logger"/> + instances into a rooted tree hierarchy. + </para> + <para> + The <see cref="T:log4net.Repository.Hierarchy.Logger"/> class is abstract. Only concrete subclasses of + <see cref="T:log4net.Repository.Hierarchy.Logger"/> can be created. The <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> + is used to create instances of this type for the <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Aspi Havewala</author> + <author>Douglas de la Torre</author> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.#ctor(System.String)"> + <summary> + This constructor created a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance and + sets its name. + </summary> + <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param> + <remarks> + <para> + This constructor is protected and designed to be used by + a subclass that is not abstract. + </para> + <para> + Loggers are constructed by <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> + objects. See <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"/> for the default + logger creator. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.AddAppender(log4net.Appender.IAppender)"> + <summary> + Add <paramref name="newAppender"/> to the list of appenders of this + Logger instance. + </summary> + <param name="newAppender">An appender to add to this logger</param> + <remarks> + <para> + Add <paramref name="newAppender"/> to the list of appenders of this + Logger instance. + </para> + <para> + If <paramref name="newAppender"/> is already in the list of + appenders, then it won't be added again. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.GetAppender(System.String)"> + <summary> + Look for the appender named as <c>name</c> + </summary> + <param name="name">The name of the appender to lookup</param> + <returns>The appender with the name specified, or <c>null</c>.</returns> + <remarks> + <para> + Returns the named appender, or null if the appender is not found. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAllAppenders"> + <summary> + Remove all previously added appenders from this Logger instance. + </summary> + <remarks> + <para> + Remove all previously added appenders from this Logger instance. + </para> + <para> + This is useful when re-reading configuration information. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAppender(log4net.Appender.IAppender)"> + <summary> + Remove the appender passed as parameter form the list of appenders. + </summary> + <param name="appender">The appender to remove</param> + <returns>The appender removed from the list</returns> + <remarks> + <para> + Remove the appender passed as parameter form the list of appenders. + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAppender(System.String)"> + <summary> + Remove the appender passed as parameter form the list of appenders. + </summary> + <param name="name">The name of the appender to remove</param> + <returns>The appender removed from the list</returns> + <remarks> + <para> + Remove the named appender passed as parameter form the list of appenders. + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.Log(System.Type,log4net.Core.Level,System.Object,System.Exception)"> + <summary> + This generic form is intended to be used by wrappers. + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <param name="level">The level of the message to be logged.</param> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Generate a logging event for the specified <paramref name="level"/> using + the <paramref name="message"/> and <paramref name="exception"/>. + </para> + <para> + This method must not throw any exception to the caller. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.Log(log4net.Core.LoggingEvent)"> + <summary> + This is the most generic printing method that is intended to be used + by wrappers. + </summary> + <param name="logEvent">The event being logged.</param> + <remarks> + <para> + Logs the specified logging event through this logger. + </para> + <para> + This method must not throw any exception to the caller. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.IsEnabledFor(log4net.Core.Level)"> + <summary> + Checks if this logger is enabled for a given <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> passed as parameter. + </summary> + <param name="level">The level to check.</param> + <returns> + <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>. + </returns> + <remarks> + <para> + Test if this logger is going to log events of the specified <paramref name="level"/>. + </para> + <para> + This method must not throw any exception to the caller. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.CallAppenders(log4net.Core.LoggingEvent)"> + <summary> + Deliver the <see cref="T:log4net.Core.LoggingEvent"/> to the attached appenders. + </summary> + <param name="loggingEvent">The event to log.</param> + <remarks> + <para> + Call the appenders in the hierarchy starting at + <c>this</c>. If no appenders could be found, emit a + warning. + </para> + <para> + This method calls all the appenders inherited from the + hierarchy circumventing any evaluation of whether to log or not + to log the particular log request. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.CloseNestedAppenders"> + <summary> + Closes all attached appenders implementing the <see cref="T:log4net.Core.IAppenderAttachable"/> interface. + </summary> + <remarks> + <para> + Used to ensure that the appenders are correctly shutdown. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.Log(log4net.Core.Level,System.Object,System.Exception)"> + <summary> + This is the most generic printing method. This generic form is intended to be used by wrappers + </summary> + <param name="level">The level of the message to be logged.</param> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Generate a logging event for the specified <paramref name="level"/> using + the <paramref name="message"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.ForcedLog(System.Type,log4net.Core.Level,System.Object,System.Exception)"> + <summary> + Creates a new logging event and logs the event without further checks. + </summary> + <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is + the stack boundary into the logging system for this call.</param> + <param name="level">The level of the message to be logged.</param> + <param name="message">The message object to log.</param> + <param name="exception">The exception to log, including its stack trace.</param> + <remarks> + <para> + Generates a logging event and delivers it to the attached + appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Logger.ForcedLog(log4net.Core.LoggingEvent)"> + <summary> + Creates a new logging event and logs the event without further checks. + </summary> + <param name="logEvent">The event being logged.</param> + <remarks> + <para> + Delivers the logging event to the attached appenders. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.ThisDeclaringType"> + <summary> + The fully qualified type of the Logger class. + </summary> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_name"> + <summary> + The name of this logger. + </summary> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_level"> + <summary> + The assigned level of this logger. + </summary> + <remarks> + <para> + The <c>level</c> variable need not be + assigned a value in which case it is inherited + form the hierarchy. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_parent"> + <summary> + The parent of this logger. + </summary> + <remarks> + <para> + The parent of this logger. + All loggers have at least one ancestor which is the root logger. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_hierarchy"> + <summary> + Loggers need to know what Hierarchy they are in. + </summary> + <remarks> + <para> + Loggers need to know what Hierarchy they are in. + The hierarchy that this logger is a member of is stored + here. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_appenderAttachedImpl"> + <summary> + Helper implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface + </summary> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_additive"> + <summary> + Flag indicating if child loggers inherit their parents appenders + </summary> + <remarks> + <para> + Additivity is set to true by default, that is children inherit + the appenders of their ancestors by default. If this variable is + set to <c>false</c> then the appenders found in the + ancestors of this logger are not used. However, the children + of this logger will inherit its appenders, unless the children + have their additivity flag set to <c>false</c> too. See + the user manual for more details. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.Logger.m_appenderLock"> + <summary> + Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl + </summary> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Parent"> + <summary> + Gets or sets the parent logger in the hierarchy. + </summary> + <value> + The parent logger in the hierarchy. + </value> + <remarks> + <para> + Part of the Composite pattern that makes the hierarchy. + The hierarchy is parent linked rather than child linked. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Additivity"> + <summary> + Gets or sets a value indicating if child loggers inherit their parent's appenders. + </summary> + <value> + <c>true</c> if child loggers inherit their parent's appenders. + </value> + <remarks> + <para> + Additivity is set to <c>true</c> by default, that is children inherit + the appenders of their ancestors by default. If this variable is + set to <c>false</c> then the appenders found in the + ancestors of this logger are not used. However, the children + of this logger will inherit its appenders, unless the children + have their additivity flag set to <c>false</c> too. See + the user manual for more details. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.EffectiveLevel"> + <summary> + Gets the effective level for this logger. + </summary> + <returns>The nearest level in the logger hierarchy.</returns> + <remarks> + <para> + Starting from this logger, searches the logger hierarchy for a + non-null level and returns it. Otherwise, returns the level of the + root logger. + </para> + <para>The Logger class is designed so that this method executes as + quickly as possible.</para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Hierarchy"> + <summary> + Gets or sets the <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> where this + <c>Logger</c> instance is attached to. + </summary> + <value>The hierarchy that this logger belongs to.</value> + <remarks> + <para> + This logger must be attached to a single <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Level"> + <summary> + Gets or sets the assigned <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/>, if any, for this Logger. + </summary> + <value> + The <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> of this logger. + </value> + <remarks> + <para> + The assigned <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> can be <c>null</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Appenders"> + <summary> + Get the appenders contained in this logger as an + <see cref="T:System.Collections.ICollection"/>. + </summary> + <returns>A collection of the appenders in this logger</returns> + <remarks> + <para> + Get the appenders contained in this logger as an + <see cref="T:System.Collections.ICollection"/>. If no appenders + can be found, then a <see cref="T:log4net.Util.EmptyCollection"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Name"> + <summary> + Gets the logger name. + </summary> + <value> + The name of the logger. + </value> + <remarks> + <para> + The name of this logger + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Logger.Repository"> + <summary> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this + <c>Logger</c> instance is attached to. + </summary> + <value> + The <see cref="T:log4net.Repository.ILoggerRepository"/> that this logger belongs to. + </value> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this + <c>Logger</c> instance is attached to. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl.#ctor(System.String)"> + <summary> + Construct a new Logger + </summary> + <param name="name">the name of the logger</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl"/> class + with the specified name. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.LoggerCreationEventHandler"> + <summary> + Delegate used to handle logger creation event notifications. + </summary> + <param name="sender">The <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> in which the <see cref="T:log4net.Repository.Hierarchy.Logger"/> has been created.</param> + <param name="e">The <see cref="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"/> event args that hold the <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance that has been created.</param> + <remarks> + <para> + Delegate used to handle logger creation event notifications. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"> + <summary> + Provides data for the <see cref="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"/> event. + </summary> + <remarks> + <para> + A <see cref="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"/> event is raised every time a + <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> is created. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.LoggerCreationEventArgs.m_log"> + <summary> + The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> created + </summary> + </member> + <member name="M:log4net.Repository.Hierarchy.LoggerCreationEventArgs.#ctor(log4net.Repository.Hierarchy.Logger)"> + <summary> + Constructor + </summary> + <param name="log">The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"/> event argument + class,with the specified <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"> + <summary> + Gets the <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created. + </summary> + <value> + The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created. + </value> + <remarks> + <para> + The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.Hierarchy"> + <summary> + Hierarchical organization of loggers + </summary> + <remarks> + <para> + <i>The casual user should not have to deal with this class + directly.</i> + </para> + <para> + This class is specialized in retrieving loggers by name and + also maintaining the logger hierarchy. Implements the + <see cref="T:log4net.Repository.ILoggerRepository"/> interface. + </para> + <para> + The structure of the logger hierarchy is maintained by the + <see cref="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String)"/> method. The hierarchy is such that children + link to their parent but parents do not have any references to their + children. Moreover, loggers can be instantiated in any order, in + particular descendant before ancestor. + </para> + <para> + In case a descendant is created before a particular ancestor, + then it creates a provision node for the ancestor and adds itself + to the provision node. Other descendants of the same ancestor add + themselves to the previously created provision node. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Repository.LoggerRepositorySkeleton"> + <summary> + Base implementation of <see cref="T:log4net.Repository.ILoggerRepository"/> + </summary> + <remarks> + <para> + Default abstract implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface. + </para> + <para> + Skeleton implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface. + All <see cref="T:log4net.Repository.ILoggerRepository"/> types can extend this type. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Repository.ILoggerRepository"> + <summary> + Interface implemented by logger repositories. + </summary> + <remarks> + <para> + This interface is implemented by logger repositories. e.g. + <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>. + </para> + <para> + This interface is used by the <see cref="T:log4net.LogManager"/> + to obtain <see cref="T:log4net.ILog"/> interfaces. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.ILoggerRepository.Exists(System.String)"> + <summary> + Check if the named logger exists in the repository. If so return + its reference, otherwise returns <c>null</c>. + </summary> + <param name="name">The name of the logger to lookup</param> + <returns>The Logger object with the name specified</returns> + <remarks> + <para> + If the names logger exists it is returned, otherwise + <c>null</c> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.ILoggerRepository.GetCurrentLoggers"> + <summary> + Returns all the currently defined loggers as an Array. + </summary> + <returns>All the defined loggers</returns> + <remarks> + <para> + Returns all the currently defined loggers as an Array. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.ILoggerRepository.GetLogger(System.String)"> + <summary> + Returns a named logger instance + </summary> + <param name="name">The name of the logger to retrieve</param> + <returns>The logger object with the name specified</returns> + <remarks> + <para> + Returns a named logger instance. + </para> + <para> + If a logger of that name already exists, then it will be + returned. Otherwise, a new logger will be instantiated and + then linked with its existing ancestors as well as children. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.ILoggerRepository.Shutdown"> + <summary>Shutdown the repository</summary> + <remarks> + <para> + Shutting down a repository will <i>safely</i> close and remove + all appenders in all loggers including the root logger. + </para> + <para> + Some appenders need to be closed before the + application exists. Otherwise, pending logging events might be + lost. + </para> + <para> + The <see cref="M:log4net.Repository.ILoggerRepository.Shutdown"/> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.ILoggerRepository.ResetConfiguration"> + <summary> + Reset the repositories configuration to a default state + </summary> + <remarks> + <para> + Reset all values contained in this instance to their + default state. + </para> + <para> + Existing loggers are not removed. They are just reset. + </para> + <para> + This method should be used sparingly and with care as it will + block all logging until it is completed. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.ILoggerRepository.Log(log4net.Core.LoggingEvent)"> + <summary> + Log the <see cref="T:log4net.Core.LoggingEvent"/> through this repository. + </summary> + <param name="logEvent">the event to log</param> + <remarks> + <para> + This method should not normally be used to log. + The <see cref="T:log4net.ILog"/> interface should be used + for routine logging. This interface can be obtained + using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method. + </para> + <para> + The <c>logEvent</c> is delivered to the appropriate logger and + that logger is then responsible for logging the event. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.ILoggerRepository.GetAppenders"> + <summary> + Returns all the Appenders that are configured as an Array. + </summary> + <returns>All the Appenders</returns> + <remarks> + <para> + Returns all the Appenders that are configured as an Array. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.Name"> + <summary> + The name of the repository + </summary> + <value> + The name of the repository + </value> + <remarks> + <para> + The name of the repository. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.RendererMap"> + <summary> + RendererMap accesses the object renderer map for this repository. + </summary> + <value> + RendererMap accesses the object renderer map for this repository. + </value> + <remarks> + <para> + RendererMap accesses the object renderer map for this repository. + </para> + <para> + The RendererMap holds a mapping between types and + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> objects. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.PluginMap"> + <summary> + The plugin map for this repository. + </summary> + <value> + The plugin map for this repository. + </value> + <remarks> + <para> + The plugin map holds the <see cref="T:log4net.Plugin.IPlugin"/> instances + that have been attached to this repository. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.LevelMap"> + <summary> + Get the level map for the Repository. + </summary> + <remarks> + <para> + Get the level map for the Repository. + </para> + <para> + The level map defines the mappings between + level names and <see cref="T:log4net.Core.Level"/> objects in + this repository. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.Threshold"> + <summary> + The threshold for all events in this repository + </summary> + <value> + The threshold for all events in this repository + </value> + <remarks> + <para> + The threshold for all events in this repository. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.Configured"> + <summary> + Flag indicates if this repository has been configured. + </summary> + <value> + Flag indicates if this repository has been configured. + </value> + <remarks> + <para> + Flag indicates if this repository has been configured. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.ILoggerRepository.ShutdownEvent"> + <summary> + Event to notify that the repository has been shutdown. + </summary> + <value> + Event to notify that the repository has been shutdown. + </value> + <remarks> + <para> + Event raised when the repository has been shutdown. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.ILoggerRepository.ConfigurationReset"> + <summary> + Event to notify that the repository has had its configuration reset. + </summary> + <value> + Event to notify that the repository has had its configuration reset. + </value> + <remarks> + <para> + Event raised when the repository's configuration has been + reset to default. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.ILoggerRepository.ConfigurationChanged"> + <summary> + Event to notify that the repository has had its configuration changed. + </summary> + <value> + Event to notify that the repository has had its configuration changed. + </value> + <remarks> + <para> + Event raised when the repository's configuration has been changed. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.ILoggerRepository.Properties"> + <summary> + Repository specific properties + </summary> + <value> + Repository specific properties + </value> + <remarks> + <para> + These properties can be specified on a repository specific basis. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.#ctor"> + <summary> + Default Constructor + </summary> + <remarks> + <para> + Initializes the repository with default (empty) properties. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.#ctor(log4net.Util.PropertiesDictionary)"> + <summary> + Construct the repository using specific properties + </summary> + <param name="properties">the properties to set for this repository</param> + <remarks> + <para> + Initializes the repository with specified properties. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.Exists(System.String)"> + <summary> + Test if logger exists + </summary> + <param name="name">The name of the logger to lookup</param> + <returns>The Logger object with the name specified</returns> + <remarks> + <para> + Check if the named logger exists in the repository. If so return + its reference, otherwise returns <c>null</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetCurrentLoggers"> + <summary> + Returns all the currently defined loggers in the repository + </summary> + <returns>All the defined loggers</returns> + <remarks> + <para> + Returns all the currently defined loggers in the repository as an Array. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetLogger(System.String)"> + <summary> + Return a new logger instance + </summary> + <param name="name">The name of the logger to retrieve</param> + <returns>The logger object with the name specified</returns> + <remarks> + <para> + Return a new logger instance. + </para> + <para> + If a logger of that name already exists, then it will be + returned. Otherwise, a new logger will be instantiated and + then linked with its existing ancestors as well as children. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.Shutdown"> + <summary> + Shutdown the repository + </summary> + <remarks> + <para> + Shutdown the repository. Can be overridden in a subclass. + This base class implementation notifies the <see cref="E:log4net.Repository.LoggerRepositorySkeleton.ShutdownEvent"/> + listeners and all attached plugins of the shutdown event. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.ResetConfiguration"> + <summary> + Reset the repositories configuration to a default state + </summary> + <remarks> + <para> + Reset all values contained in this instance to their + default state. + </para> + <para> + Existing loggers are not removed. They are just reset. + </para> + <para> + This method should be used sparingly and with care as it will + block all logging until it is completed. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.Log(log4net.Core.LoggingEvent)"> + <summary> + Log the logEvent through this repository. + </summary> + <param name="logEvent">the event to log</param> + <remarks> + <para> + This method should not normally be used to log. + The <see cref="T:log4net.ILog"/> interface should be used + for routine logging. This interface can be obtained + using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method. + </para> + <para> + The <c>logEvent</c> is delivered to the appropriate logger and + that logger is then responsible for logging the event. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetAppenders"> + <summary> + Returns all the Appenders that are configured as an Array. + </summary> + <returns>All the Appenders</returns> + <remarks> + <para> + Returns all the Appenders that are configured as an Array. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.AddRenderer(System.Type,log4net.ObjectRenderer.IObjectRenderer)"> + <summary> + Adds an object renderer for a specific class. + </summary> + <param name="typeToRender">The type that will be rendered by the renderer supplied.</param> + <param name="rendererInstance">The object renderer used to render the object.</param> + <remarks> + <para> + Adds an object renderer for a specific class. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnShutdown(System.EventArgs)"> + <summary> + Notify the registered listeners that the repository is shutting down + </summary> + <param name="e">Empty EventArgs</param> + <remarks> + <para> + Notify any listeners that this repository is shutting down. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnConfigurationReset(System.EventArgs)"> + <summary> + Notify the registered listeners that the repository has had its configuration reset + </summary> + <param name="e">Empty EventArgs</param> + <remarks> + <para> + Notify any listeners that this repository's configuration has been reset. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnConfigurationChanged(System.EventArgs)"> + <summary> + Notify the registered listeners that the repository has had its configuration changed + </summary> + <param name="e">Empty EventArgs</param> + <remarks> + <para> + Notify any listeners that this repository's configuration has changed. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.LoggerRepositorySkeleton.RaiseConfigurationChanged(System.EventArgs)"> + <summary> + Raise a configuration changed event on this repository + </summary> + <param name="e">EventArgs.Empty</param> + <remarks> + <para> + Applications that programmatically change the configuration of the repository should + raise this event notification to notify listeners. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.Name"> + <summary> + The name of the repository + </summary> + <value> + The string name of the repository + </value> + <remarks> + <para> + The name of this repository. The name is + used to store and lookup the repositories + stored by the <see cref="T:log4net.Core.IRepositorySelector"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.Threshold"> + <summary> + The threshold for all events in this repository + </summary> + <value> + The threshold for all events in this repository + </value> + <remarks> + <para> + The threshold for all events in this repository + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.RendererMap"> + <summary> + RendererMap accesses the object renderer map for this repository. + </summary> + <value> + RendererMap accesses the object renderer map for this repository. + </value> + <remarks> + <para> + RendererMap accesses the object renderer map for this repository. + </para> + <para> + The RendererMap holds a mapping between types and + <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> objects. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.PluginMap"> + <summary> + The plugin map for this repository. + </summary> + <value> + The plugin map for this repository. + </value> + <remarks> + <para> + The plugin map holds the <see cref="T:log4net.Plugin.IPlugin"/> instances + that have been attached to this repository. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.LevelMap"> + <summary> + Get the level map for the Repository. + </summary> + <remarks> + <para> + Get the level map for the Repository. + </para> + <para> + The level map defines the mappings between + level names and <see cref="T:log4net.Core.Level"/> objects in + this repository. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.Configured"> + <summary> + Flag indicates if this repository has been configured. + </summary> + <value> + Flag indicates if this repository has been configured. + </value> + <remarks> + <para> + Flag indicates if this repository has been configured. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.LoggerRepositorySkeleton.ShutdownEvent"> + <summary> + Event to notify that the repository has been shutdown. + </summary> + <value> + Event to notify that the repository has been shutdown. + </value> + <remarks> + <para> + Event raised when the repository has been shutdown. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.LoggerRepositorySkeleton.ConfigurationReset"> + <summary> + Event to notify that the repository has had its configuration reset. + </summary> + <value> + Event to notify that the repository has had its configuration reset. + </value> + <remarks> + <para> + Event raised when the repository's configuration has been + reset to default. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.LoggerRepositorySkeleton.ConfigurationChanged"> + <summary> + Event to notify that the repository has had its configuration changed. + </summary> + <value> + Event to notify that the repository has had its configuration changed. + </value> + <remarks> + <para> + Event raised when the repository's configuration has been changed. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.LoggerRepositorySkeleton.Properties"> + <summary> + Repository specific properties + </summary> + <value> + Repository specific properties + </value> + <remarks> + These properties can be specified on a repository specific basis + </remarks> + </member> + <member name="T:log4net.Repository.IBasicRepositoryConfigurator"> + <summary> + Basic Configurator interface for repositories + </summary> + <remarks> + <para> + Interface used by basic configurator to configure a <see cref="T:log4net.Repository.ILoggerRepository"/> + with a default <see cref="T:log4net.Appender.IAppender"/>. + </para> + <para> + A <see cref="T:log4net.Repository.ILoggerRepository"/> should implement this interface to support + configuration by the <see cref="T:log4net.Config.BasicConfigurator"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"> + <summary> + Initialize the repository using the specified appender + </summary> + <param name="appender">the appender to use to log all logging events</param> + <remarks> + <para> + Configure the repository to route all logging events to the + specified appender. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.IXmlRepositoryConfigurator"> + <summary> + Configure repository using XML + </summary> + <remarks> + <para> + Interface used by Xml configurator to configure a <see cref="T:log4net.Repository.ILoggerRepository"/>. + </para> + <para> + A <see cref="T:log4net.Repository.ILoggerRepository"/> should implement this interface to support + configuration by the <see cref="T:log4net.Config.XmlConfigurator"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.IXmlRepositoryConfigurator.Configure(System.Xml.XmlElement)"> + <summary> + Initialize the repository using the specified config + </summary> + <param name="element">the element containing the root of the config</param> + <remarks> + <para> + The schema for the XML configuration data is defined by + the implementation. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Util.PropertiesDictionary)"> + <summary> + Construct with properties + </summary> + <param name="properties">The properties to pass to this repository.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Repository.Hierarchy.ILoggerFactory)"> + <summary> + Construct with a logger factory + </summary> + <param name="loggerFactory">The factory to use to create new logger instances.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class with + the specified <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Util.PropertiesDictionary,log4net.Repository.Hierarchy.ILoggerFactory)"> + <summary> + Construct with properties and a logger factory + </summary> + <param name="properties">The properties to pass to this repository.</param> + <param name="loggerFactory">The factory to use to create new logger instances.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class with + the specified <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.Exists(System.String)"> + <summary> + Test if a logger exists + </summary> + <param name="name">The name of the logger to lookup</param> + <returns>The Logger object with the name specified</returns> + <remarks> + <para> + Check if the named logger exists in the hierarchy. If so return + its reference, otherwise returns <c>null</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetCurrentLoggers"> + <summary> + Returns all the currently defined loggers in the hierarchy as an Array + </summary> + <returns>All the defined loggers</returns> + <remarks> + <para> + Returns all the currently defined loggers in the hierarchy as an Array. + The root logger is <b>not</b> included in the returned + enumeration. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String)"> + <summary> + Return a new logger instance named as the first parameter using + the default factory. + </summary> + <remarks> + <para> + Return a new logger instance named as the first parameter using + the default factory. + </para> + <para> + If a logger of that name already exists, then it will be + returned. Otherwise, a new logger will be instantiated and + then linked with its existing ancestors as well as children. + </para> + </remarks> + <param name="name">The name of the logger to retrieve</param> + <returns>The logger object with the name specified</returns> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.Shutdown"> + <summary> + Shutting down a hierarchy will <i>safely</i> close and remove + all appenders in all loggers including the root logger. + </summary> + <remarks> + <para> + Shutting down a hierarchy will <i>safely</i> close and remove + all appenders in all loggers including the root logger. + </para> + <para> + Some appenders need to be closed before the + application exists. Otherwise, pending logging events might be + lost. + </para> + <para> + The <c>Shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.ResetConfiguration"> + <summary> + Reset all values contained in this hierarchy instance to their default. + </summary> + <remarks> + <para> + Reset all values contained in this hierarchy instance to their + default. This removes all appenders from all loggers, sets + the level of all non-root loggers to <c>null</c>, + sets their additivity flag to <c>true</c> and sets the level + of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover, + message disabling is set its default "off" value. + </para> + <para> + Existing loggers are not removed. They are just reset. + </para> + <para> + This method should be used sparingly and with care as it will + block all logging until it is completed. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.Log(log4net.Core.LoggingEvent)"> + <summary> + Log the logEvent through this hierarchy. + </summary> + <param name="logEvent">the event to log</param> + <remarks> + <para> + This method should not normally be used to log. + The <see cref="T:log4net.ILog"/> interface should be used + for routine logging. This interface can be obtained + using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method. + </para> + <para> + The <c>logEvent</c> is delivered to the appropriate logger and + that logger is then responsible for logging the event. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetAppenders"> + <summary> + Returns all the Appenders that are currently configured + </summary> + <returns>An array containing all the currently configured appenders</returns> + <remarks> + <para> + Returns all the <see cref="T:log4net.Appender.IAppender"/> instances that are currently configured. + All the loggers are searched for appenders. The appenders may also be containers + for appenders and these are also searched for additional loggers. + </para> + <para> + The list returned is unordered but does not contain duplicates. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.CollectAppender(System.Collections.ArrayList,log4net.Appender.IAppender)"> + <summary> + Collect the appenders from an <see cref="T:log4net.Core.IAppenderAttachable"/>. + The appender may also be a container. + </summary> + <param name="appenderList"></param> + <param name="appender"></param> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.CollectAppenders(System.Collections.ArrayList,log4net.Core.IAppenderAttachable)"> + <summary> + Collect the appenders from an <see cref="T:log4net.Core.IAppenderAttachable"/> container + </summary> + <param name="appenderList"></param> + <param name="container"></param> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.log4net#Repository#IBasicRepositoryConfigurator#Configure(log4net.Appender.IAppender)"> + <summary> + Initialize the log4net system using the specified appender + </summary> + <param name="appender">the appender to use to log all logging events</param> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.BasicRepositoryConfigure(log4net.Appender.IAppender)"> + <summary> + Initialize the log4net system using the specified appender + </summary> + <param name="appender">the appender to use to log all logging events</param> + <remarks> + <para> + This method provides the same functionality as the + <see cref="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"/> method implemented + on this object, but it is protected and therefore can be called by subclasses. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.log4net#Repository#IXmlRepositoryConfigurator#Configure(System.Xml.XmlElement)"> + <summary> + Initialize the log4net system using the specified config + </summary> + <param name="element">the element containing the root of the config</param> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.XmlRepositoryConfigure(System.Xml.XmlElement)"> + <summary> + Initialize the log4net system using the specified config + </summary> + <param name="element">the element containing the root of the config</param> + <remarks> + <para> + This method provides the same functionality as the + <see cref="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"/> method implemented + on this object, but it is protected and therefore can be called by subclasses. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.IsDisabled(log4net.Core.Level)"> + <summary> + Test if this hierarchy is disabled for the specified <see cref="T:log4net.Core.Level"/>. + </summary> + <param name="level">The level to check against.</param> + <returns> + <c>true</c> if the repository is disabled for the level argument, <c>false</c> otherwise. + </returns> + <remarks> + <para> + If this hierarchy has not been configured then this method will + always return <c>true</c>. + </para> + <para> + This method will return <c>true</c> if this repository is + disabled for <c>level</c> object passed as parameter and + <c>false</c> otherwise. + </para> + <para> + See also the <see cref="P:log4net.Repository.ILoggerRepository.Threshold"/> property. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.Clear"> + <summary> + Clear all logger definitions from the internal hashtable + </summary> + <remarks> + <para> + This call will clear all logger definitions from the internal + hashtable. Invoking this method will irrevocably mess up the + logger hierarchy. + </para> + <para> + You should <b>really</b> know what you are doing before + invoking this method. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String,log4net.Repository.Hierarchy.ILoggerFactory)"> + <summary> + Return a new logger instance named as the first parameter using + <paramref name="factory"/>. + </summary> + <param name="name">The name of the logger to retrieve</param> + <param name="factory">The factory that will make the new logger instance</param> + <returns>The logger object with the name specified</returns> + <remarks> + <para> + If a logger of that name already exists, then it will be + returned. Otherwise, a new logger will be instantiated by the + <paramref name="factory"/> parameter and linked with its existing + ancestors as well as children. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.OnLoggerCreationEvent(log4net.Repository.Hierarchy.Logger)"> + <summary> + Sends a logger creation event to all registered listeners + </summary> + <param name="logger">The newly created logger</param> + <remarks> + Raises the logger creation event. + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.UpdateParents(log4net.Repository.Hierarchy.Logger)"> + <summary> + Updates all the parents of the specified logger + </summary> + <param name="log">The logger to update the parents for</param> + <remarks> + <para> + This method loops through all the <i>potential</i> parents of + <paramref name="log"/>. There 3 possible cases: + </para> + <list type="number"> + <item> + <term>No entry for the potential parent of <paramref name="log"/> exists</term> + <description> + We create a ProvisionNode for this potential + parent and insert <paramref name="log"/> in that provision node. + </description> + </item> + <item> + <term>The entry is of type Logger for the potential parent.</term> + <description> + The entry is <paramref name="log"/>'s nearest existing parent. We + update <paramref name="log"/>'s parent field with this entry. We also break from + he loop because updating our parent's parent is our parent's + responsibility. + </description> + </item> + <item> + <term>The entry is of type ProvisionNode for this potential parent.</term> + <description> + We add <paramref name="log"/> to the list of children for this + potential parent. + </description> + </item> + </list> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.UpdateChildren(log4net.Repository.Hierarchy.ProvisionNode,log4net.Repository.Hierarchy.Logger)"> + <summary> + Replace a <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> with a <see cref="T:log4net.Repository.Hierarchy.Logger"/> in the hierarchy. + </summary> + <param name="pn"></param> + <param name="log"></param> + <remarks> + <para> + We update the links for all the children that placed themselves + in the provision node 'pn'. The second argument 'log' is a + reference for the newly created Logger, parent of all the + children in 'pn'. + </para> + <para> + We loop on all the children 'c' in 'pn'. + </para> + <para> + If the child 'c' has been already linked to a child of + 'log' then there is no need to update 'c'. + </para> + <para> + Otherwise, we set log's parent field to c's parent and set + c's parent field to log. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.AddLevel(log4net.Repository.Hierarchy.Hierarchy.LevelEntry)"> + <summary> + Define or redefine a Level using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument + </summary> + <param name="levelEntry">the level values</param> + <remarks> + <para> + Define or redefine a Level using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument + </para> + <para> + Supports setting levels via the configuration file. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.AddProperty(log4net.Repository.Hierarchy.Hierarchy.PropertyEntry)"> + <summary> + Set a Property using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument + </summary> + <param name="propertyEntry">the property value</param> + <remarks> + <para> + Set a Property using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument. + </para> + <para> + Supports setting property values via the configuration file. + </para> + </remarks> + </member> + <member name="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"> + <summary> + Event used to notify that a logger has been created. + </summary> + <remarks> + <para> + Event raised when a logger is created. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.EmittedNoAppenderWarning"> + <summary> + Has no appender warning been emitted + </summary> + <remarks> + <para> + Flag to indicate if we have already issued a warning + about not having an appender warning. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.Root"> + <summary> + Get the root of this hierarchy + </summary> + <remarks> + <para> + Get the root of this hierarchy. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.LoggerFactory"> + <summary> + Gets or sets the default <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> instance. + </summary> + <value>The default <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/></value> + <remarks> + <para> + The logger factory is used to create logger instances. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"> + <summary> + A class to hold the value, name and display name for a level + </summary> + <remarks> + <para> + A class to hold the value, name and display name for a level + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.ToString"> + <summary> + Override <c>Object.ToString</c> to return sensible debug info + </summary> + <returns>string info about this object</returns> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.Value"> + <summary> + Value of the level + </summary> + <remarks> + <para> + If the value is not set (defaults to -1) the value will be looked + up for the current level with the same name. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.Name"> + <summary> + Name of the level + </summary> + <value> + The name of the level + </value> + <remarks> + <para> + The name of the level. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.DisplayName"> + <summary> + Display name for the level + </summary> + <value> + The display name of the level + </value> + <remarks> + <para> + The display name of the level. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry"> + <summary> + A class to hold the key and data for a property set in the config file + </summary> + <remarks> + <para> + A class to hold the key and data for a property set in the config file + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.ToString"> + <summary> + Override <c>Object.ToString</c> to return sensible debug info + </summary> + <returns>string info about this object</returns> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.Key"> + <summary> + Property Key + </summary> + <value> + Property Key + </value> + <remarks> + <para> + Property Key. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.Value"> + <summary> + Property Value + </summary> + <value> + Property Value + </value> + <remarks> + <para> + Property Value. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.LoggerKey"> + <summary> + Used internally to accelerate hash table searches. + </summary> + <remarks> + <para> + Internal class used to improve performance of + string keyed hashtables. + </para> + <para> + The hashcode of the string is cached for reuse. + The string is stored as an interned value. + When comparing two <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> objects for equality + the reference equality of the interned strings is compared. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.Hierarchy.LoggerKey.#ctor(System.String)"> + <summary> + Construct key with string name + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> class + with the specified name. + </para> + <para> + Stores the hashcode of the string and interns + the string key to optimize comparisons. + </para> + <note> + The Compact Framework 1.0 the <see cref="M:System.String.Intern(System.String)"/> + method does not work. On the Compact Framework + the string keys are not interned nor are they + compared by reference. + </note> + </remarks> + <param name="name">The name of the logger.</param> + </member> + <member name="M:log4net.Repository.Hierarchy.LoggerKey.GetHashCode"> + <summary> + Returns a hash code for the current instance. + </summary> + <returns>A hash code for the current instance.</returns> + <remarks> + <para> + Returns the cached hashcode. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.LoggerKey.Equals(System.Object)"> + <summary> + Determines whether two <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> instances + are equal. + </summary> + <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/>.</param> + <returns> + <c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/>; otherwise, <c>false</c>. + </returns> + <remarks> + <para> + Compares the references of the interned strings. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.ProvisionNode"> + <summary> + Provision nodes are used where no logger instance has been specified + </summary> + <remarks> + <para> + <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> instances are used in the + <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> when there is no specified + <see cref="T:log4net.Repository.Hierarchy.Logger"/> for that node. + </para> + <para> + A provision node holds a list of child loggers on behalf of + a logger that does not exist. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.Hierarchy.ProvisionNode.#ctor(log4net.Repository.Hierarchy.Logger)"> + <summary> + Create a new provision node with child node + </summary> + <param name="log">A child logger to add to this node.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> class + with the specified child logger. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.RootLogger"> + <summary> + The <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> sits at the root of the logger hierarchy tree. + </summary> + <remarks> + <para> + The <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> is a regular <see cref="T:log4net.Repository.Hierarchy.Logger"/> except + that it provides several guarantees. + </para> + <para> + First, it cannot be assigned a <c>null</c> + level. Second, since the root logger cannot have a parent, the + <see cref="P:log4net.Repository.Hierarchy.RootLogger.EffectiveLevel"/> property always returns the value of the + level field without walking the hierarchy. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.Hierarchy.RootLogger.#ctor(log4net.Core.Level)"> + <summary> + Construct a <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> + </summary> + <param name="level">The level to assign to the root logger.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> class with + the specified logging level. + </para> + <para> + The root logger names itself as "root". However, the root + logger cannot be retrieved by name. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.RootLogger.EffectiveLevel"> + <summary> + Gets the assigned level value without walking the logger hierarchy. + </summary> + <value>The assigned level value without walking the logger hierarchy.</value> + <remarks> + <para> + Because the root logger cannot have a parent and its level + must not be <c>null</c> this property just returns the + value of <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Repository.Hierarchy.RootLogger.Level"> + <summary> + Gets or sets the assigned <see cref="P:log4net.Repository.Hierarchy.RootLogger.Level"/> for the root logger. + </summary> + <value> + The <see cref="P:log4net.Repository.Hierarchy.RootLogger.Level"/> of the root logger. + </value> + <remarks> + <para> + Setting the level of the root logger to a <c>null</c> reference + may have catastrophic results. We prevent this here. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.Hierarchy.XmlHierarchyConfigurator"> + <summary> + Initializes the log4net environment using an XML DOM. + </summary> + <remarks> + <para> + Configures a <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> using an XML DOM. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.#ctor(log4net.Repository.Hierarchy.Hierarchy)"> + <summary> + Construct the configurator for a hierarchy + </summary> + <param name="hierarchy">The hierarchy to build.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.XmlHierarchyConfigurator"/> class + with the specified <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.Configure(System.Xml.XmlElement)"> + <summary> + Configure the hierarchy by parsing a DOM tree of XML elements. + </summary> + <param name="element">The root element to parse.</param> + <remarks> + <para> + Configure the hierarchy by parsing a DOM tree of XML elements. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindAppenderByReference(System.Xml.XmlElement)"> + <summary> + Parse appenders by IDREF. + </summary> + <param name="appenderRef">The appender ref element.</param> + <returns>The instance of the appender that the ref refers to.</returns> + <remarks> + <para> + Parse an XML element that represents an appender and return + the appender. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(System.Xml.XmlElement)"> + <summary> + Parses an appender element. + </summary> + <param name="appenderElement">The appender element.</param> + <returns>The appender instance or <c>null</c> when parsing failed.</returns> + <remarks> + <para> + Parse an XML element that represents an appender and return + the appender instance. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseLogger(System.Xml.XmlElement)"> + <summary> + Parses a logger element. + </summary> + <param name="loggerElement">The logger element.</param> + <remarks> + <para> + Parse an XML element that represents a logger. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRoot(System.Xml.XmlElement)"> + <summary> + Parses the root logger element. + </summary> + <param name="rootElement">The root element.</param> + <remarks> + <para> + Parse an XML element that represents the root logger. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseChildrenOfLoggerElement(System.Xml.XmlElement,log4net.Repository.Hierarchy.Logger,System.Boolean)"> + <summary> + Parses the children of a logger element. + </summary> + <param name="catElement">The category element.</param> + <param name="log">The logger instance.</param> + <param name="isRoot">Flag to indicate if the logger is the root logger.</param> + <remarks> + <para> + Parse the child elements of a <logger> element. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRenderer(System.Xml.XmlElement)"> + <summary> + Parses an object renderer. + </summary> + <param name="element">The renderer element.</param> + <remarks> + <para> + Parse an XML element that represents a renderer. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseLevel(System.Xml.XmlElement,log4net.Repository.Hierarchy.Logger,System.Boolean)"> + <summary> + Parses a level element. + </summary> + <param name="element">The level element.</param> + <param name="log">The logger object to set the level on.</param> + <param name="isRoot">Flag to indicate if the logger is the root logger.</param> + <remarks> + <para> + Parse an XML element that represents a level. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.SetParameter(System.Xml.XmlElement,System.Object)"> + <summary> + Sets a parameter on an object. + </summary> + <param name="element">The parameter element.</param> + <param name="target">The object to set the parameter on.</param> + <remarks> + The parameter name must correspond to a writable property + on the object. The value of the parameter is a string, + therefore this function will attempt to set a string + property first. If unable to set a string property it + will inspect the property and its argument type. It will + attempt to call a static method called <c>Parse</c> on the + type of the property. This method will take a single + string argument and return a value that can be used to + set the property. + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.HasAttributesOrElements(System.Xml.XmlElement)"> + <summary> + Test if an element has no attributes or child elements + </summary> + <param name="element">the element to inspect</param> + <returns><c>true</c> if the element has any attributes or child elements, <c>false</c> otherwise</returns> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.IsTypeConstructible(System.Type)"> + <summary> + Test if a <see cref="T:System.Type"/> is constructible with <c>Activator.CreateInstance</c>. + </summary> + <param name="type">the type to inspect</param> + <returns><c>true</c> if the type is creatable using a default constructor, <c>false</c> otherwise</returns> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindMethodInfo(System.Type,System.String)"> + <summary> + Look for a method on the <paramref name="targetType"/> that matches the <paramref name="name"/> supplied + </summary> + <param name="targetType">the type that has the method</param> + <param name="name">the name of the method</param> + <returns>the method info found</returns> + <remarks> + <para> + The method must be a public instance method on the <paramref name="targetType"/>. + The method must be named <paramref name="name"/> or "Add" followed by <paramref name="name"/>. + The method must take a single parameter. + </para> + </remarks> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ConvertStringTo(System.Type,System.String)"> + <summary> + Converts a string value to a target type. + </summary> + <param name="type">The type of object to convert the string to.</param> + <param name="value">The string value to use as the value of the object.</param> + <returns> + <para> + An object of type <paramref name="type"/> with value <paramref name="value"/> or + <c>null</c> when the conversion could not be performed. + </para> + </returns> + </member> + <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.CreateObjectFromXml(System.Xml.XmlElement,System.Type,System.Type)"> + <summary> + Creates an object as specified in XML. + </summary> + <param name="element">The XML element that contains the definition of the object.</param> + <param name="defaultTargetType">The object type to use if not explicitly specified.</param> + <param name="typeConstraint">The type that the returned object must be or must inherit from.</param> + <returns>The object or <c>null</c></returns> + <remarks> + <para> + Parse an XML element and create an object instance based on the configuration + data. + </para> + <para> + The type of the instance may be specified in the XML. If not + specified then the <paramref name="defaultTargetType"/> is used + as the type. However the type is specified it must support the + <paramref name="typeConstraint"/> type. + </para> + </remarks> + </member> + <member name="F:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.m_appenderBag"> + <summary> + key: appenderName, value: appender. + </summary> + </member> + <member name="F:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.m_hierarchy"> + <summary> + The Hierarchy being configured. + </summary> + </member> + <member name="T:log4net.Repository.LoggerRepositoryShutdownEventHandler"> + <summary> + Delegate used to handle logger repository shutdown event notifications + </summary> + <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that is shutting down.</param> + <param name="e">Empty event args</param> + <remarks> + <para> + Delegate used to handle logger repository shutdown event notifications. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.LoggerRepositoryConfigurationResetEventHandler"> + <summary> + Delegate used to handle logger repository configuration reset event notifications + </summary> + <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that has had its configuration reset.</param> + <param name="e">Empty event args</param> + <remarks> + <para> + Delegate used to handle logger repository configuration reset event notifications. + </para> + </remarks> + </member> + <member name="T:log4net.Repository.LoggerRepositoryConfigurationChangedEventHandler"> + <summary> + Delegate used to handle event notifications for logger repository configuration changes. + </summary> + <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that has had its configuration changed.</param> + <param name="e">Empty event arguments.</param> + <remarks> + <para> + Delegate used to handle event notifications for logger repository configuration changes. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.AppDomainPatternConverter"> + <summary> + Write the name of the current AppDomain to the output + </summary> + <remarks> + <para> + Write the name of the current AppDomain to the output writer + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.AppDomainPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the name of the current AppDomain to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Writes name of the current AppDomain to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.DatePatternConverter"> + <summary> + Write the current date to the output + </summary> + <remarks> + <para> + Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format + the current date and time to the writer as a string. + </para> + <para> + The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines + the formatting of the date. The following values are allowed: + <list type="definition"> + <listheader> + <term>Option value</term> + <description>Output</description> + </listheader> + <item> + <term>ISO8601</term> + <description> + Uses the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> formatter. + Formats using the <c>"yyyy-MM-dd HH:mm:ss,fff"</c> pattern. + </description> + </item> + <item> + <term>DATE</term> + <description> + Uses the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> formatter. + Formats using the <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, <c>"06 Nov 1994 15:49:37,459"</c>. + </description> + </item> + <item> + <term>ABSOLUTE</term> + <description> + Uses the <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/> formatter. + Formats using the <c>"HH:mm:ss,fff"</c> for example, <c>"15:49:37,459"</c>. + </description> + </item> + <item> + <term>other</term> + <description> + Any other pattern string uses the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> formatter. + This formatter passes the pattern string to the <see cref="T:System.DateTime"/> + <see cref="M:System.DateTime.ToString(System.String)"/> method. + For details on valid patterns see + <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.asp">DateTimeFormatInfo Class</a>. + </description> + </item> + </list> + </para> + <para> + The date and time is in the local time zone and is rendered in that zone. + To output the time in Universal time see <see cref="T:log4net.Util.PatternStringConverters.UtcDatePatternConverter"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.PatternStringConverters.DatePatternConverter.m_dateFormatter"> + <summary> + The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string + </summary> + <remarks> + <para> + The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"> + <summary> + Initialize the converter options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.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="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternStringConverters.DatePatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the current date to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Pass the current date and time to the <see cref="T:log4net.DateFormatter.IDateFormatter"/> + for it to render it to the writer. + </para> + <para> + The date and time passed is in the local time zone. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.EnvironmentPatternConverter"> + <summary> + Write an environment variable to the output + </summary> + <remarks> + <para> + Write an environment variable to the output writer. + The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines + the name of the variable to output. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.EnvironmentPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write an environment variable to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Writes the environment variable to the output <paramref name="writer"/>. + The name of the environment variable to output must be set + using the <see cref="P:log4net.Util.PatternConverter.Option"/> + property. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.IdentityPatternConverter"> + <summary> + Write the current thread identity to the output + </summary> + <remarks> + <para> + Write the current thread identity to the output writer + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.IdentityPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the current thread identity to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Writes the current thread identity to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"> + <summary> + Pattern converter for literal string instances in the pattern + </summary> + <remarks> + <para> + Writes the literal string value specified in the + <see cref="P:log4net.Util.PatternConverter.Option"/> property to + the output. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.SetNext(log4net.Util.PatternConverter)"> + <summary> + Set the next converter in the chain + </summary> + <param name="pc">The next pattern converter in the chain</param> + <returns>The next pattern converter</returns> + <remarks> + <para> + Special case the building of the pattern converter chain + for <see cref="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"/> instances. Two adjacent + literals in the pattern can be represented by a single combined + pattern converter. This implementation detects when a + <see cref="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"/> is added to the chain + after this converter and combines its value with this converter's + literal value. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.Format(System.IO.TextWriter,System.Object)"> + <summary> + Write the literal to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, not set</param> + <remarks> + <para> + Override the formatting behavior to ignore the FormattingInfo + because we have a literal instead. + </para> + <para> + Writes the value of <see cref="P:log4net.Util.PatternConverter.Option"/> + to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Convert this pattern into the rendered message + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">null, not set</param> + <remarks> + <para> + This method is not used. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.NewLinePatternConverter"> + <summary> + Writes a newline to the output + </summary> + <remarks> + <para> + Writes the system dependent line terminator to the output. + This behavior can be overridden by setting the <see cref="P:log4net.Util.PatternConverter.Option"/>: + </para> + <list type="definition"> + <listheader> + <term>Option Value</term> + <description>Output</description> + </listheader> + <item> + <term>DOS</term> + <description>DOS or Windows line terminator <c>"\r\n"</c></description> + </item> + <item> + <term>UNIX</term> + <description>UNIX line terminator <c>"\n"</c></description> + </item> + </list> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"> + <summary> + Initialize the converter + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.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="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.ProcessIdPatternConverter"> + <summary> + Write the current process ID to the output + </summary> + <remarks> + <para> + Write the current process ID to the output writer + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.ProcessIdPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the current process ID to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Write the current process ID to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.PropertyPatternConverter"> + <summary> + Property pattern converter + </summary> + <remarks> + <para> + This pattern converter reads the thread and global properties. + The thread properties take priority over global properties. + See <see cref="P:log4net.ThreadContext.Properties"/> for details of the + thread properties. See <see cref="P:log4net.GlobalContext.Properties"/> for + details of the global properties. + </para> + <para> + If the <see cref="P:log4net.Util.PatternConverter.Option"/> is specified then that will be used to + lookup a single property. If no <see cref="P:log4net.Util.PatternConverter.Option"/> is specified + then all properties will be dumped as a list of key value pairs. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.PropertyPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the property value to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Writes out the value of a named property. The property name + should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/> + property. + </para> + <para> + If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c> + then all the properties are written as key value pairs. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.RandomStringPatternConverter"> + <summary> + A Pattern converter that generates a string of random characters + </summary> + <remarks> + <para> + The converter generates a string of random characters. By default + the string is length 4. This can be changed by setting the <see cref="P:log4net.Util.PatternConverter.Option"/> + to the string value of the length required. + </para> + <para> + The random characters in the string are limited to uppercase letters + and numbers only. + </para> + <para> + The random number generator used by this class is not cryptographically secure. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.PatternStringConverters.RandomStringPatternConverter.s_random"> + <summary> + Shared random number generator + </summary> + </member> + <member name="F:log4net.Util.PatternStringConverters.RandomStringPatternConverter.m_length"> + <summary> + Length of random string to generate. Default length 4. + </summary> + </member> + <member name="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"> + <summary> + Initialize the converter options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.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="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write a randoim string to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Write a randoim string to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.UserNamePatternConverter"> + <summary> + Write the current threads username to the output + </summary> + <remarks> + <para> + Write the current threads username to the output writer + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.UserNamePatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the current threads username to the output + </summary> + <param name="writer">the writer to write to</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Write the current threads username to the output <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternStringConverters.UtcDatePatternConverter"> + <summary> + Write the UTC date time to the output + </summary> + <remarks> + <para> + Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format + the current date and time in Universal time. + </para> + <para> + See the <see cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/> for details on the date pattern syntax. + </para> + </remarks> + <seealso cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.PatternStringConverters.UtcDatePatternConverter.Convert(System.IO.TextWriter,System.Object)"> + <summary> + Write the current date and time to the output + </summary> + <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param> + <param name="state">null, state is not set</param> + <remarks> + <para> + Pass the current date and time to the <see cref="T:log4net.DateFormatter.IDateFormatter"/> + for it to render it to the writer. + </para> + <para> + The date is in Universal time when it is rendered. + </para> + </remarks> + <seealso cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/> + </member> + <member name="T:log4net.Util.TypeConverters.BooleanConverter"> + <summary> + Type converter for Boolean. + </summary> + <remarks> + <para> + Supports conversion from string to <c>bool</c> type. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.TypeConverters.BooleanConverter.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="sourceType"/> is + the <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.BooleanConverter.ConvertFrom(System.Object)"> + <summary> + Convert the source object to the type supported by this object + </summary> + <param name="source">the object to convert</param> + <returns>the converted object</returns> + <remarks> + <para> + Uses the <see cref="M:System.Boolean.Parse(System.String)"/> method to convert the + <see cref="T:System.String"/> argument to a <see cref="T:System.Boolean"/>. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.BooleanConverter.CanConvertFrom(System.Type)"/> + method. + </exception> + </member> + <member name="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + <summary> + Exception base type for conversion errors. + </summary> + <remarks> + <para> + This type extends <see cref="T:System.ApplicationException"/>. It + does not add any new functionality but does differentiate the + type of exception being thrown. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.String)"> + <summary> + Constructor + </summary> + <param name="message">A message to include with the exception.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class + with the specified message. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.String,System.Exception)"> + <summary> + Constructor + </summary> + <param name="message">A message to include with the exception.</param> + <param name="innerException">A nested exception to include.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class + with the specified message and inner exception. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Serialization constructor + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param> + <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class + with serialized data. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.Create(System.Type,System.Object)"> + <summary> + Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class. + </summary> + <param name="destinationType">The conversion destination type.</param> + <param name="sourceValue">The value to convert.</param> + <returns>An instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/>.</returns> + <remarks> + <para> + Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.Create(System.Type,System.Object,System.Exception)"> + <summary> + Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class. + </summary> + <param name="destinationType">The conversion destination type.</param> + <param name="sourceValue">The value to convert.</param> + <param name="innerException">A nested exception to include.</param> + <returns>An instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/>.</returns> + <remarks> + <para> + Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class. + </para> + </remarks> + </member> + <member name="T:log4net.Util.TypeConverters.ConverterRegistry"> + <summary> + Register of type converters for specific types. + </summary> + <remarks> + <para> + Maintains a registry of type converters used to convert between + types. + </para> + <para> + Use the <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Object)"/> and + <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Type)"/> methods to register new converters. + The <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertTo(System.Type,System.Type)"/> and <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertFrom(System.Type)"/> methods + lookup appropriate converters to use. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.#ctor"> + <summary> + Private constructor + </summary> + <remarks> + Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> class. + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.#cctor"> + <summary> + Static constructor. + </summary> + <remarks> + <para> + This constructor defines the intrinsic type converters. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Object)"> + <summary> + Adds a converter for a specific type. + </summary> + <param name="destinationType">The type being converted to.</param> + <param name="converter">The type converter to use to convert to the destination type.</param> + <remarks> + <para> + Adds a converter instance for a specific type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Type)"> + <summary> + Adds a converter for a specific type. + </summary> + <param name="destinationType">The type being converted to.</param> + <param name="converterType">The type of the type converter to use to convert to the destination type.</param> + <remarks> + <para> + Adds a converter <see cref="T:System.Type"/> for a specific type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertTo(System.Type,System.Type)"> + <summary> + Gets the type converter to use to convert values to the destination type. + </summary> + <param name="sourceType">The type being converted from.</param> + <param name="destinationType">The type being converted to.</param> + <returns> + The type converter instance to use for type conversions or <c>null</c> + if no type converter is found. + </returns> + <remarks> + <para> + Gets the type converter to use to convert values to the destination type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertFrom(System.Type)"> + <summary> + Gets the type converter to use to convert values to the destination type. + </summary> + <param name="destinationType">The type being converted to.</param> + <returns> + The type converter instance to use for type conversions or <c>null</c> + if no type converter is found. + </returns> + <remarks> + <para> + Gets the type converter to use to convert values to the destination type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConverterFromAttribute(System.Type)"> + <summary> + Lookups the type converter to use as specified by the attributes on the + destination type. + </summary> + <param name="destinationType">The type being converted to.</param> + <returns> + The type converter instance to use for type conversions or <c>null</c> + if no type converter is found. + </returns> + </member> + <member name="M:log4net.Util.TypeConverters.ConverterRegistry.CreateConverterInstance(System.Type)"> + <summary> + Creates the instance of the type converter. + </summary> + <param name="converterType">The type of the type converter.</param> + <returns> + The type converter instance to use for type conversions or <c>null</c> + if no type converter is found. + </returns> + <remarks> + <para> + The type specified for the type converter must implement + the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/> or <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces + and must have a public default (no argument) constructor. + </para> + </remarks> + </member> + <member name="F:log4net.Util.TypeConverters.ConverterRegistry.s_type2converter"> + <summary> + Mapping from <see cref="T:System.Type"/> to type converter. + </summary> + </member> + <member name="T:log4net.Util.TypeConverters.EncodingConverter"> + <summary> + Supports conversion from string to <see cref="T:System.Text.Encoding"/> type. + </summary> + <remarks> + <para> + Supports conversion from string to <see cref="T:System.Text.Encoding"/> type. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.TypeConverters.EncodingConverter.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="sourceType"/> is + the <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.EncodingConverter.ConvertFrom(System.Object)"> + <summary> + Overrides the ConvertFrom method of IConvertFrom. + </summary> + <param name="source">the object to convert to an encoding</param> + <returns>the encoding</returns> + <remarks> + <para> + Uses the <see cref="M:System.Text.Encoding.GetEncoding(System.String)"/> method to + convert the <see cref="T:System.String"/> argument to an <see cref="T:System.Text.Encoding"/>. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.EncodingConverter.CanConvertFrom(System.Type)"/> + method. + </exception> + </member> + <member name="T:log4net.Util.TypeConverters.IConvertTo"> + <summary> + Interface supported by type converters + </summary> + <remarks> + <para> + This interface supports conversion from a single type to arbitrary types. + See <see cref="T:log4net.Util.TypeConverters.TypeConverterAttribute"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.TypeConverters.IConvertTo.CanConvertTo(System.Type)"> + <summary> + Returns whether this converter can convert the object to the specified type + </summary> + <param name="targetType">A Type that represents the type you want to convert to</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Test if the type supported by this converter can be converted to the + <paramref name="targetType"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.IConvertTo.ConvertTo(System.Object,System.Type)"> + <summary> + Converts the given value object to the specified type, using the arguments + </summary> + <param name="source">the object to convert</param> + <param name="targetType">The Type to convert the value parameter to</param> + <returns>the converted object</returns> + <remarks> + <para> + Converts the <paramref name="source"/> (which must be of the type supported + by this converter) to the <paramref name="targetType"/> specified.. + </para> + </remarks> + </member> + <member name="T:log4net.Util.TypeConverters.IPAddressConverter"> + <summary> + Supports conversion from string to <see cref="T:System.Net.IPAddress"/> type. + </summary> + <remarks> + <para> + Supports conversion from string to <see cref="T:System.Net.IPAddress"/> type. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.TypeConverters.IPAddressConverter.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="sourceType"/> is + the <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.IPAddressConverter.ConvertFrom(System.Object)"> + <summary> + Overrides the ConvertFrom method of IConvertFrom. + </summary> + <param name="source">the object to convert to an IPAddress</param> + <returns>the IPAddress</returns> + <remarks> + <para> + Uses the <see cref="M:System.Net.IPAddress.Parse(System.String)"/> method to convert the + <see cref="T:System.String"/> argument to an <see cref="T:System.Net.IPAddress"/>. + If that fails then the string is resolved as a DNS hostname. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.IPAddressConverter.CanConvertFrom(System.Type)"/> + method. + </exception> + </member> + <member name="F:log4net.Util.TypeConverters.IPAddressConverter.validIpAddressChars"> + <summary> + Valid characters in an IPv4 or IPv6 address string. (Does not support subnets) + </summary> + </member> + <member name="T:log4net.Util.TypeConverters.PatternLayoutConverter"> + <summary> + Supports conversion from string to <see cref="T:log4net.Layout.PatternLayout"/> type. + </summary> + <remarks> + <para> + Supports conversion from string to <see cref="T:log4net.Layout.PatternLayout"/> type. + </para> + <para> + The string is used as the <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/> + of the <see cref="T:log4net.Layout.PatternLayout"/>. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.TypeConverters.PatternLayoutConverter.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="sourceType"/> is + the <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.PatternLayoutConverter.ConvertFrom(System.Object)"> + <summary> + Overrides the ConvertFrom method of IConvertFrom. + </summary> + <param name="source">the object to convert to a PatternLayout</param> + <returns>the PatternLayout</returns> + <remarks> + <para> + Creates and returns a new <see cref="T:log4net.Layout.PatternLayout"/> using + the <paramref name="source"/> <see cref="T:System.String"/> as the + <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/>. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.PatternLayoutConverter.CanConvertFrom(System.Type)"/> + method. + </exception> + </member> + <member name="T:log4net.Util.TypeConverters.PatternStringConverter"> + <summary> + Convert between string and <see cref="T:log4net.Util.PatternString"/> + </summary> + <remarks> + <para> + Supports conversion from string to <see cref="T:log4net.Util.PatternString"/> type, + and from a <see cref="T:log4net.Util.PatternString"/> type to a string. + </para> + <para> + The string is used as the <see cref="P:log4net.Util.PatternString.ConversionPattern"/> + of the <see cref="T:log4net.Util.PatternString"/>. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertTo(System.Type)"> + <summary> + Can the target type be converted to the type supported by this object + </summary> + <param name="targetType">A <see cref="T:System.Type"/> that represents the type you want to convert to</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="targetType"/> is + assignable from a <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.PatternStringConverter.ConvertTo(System.Object,System.Type)"> + <summary> + Converts the given value object to the specified type, using the arguments + </summary> + <param name="source">the object to convert</param> + <param name="targetType">The Type to convert the value parameter to</param> + <returns>the converted object</returns> + <remarks> + <para> + Uses the <see cref="M:log4net.Util.PatternString.Format"/> method to convert the + <see cref="T:log4net.Util.PatternString"/> argument to a <see cref="T:System.String"/>. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + <paramref name="targetType"/>. To check for this condition use the + <see cref="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertTo(System.Type)"/> method. + </exception> + </member> + <member name="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="sourceType"/> is + the <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.PatternStringConverter.ConvertFrom(System.Object)"> + <summary> + Overrides the ConvertFrom method of IConvertFrom. + </summary> + <param name="source">the object to convert to a PatternString</param> + <returns>the PatternString</returns> + <remarks> + <para> + Creates and returns a new <see cref="T:log4net.Util.PatternString"/> using + the <paramref name="source"/> <see cref="T:System.String"/> as the + <see cref="P:log4net.Util.PatternString.ConversionPattern"/>. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertFrom(System.Type)"/> + method. + </exception> + </member> + <member name="T:log4net.Util.TypeConverters.TypeConverter"> + <summary> + Supports conversion from string to <see cref="T:System.Type"/> type. + </summary> + <remarks> + <para> + Supports conversion from string to <see cref="T:System.Type"/> type. + </para> + </remarks> + <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.TypeConverters.TypeConverter.CanConvertFrom(System.Type)"> + <summary> + Can the source type be converted to the type supported by this object + </summary> + <param name="sourceType">the type to convert</param> + <returns>true if the conversion is possible</returns> + <remarks> + <para> + Returns <c>true</c> if the <paramref name="sourceType"/> is + the <see cref="T:System.String"/> type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.TypeConverter.ConvertFrom(System.Object)"> + <summary> + Overrides the ConvertFrom method of IConvertFrom. + </summary> + <param name="source">the object to convert to a Type</param> + <returns>the Type</returns> + <remarks> + <para> + Uses the <see cref="M:System.Type.GetType(System.String,System.Boolean)"/> method to convert the + <see cref="T:System.String"/> argument to a <see cref="T:System.Type"/>. + Additional effort is made to locate partially specified types + by searching the loaded assemblies. + </para> + </remarks> + <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"> + The <paramref name="source"/> object cannot be converted to the + target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.TypeConverter.CanConvertFrom(System.Type)"/> + method. + </exception> + </member> + <member name="T:log4net.Util.TypeConverters.TypeConverterAttribute"> + <summary> + Attribute used to associate a type converter + </summary> + <remarks> + <para> + Class and Interface level attribute that specifies a type converter + to use with the associated type. + </para> + <para> + To associate a type converter with a target type apply a + <c>TypeConverterAttribute</c> to the target type. Specify the + type of the type converter on the attribute. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Util.TypeConverters.TypeConverterAttribute.m_typeName"> + <summary> + The string type name of the type converter + </summary> + </member> + <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor(System.String)"> + <summary> + Create a new type converter attribute for the specified type name + </summary> + <param name="typeName">The string type name of the type converter</param> + <remarks> + <para> + The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor(System.Type)"> + <summary> + Create a new type converter attribute for the specified type + </summary> + <param name="converterType">The type of the type converter</param> + <remarks> + <para> + The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces. + </para> + </remarks> + </member> + <member name="P:log4net.Util.TypeConverters.TypeConverterAttribute.ConverterTypeName"> + <summary> + The string type name of the type converter + </summary> + <value> + The string type name of the type converter + </value> + <remarks> + <para> + The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/> + or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces. + </para> + </remarks> + </member> + <member name="T:log4net.Util.AppenderAttachedImpl"> + <summary> + A straightforward implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface. + </summary> + <remarks> + <para> + This is the default implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> + interface. Implementors of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface + should aggregate an instance of this type. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.AppenderAttachedImpl"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent)"> + <summary> + Append on on all attached appenders. + </summary> + <param name="loggingEvent">The event being logged.</param> + <returns>The number of appenders called.</returns> + <remarks> + <para> + Calls the <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method on all + attached appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent[])"> + <summary> + Append on on all attached appenders. + </summary> + <param name="loggingEvents">The array of events being logged.</param> + <returns>The number of appenders called.</returns> + <remarks> + <para> + Calls the <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method on all + attached appenders. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.CallAppend(log4net.Appender.IAppender,log4net.Core.LoggingEvent[])"> + <summary> + Calls the DoAppende method on the <see cref="T:log4net.Appender.IAppender"/> with + the <see cref="T:log4net.Core.LoggingEvent"/> objects supplied. + </summary> + <param name="appender">The appender</param> + <param name="loggingEvents">The events</param> + <remarks> + <para> + If the <paramref name="appender"/> supports the <see cref="T:log4net.Appender.IBulkAppender"/> + interface then the <paramref name="loggingEvents"/> will be passed + through using that interface. Otherwise the <see cref="T:log4net.Core.LoggingEvent"/> + objects in the array will be passed one at a time. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.AddAppender(log4net.Appender.IAppender)"> + <summary> + Attaches an appender. + </summary> + <param name="newAppender">The appender to add.</param> + <remarks> + <para> + If the appender is already in the list it won't be added again. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.GetAppender(System.String)"> + <summary> + Gets an attached appender with the specified name. + </summary> + <param name="name">The name of the appender to get.</param> + <returns> + The appender with the name specified, or <c>null</c> if no appender with the + specified name is found. + </returns> + <remarks> + <para> + Lookup an attached appender by name. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAllAppenders"> + <summary> + Removes all attached appenders. + </summary> + <remarks> + <para> + Removes and closes all attached appenders + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAppender(log4net.Appender.IAppender)"> + <summary> + Removes the specified appender from the list of attached appenders. + </summary> + <param name="appender">The appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + <para> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </para> + </remarks> + </member> + <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAppender(System.String)"> + <summary> + Removes the appender with the specified name from the list of appenders. + </summary> + <param name="name">The name of the appender to remove.</param> + <returns>The appender removed from the list</returns> + <remarks> + <para> + The appender removed is not closed. + If you are discarding the appender you must call + <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed. + </para> + </remarks> + </member> + <member name="F:log4net.Util.AppenderAttachedImpl.m_appenderList"> + <summary> + List of appenders + </summary> + </member> + <member name="F:log4net.Util.AppenderAttachedImpl.m_appenderArray"> + <summary> + Array of appenders, used to cache the m_appenderList + </summary> + </member> + <member name="P:log4net.Util.AppenderAttachedImpl.Appenders"> + <summary> + Gets all attached appenders. + </summary> + <returns> + A collection of attached appenders, or <c>null</c> if there + are no attached appenders. + </returns> + <remarks> + <para> + The read only collection of all currently attached appenders. + </para> + </remarks> + </member> + <member name="T:log4net.Util.CompositeProperties"> + <summary> + This class aggregates several PropertiesDictionary collections together. + </summary> + <remarks> + <para> + Provides a dictionary style lookup over an ordered list of + <see cref="T:log4net.Util.PropertiesDictionary"/> collections. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.CompositeProperties.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.CompositeProperties"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CompositeProperties.Add(log4net.Util.ReadOnlyPropertiesDictionary)"> + <summary> + Add a Properties Dictionary to this composite collection + </summary> + <param name="properties">the properties to add</param> + <remarks> + <para> + Properties dictionaries added first take precedence over dictionaries added + later. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CompositeProperties.Flatten"> + <summary> + Flatten this composite collection into a single properties dictionary + </summary> + <returns>the flattened dictionary</returns> + <remarks> + <para> + Reduces the collection of ordered dictionaries to a single dictionary + containing the resultant values for the keys. + </para> + </remarks> + </member> + <member name="P:log4net.Util.CompositeProperties.Item(System.String)"> + <summary> + Gets the value of a property + </summary> + <value> + The value for the property with the specified key + </value> + <remarks> + <para> + Looks up the value for the <paramref name="key"/> specified. + The <see cref="T:log4net.Util.PropertiesDictionary"/> collections are searched + in the order in which they were added to this collection. The value + returned is the value held by the first collection that contains + the specified key. + </para> + <para> + If none of the collections contain the specified key then + <c>null</c> is returned. + </para> + </remarks> + </member> + <member name="T:log4net.Util.ContextPropertiesBase"> + <summary> + Base class for Context Properties implementations + </summary> + <remarks> + <para> + This class defines a basic property get set accessor + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="P:log4net.Util.ContextPropertiesBase.Item(System.String)"> + <summary> + Gets or sets the value of a property + </summary> + <value> + The value for the property with the specified key + </value> + <remarks> + <para> + Gets or sets the value of a property + </para> + </remarks> + </member> + <member name="T:log4net.Util.CountingQuietTextWriter"> + <summary> + Subclass of <see cref="T:log4net.Util.QuietTextWriter"/> that maintains a count of + the number of bytes written. + </summary> + <remarks> + <para> + This writer counts the number of bytes written. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Util.QuietTextWriter"> + <summary> + <see cref="T:System.IO.TextWriter"/> that does not leak exceptions + </summary> + <remarks> + <para> + <see cref="T:log4net.Util.QuietTextWriter"/> does not throw exceptions when things go wrong. + Instead, it delegates error handling to its <see cref="T:log4net.Core.IErrorHandler"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Util.TextWriterAdapter"> + <summary> + Adapter that extends <see cref="T:System.IO.TextWriter"/> and forwards all + messages to an instance of <see cref="T:System.IO.TextWriter"/>. + </summary> + <remarks> + <para> + Adapter that extends <see cref="T:System.IO.TextWriter"/> and forwards all + messages to an instance of <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.TextWriterAdapter.m_writer"> + <summary> + The writer to forward messages to + </summary> + </member> + <member name="M:log4net.Util.TextWriterAdapter.#ctor(System.IO.TextWriter)"> + <summary> + Create an instance of <see cref="T:log4net.Util.TextWriterAdapter"/> that forwards all + messages to a <see cref="T:System.IO.TextWriter"/>. + </summary> + <param name="writer">The <see cref="T:System.IO.TextWriter"/> to forward to</param> + <remarks> + <para> + Create an instance of <see cref="T:log4net.Util.TextWriterAdapter"/> that forwards all + messages to a <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.TextWriterAdapter.Close"> + <summary> + Closes the writer and releases any system resources associated with the writer + </summary> + <remarks> + <para> + </para> + </remarks> + </member> + <member name="M:log4net.Util.TextWriterAdapter.Dispose(System.Boolean)"> + <summary> + Dispose this writer + </summary> + <param name="disposing">flag indicating if we are being disposed</param> + <remarks> + <para> + Dispose this writer + </para> + </remarks> + </member> + <member name="M:log4net.Util.TextWriterAdapter.Flush"> + <summary> + Flushes any buffered output + </summary> + <remarks> + <para> + Clears all buffers for the writer and causes any buffered data to be written + to the underlying device + </para> + </remarks> + </member> + <member name="M:log4net.Util.TextWriterAdapter.Write(System.Char)"> + <summary> + Writes a character to the wrapped TextWriter + </summary> + <param name="value">the value to write to the TextWriter</param> + <remarks> + <para> + Writes a character to the wrapped TextWriter + </para> + </remarks> + </member> + <member name="M:log4net.Util.TextWriterAdapter.Write(System.Char[],System.Int32,System.Int32)"> + <summary> + Writes a character buffer to the wrapped TextWriter + </summary> + <param name="buffer">the data buffer</param> + <param name="index">the start index</param> + <param name="count">the number of characters to write</param> + <remarks> + <para> + Writes a character buffer to the wrapped TextWriter + </para> + </remarks> + </member> + <member name="M:log4net.Util.TextWriterAdapter.Write(System.String)"> + <summary> + Writes a string to the wrapped TextWriter + </summary> + <param name="value">the value to write to the TextWriter</param> + <remarks> + <para> + Writes a string to the wrapped TextWriter + </para> + </remarks> + </member> + <member name="P:log4net.Util.TextWriterAdapter.Writer"> + <summary> + Gets or sets the underlying <see cref="T:System.IO.TextWriter"/>. + </summary> + <value> + The underlying <see cref="T:System.IO.TextWriter"/>. + </value> + <remarks> + <para> + Gets or sets the underlying <see cref="T:System.IO.TextWriter"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.TextWriterAdapter.Encoding"> + <summary> + The Encoding in which the output is written + </summary> + <value> + The <see cref="P:log4net.Util.TextWriterAdapter.Encoding"/> + </value> + <remarks> + <para> + The Encoding in which the output is written + </para> + </remarks> + </member> + <member name="P:log4net.Util.TextWriterAdapter.FormatProvider"> + <summary> + Gets an object that controls formatting + </summary> + <value> + The format provider + </value> + <remarks> + <para> + Gets an object that controls formatting + </para> + </remarks> + </member> + <member name="P:log4net.Util.TextWriterAdapter.NewLine"> + <summary> + Gets or sets the line terminator string used by the TextWriter + </summary> + <value> + The line terminator to use + </value> + <remarks> + <para> + Gets or sets the line terminator string used by the TextWriter + </para> + </remarks> + </member> + <member name="M:log4net.Util.QuietTextWriter.#ctor(System.IO.TextWriter,log4net.Core.IErrorHandler)"> + <summary> + Constructor + </summary> + <param name="writer">the writer to actually write to</param> + <param name="errorHandler">the error handler to report error to</param> + <remarks> + <para> + Create a new QuietTextWriter using a writer and error handler + </para> + </remarks> + </member> + <member name="M:log4net.Util.QuietTextWriter.Write(System.Char)"> + <summary> + Writes a character to the underlying writer + </summary> + <param name="value">the char to write</param> + <remarks> + <para> + Writes a character to the underlying writer + </para> + </remarks> + </member> + <member name="M:log4net.Util.QuietTextWriter.Write(System.Char[],System.Int32,System.Int32)"> + <summary> + Writes a buffer to the underlying writer + </summary> + <param name="buffer">the buffer to write</param> + <param name="index">the start index to write from</param> + <param name="count">the number of characters to write</param> + <remarks> + <para> + Writes a buffer to the underlying writer + </para> + </remarks> + </member> + <member name="M:log4net.Util.QuietTextWriter.Write(System.String)"> + <summary> + Writes a string to the output. + </summary> + <param name="value">The string data to write to the output.</param> + <remarks> + <para> + Writes a string to the output. + </para> + </remarks> + </member> + <member name="M:log4net.Util.QuietTextWriter.Close"> + <summary> + Closes the underlying output writer. + </summary> + <remarks> + <para> + Closes the underlying output writer. + </para> + </remarks> + </member> + <member name="F:log4net.Util.QuietTextWriter.m_errorHandler"> + <summary> + The error handler instance to pass all errors to + </summary> + </member> + <member name="F:log4net.Util.QuietTextWriter.m_closed"> + <summary> + Flag to indicate if this writer is closed + </summary> + </member> + <member name="P:log4net.Util.QuietTextWriter.ErrorHandler"> + <summary> + Gets or sets the error handler that all errors are passed to. + </summary> + <value> + The error handler that all errors are passed to. + </value> + <remarks> + <para> + Gets or sets the error handler that all errors are passed to. + </para> + </remarks> + </member> + <member name="P:log4net.Util.QuietTextWriter.Closed"> + <summary> + Gets a value indicating whether this writer is closed. + </summary> + <value> + <c>true</c> if this writer is closed, otherwise <c>false</c>. + </value> + <remarks> + <para> + Gets a value indicating whether this writer is closed. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CountingQuietTextWriter.#ctor(System.IO.TextWriter,log4net.Core.IErrorHandler)"> + <summary> + Constructor + </summary> + <param name="writer">The <see cref="T:System.IO.TextWriter"/> to actually write to.</param> + <param name="errorHandler">The <see cref="T:log4net.Core.IErrorHandler"/> to report errors to.</param> + <remarks> + <para> + Creates a new instance of the <see cref="T:log4net.Util.CountingQuietTextWriter"/> class + with the specified <see cref="T:System.IO.TextWriter"/> and <see cref="T:log4net.Core.IErrorHandler"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.Char)"> + <summary> + Writes a character to the underlying writer and counts the number of bytes written. + </summary> + <param name="value">the char to write</param> + <remarks> + <para> + Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts + the number of bytes written. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.Char[],System.Int32,System.Int32)"> + <summary> + Writes a buffer to the underlying writer and counts the number of bytes written. + </summary> + <param name="buffer">the buffer to write</param> + <param name="index">the start index to write from</param> + <param name="count">the number of characters to write</param> + <remarks> + <para> + Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts + the number of bytes written. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.String)"> + <summary> + Writes a string to the output and counts the number of bytes written. + </summary> + <param name="str">The string data to write to the output.</param> + <remarks> + <para> + Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts + the number of bytes written. + </para> + </remarks> + </member> + <member name="F:log4net.Util.CountingQuietTextWriter.m_countBytes"> + <summary> + Total number of bytes written. + </summary> + </member> + <member name="P:log4net.Util.CountingQuietTextWriter.Count"> + <summary> + Gets or sets the total number of bytes written. + </summary> + <value> + The total number of bytes written. + </value> + <remarks> + <para> + Gets or sets the total number of bytes written. + </para> + </remarks> + </member> + <member name="T:log4net.Util.CyclicBuffer"> + <summary> + A fixed size rolling buffer of logging events. + </summary> + <remarks> + <para> + An array backed fixed size leaky bucket. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.CyclicBuffer.#ctor(System.Int32)"> + <summary> + Constructor + </summary> + <param name="maxSize">The maximum number of logging events in the buffer.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.CyclicBuffer"/> class with + the specified maximum number of buffered logging events. + </para> + </remarks> + <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="maxSize"/> argument is not a positive integer.</exception> + </member> + <member name="M:log4net.Util.CyclicBuffer.Append(log4net.Core.LoggingEvent)"> + <summary> + Appends a <paramref name="loggingEvent"/> to the buffer. + </summary> + <param name="loggingEvent">The event to append to the buffer.</param> + <returns>The event discarded from the buffer, if the buffer is full, otherwise <c>null</c>.</returns> + <remarks> + <para> + Append an event to the buffer. If the buffer still contains free space then + <c>null</c> is returned. If the buffer is full then an event will be dropped + to make space for the new event, the event dropped is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CyclicBuffer.PopOldest"> + <summary> + Get and remove the oldest event in the buffer. + </summary> + <returns>The oldest logging event in the buffer</returns> + <remarks> + <para> + Gets the oldest (first) logging event in the buffer and removes it + from the buffer. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CyclicBuffer.PopAll"> + <summary> + Pops all the logging events from the buffer into an array. + </summary> + <returns>An array of all the logging events in the buffer.</returns> + <remarks> + <para> + Get all the events in the buffer and clear the buffer. + </para> + </remarks> + </member> + <member name="M:log4net.Util.CyclicBuffer.Clear"> + <summary> + Clear the buffer + </summary> + <remarks> + <para> + Clear the buffer of all events. The events in the buffer are lost. + </para> + </remarks> + </member> + <member name="P:log4net.Util.CyclicBuffer.Item(System.Int32)"> + <summary> + Gets the <paramref name="i"/>th oldest event currently in the buffer. + </summary> + <value>The <paramref name="i"/>th oldest event currently in the buffer.</value> + <remarks> + <para> + If <paramref name="i"/> is outside the range 0 to the number of events + currently in the buffer, then <c>null</c> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Util.CyclicBuffer.MaxSize"> + <summary> + Gets the maximum size of the buffer. + </summary> + <value>The maximum size of the buffer.</value> + <remarks> + <para> + Gets the maximum size of the buffer + </para> + </remarks> + </member> + <member name="P:log4net.Util.CyclicBuffer.Length"> + <summary> + Gets the number of logging events in the buffer. + </summary> + <value>The number of logging events in the buffer.</value> + <remarks> + <para> + This number is guaranteed to be in the range 0 to <see cref="P:log4net.Util.CyclicBuffer.MaxSize"/> + (inclusive). + </para> + </remarks> + </member> + <member name="T:log4net.Util.EmptyCollection"> + <summary> + An always empty <see cref="T:System.Collections.ICollection"/>. + </summary> + <remarks> + <para> + A singleton implementation of the <see cref="T:System.Collections.ICollection"/> + interface that always represents an empty collection. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.EmptyCollection.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.EmptyCollection"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to enforce the singleton pattern. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyCollection.CopyTo(System.Array,System.Int32)"> + <summary> + Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an + <see cref="T:System.Array"/>, starting at a particular Array index. + </summary> + <param name="array">The one-dimensional <see cref="T:System.Array"/> + that is the destination of the elements copied from + <see cref="T:System.Collections.ICollection"/>. The Array must have zero-based + indexing.</param> + <param name="index">The zero-based index in array at which + copying begins.</param> + <remarks> + <para> + As the collection is empty no values are copied into the array. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyCollection.GetEnumerator"> + <summary> + Returns an enumerator that can iterate through a collection. + </summary> + <returns> + An <see cref="T:System.Collections.IEnumerator"/> that can be used to + iterate through the collection. + </returns> + <remarks> + <para> + As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned. + </para> + </remarks> + </member> + <member name="F:log4net.Util.EmptyCollection.s_instance"> + <summary> + The singleton instance of the empty collection. + </summary> + </member> + <member name="P:log4net.Util.EmptyCollection.Instance"> + <summary> + Gets the singleton instance of the empty collection. + </summary> + <returns>The singleton instance of the empty collection.</returns> + <remarks> + <para> + Gets the singleton instance of the empty collection. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyCollection.IsSynchronized"> + <summary> + Gets a value indicating if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe). + </summary> + <value> + <b>true</b> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe); otherwise, <b>false</b>. + </value> + <remarks> + <para> + For the <see cref="T:log4net.Util.EmptyCollection"/> this property is always <c>true</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyCollection.Count"> + <summary> + Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>. + </summary> + <value> + The number of elements contained in the <see cref="T:System.Collections.ICollection"/>. + </value> + <remarks> + <para> + As the collection is empty the <see cref="P:log4net.Util.EmptyCollection.Count"/> is always <c>0</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyCollection.SyncRoot"> + <summary> + Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>. + </summary> + <value> + An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>. + </value> + <remarks> + <para> + As the collection is empty and thread safe and synchronized this instance is also + the <see cref="P:log4net.Util.EmptyCollection.SyncRoot"/> object. + </para> + </remarks> + </member> + <member name="T:log4net.Util.EmptyDictionary"> + <summary> + An always empty <see cref="T:System.Collections.IDictionary"/>. + </summary> + <remarks> + <para> + A singleton implementation of the <see cref="T:System.Collections.IDictionary"/> + interface that always represents an empty collection. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.EmptyDictionary.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.EmptyDictionary"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to enforce the singleton pattern. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyDictionary.CopyTo(System.Array,System.Int32)"> + <summary> + Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an + <see cref="T:System.Array"/>, starting at a particular Array index. + </summary> + <param name="array">The one-dimensional <see cref="T:System.Array"/> + that is the destination of the elements copied from + <see cref="T:System.Collections.ICollection"/>. The Array must have zero-based + indexing.</param> + <param name="index">The zero-based index in array at which + copying begins.</param> + <remarks> + <para> + As the collection is empty no values are copied into the array. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyDictionary.System#Collections#IEnumerable#GetEnumerator"> + <summary> + Returns an enumerator that can iterate through a collection. + </summary> + <returns> + An <see cref="T:System.Collections.IEnumerator"/> that can be used to + iterate through the collection. + </returns> + <remarks> + <para> + As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyDictionary.Add(System.Object,System.Object)"> + <summary> + Adds an element with the provided key and value to the + <see cref="T:log4net.Util.EmptyDictionary"/>. + </summary> + <param name="key">The <see cref="T:System.Object"/> to use as the key of the element to add.</param> + <param name="value">The <see cref="T:System.Object"/> to use as the value of the element to add.</param> + <remarks> + <para> + As the collection is empty no new values can be added. A <see cref="T:System.InvalidOperationException"/> + is thrown if this method is called. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception> + </member> + <member name="M:log4net.Util.EmptyDictionary.Clear"> + <summary> + Removes all elements from the <see cref="T:log4net.Util.EmptyDictionary"/>. + </summary> + <remarks> + <para> + As the collection is empty no values can be removed. A <see cref="T:System.InvalidOperationException"/> + is thrown if this method is called. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception> + </member> + <member name="M:log4net.Util.EmptyDictionary.Contains(System.Object)"> + <summary> + Determines whether the <see cref="T:log4net.Util.EmptyDictionary"/> contains an element + with the specified key. + </summary> + <param name="key">The key to locate in the <see cref="T:log4net.Util.EmptyDictionary"/>.</param> + <returns><c>false</c></returns> + <remarks> + <para> + As the collection is empty the <see cref="M:log4net.Util.EmptyDictionary.Contains(System.Object)"/> method always returns <c>false</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyDictionary.GetEnumerator"> + <summary> + Returns an enumerator that can iterate through a collection. + </summary> + <returns> + An <see cref="T:System.Collections.IEnumerator"/> that can be used to + iterate through the collection. + </returns> + <remarks> + <para> + As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.EmptyDictionary.Remove(System.Object)"> + <summary> + Removes the element with the specified key from the <see cref="T:log4net.Util.EmptyDictionary"/>. + </summary> + <param name="key">The key of the element to remove.</param> + <remarks> + <para> + As the collection is empty no values can be removed. A <see cref="T:System.InvalidOperationException"/> + is thrown if this method is called. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception> + </member> + <member name="F:log4net.Util.EmptyDictionary.s_instance"> + <summary> + The singleton instance of the empty dictionary. + </summary> + </member> + <member name="P:log4net.Util.EmptyDictionary.Instance"> + <summary> + Gets the singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>. + </summary> + <returns>The singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.</returns> + <remarks> + <para> + Gets the singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.IsSynchronized"> + <summary> + Gets a value indicating if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe). + </summary> + <value> + <b>true</b> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe); otherwise, <b>false</b>. + </value> + <remarks> + <para> + For the <see cref="T:log4net.Util.EmptyCollection"/> this property is always <b>true</b>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.Count"> + <summary> + Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/> + </summary> + <value> + The number of elements contained in the <see cref="T:System.Collections.ICollection"/>. + </value> + <remarks> + <para> + As the collection is empty the <see cref="P:log4net.Util.EmptyDictionary.Count"/> is always <c>0</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.SyncRoot"> + <summary> + Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>. + </summary> + <value> + An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>. + </value> + <remarks> + <para> + As the collection is empty and thread safe and synchronized this instance is also + the <see cref="P:log4net.Util.EmptyDictionary.SyncRoot"/> object. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.IsFixedSize"> + <summary> + Gets a value indicating whether the <see cref="T:log4net.Util.EmptyDictionary"/> has a fixed size. + </summary> + <value><c>true</c></value> + <remarks> + <para> + As the collection is empty <see cref="P:log4net.Util.EmptyDictionary.IsFixedSize"/> always returns <c>true</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.IsReadOnly"> + <summary> + Gets a value indicating whether the <see cref="T:log4net.Util.EmptyDictionary"/> is read-only. + </summary> + <value><c>true</c></value> + <remarks> + <para> + As the collection is empty <see cref="P:log4net.Util.EmptyDictionary.IsReadOnly"/> always returns <c>true</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.Keys"> + <summary> + Gets an <see cref="T:System.Collections.ICollection"/> containing the keys of the <see cref="T:log4net.Util.EmptyDictionary"/>. + </summary> + <value>An <see cref="T:System.Collections.ICollection"/> containing the keys of the <see cref="T:log4net.Util.EmptyDictionary"/>.</value> + <remarks> + <para> + As the collection is empty a <see cref="T:log4net.Util.EmptyCollection"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.Values"> + <summary> + Gets an <see cref="T:System.Collections.ICollection"/> containing the values of the <see cref="T:log4net.Util.EmptyDictionary"/>. + </summary> + <value>An <see cref="T:System.Collections.ICollection"/> containing the values of the <see cref="T:log4net.Util.EmptyDictionary"/>.</value> + <remarks> + <para> + As the collection is empty a <see cref="T:log4net.Util.EmptyCollection"/> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Util.EmptyDictionary.Item(System.Object)"> + <summary> + Gets or sets the element with the specified key. + </summary> + <param name="key">The key of the element to get or set.</param> + <value><c>null</c></value> + <remarks> + <para> + As the collection is empty no values can be looked up or stored. + If the index getter is called then <c>null</c> is returned. + A <see cref="T:System.InvalidOperationException"/> is thrown if the setter is called. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception> + </member> + <member name="T:log4net.Util.FormattingInfo"> + <summary> + Contain the information obtained when parsing formatting modifiers + in conversion modifiers. + </summary> + <remarks> + <para> + Holds the formatting information extracted from the format string by + the <see cref="T:log4net.Util.PatternParser"/>. This is used by the <see cref="T:log4net.Util.PatternConverter"/> + objects when rendering the output. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.FormattingInfo.#ctor"> + <summary> + Defaut Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.FormattingInfo"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.FormattingInfo.#ctor(System.Int32,System.Int32,System.Boolean)"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.FormattingInfo"/> class + with the specified parameters. + </para> + </remarks> + </member> + <member name="P:log4net.Util.FormattingInfo.Min"> + <summary> + Gets or sets the minimum value. + </summary> + <value> + The minimum value. + </value> + <remarks> + <para> + Gets or sets the minimum value. + </para> + </remarks> + </member> + <member name="P:log4net.Util.FormattingInfo.Max"> + <summary> + Gets or sets the maximum value. + </summary> + <value> + The maximum value. + </value> + <remarks> + <para> + Gets or sets the maximum value. + </para> + </remarks> + </member> + <member name="P:log4net.Util.FormattingInfo.LeftAlign"> + <summary> + Gets or sets a flag indicating whether left align is enabled + or not. + </summary> + <value> + A flag indicating whether left align is enabled or not. + </value> + <remarks> + <para> + Gets or sets a flag indicating whether left align is enabled or not. + </para> + </remarks> + </member> + <member name="T:log4net.Util.GlobalContextProperties"> + <summary> + Implementation of Properties collection for the <see cref="T:log4net.GlobalContext"/> + </summary> + <remarks> + <para> + This class implements a properties collection that is thread safe and supports both + storing properties and capturing a read only copy of the current propertied. + </para> + <para> + This class is optimized to the scenario where the properties are read frequently + and are modified infrequently. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.GlobalContextProperties.m_readOnlyProperties"> + <summary> + The read only copy of the properties. + </summary> + <remarks> + <para> + This variable is declared <c>volatile</c> to prevent the compiler and JIT from + reordering reads and writes of this thread performed on different threads. + </para> + </remarks> + </member> + <member name="F:log4net.Util.GlobalContextProperties.m_syncRoot"> + <summary> + Lock object used to synchronize updates within this instance + </summary> + </member> + <member name="M:log4net.Util.GlobalContextProperties.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.GlobalContextProperties"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.GlobalContextProperties.Remove(System.String)"> + <summary> + Remove a property from the global context + </summary> + <param name="key">the key for the entry to remove</param> + <remarks> + <para> + Removing an entry from the global context properties is relatively expensive compared + with reading a value. + </para> + </remarks> + </member> + <member name="M:log4net.Util.GlobalContextProperties.Clear"> + <summary> + Clear the global context properties + </summary> + </member> + <member name="M:log4net.Util.GlobalContextProperties.GetReadOnlyProperties"> + <summary> + Get a readonly immutable copy of the properties + </summary> + <returns>the current global context properties</returns> + <remarks> + <para> + This implementation is fast because the GlobalContextProperties class + stores a readonly copy of the properties. + </para> + </remarks> + </member> + <member name="P:log4net.Util.GlobalContextProperties.Item(System.String)"> + <summary> + Gets or sets the value of a property + </summary> + <value> + The value for the property with the specified key + </value> + <remarks> + <para> + Reading the value for a key is faster than setting the value. + When the value is written a new read only copy of + the properties is created. + </para> + </remarks> + </member> + <member name="T:log4net.Util.LevelMapping"> + <summary> + Manages a mapping from levels to <see cref="T:log4net.Util.LevelMappingEntry"/> + </summary> + <remarks> + <para> + Manages an ordered mapping from <see cref="T:log4net.Core.Level"/> instances + to <see cref="T:log4net.Util.LevelMappingEntry"/> subclasses. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.LevelMapping.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Initialise a new instance of <see cref="T:log4net.Util.LevelMapping"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LevelMapping.Add(log4net.Util.LevelMappingEntry)"> + <summary> + Add a <see cref="T:log4net.Util.LevelMappingEntry"/> to this mapping + </summary> + <param name="entry">the entry to add</param> + <remarks> + <para> + If a <see cref="T:log4net.Util.LevelMappingEntry"/> has previously been added + for the same <see cref="T:log4net.Core.Level"/> then that entry will be + overwritten. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LevelMapping.Lookup(log4net.Core.Level)"> + <summary> + Lookup the mapping for the specified level + </summary> + <param name="level">the level to lookup</param> + <returns>the <see cref="T:log4net.Util.LevelMappingEntry"/> for the level or <c>null</c> if no mapping found</returns> + <remarks> + <para> + Lookup the value for the specified level. Finds the nearest + mapping value for the level that is equal to or less than the + <paramref name="level"/> specified. + </para> + <para> + If no mapping could be found then <c>null</c> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LevelMapping.ActivateOptions"> + <summary> + Initialize options + </summary> + <remarks> + <para> + Caches the sorted list of <see cref="T:log4net.Util.LevelMappingEntry"/> in an array + </para> + </remarks> + </member> + <member name="T:log4net.Util.LogicalThreadContextProperties"> + <summary> + Implementation of Properties collection for the <see cref="T:log4net.LogicalThreadContext"/> + </summary> + <remarks> + <para> + Class implements a collection of properties that is specific to each thread. + The class is not synchronized as each thread has its own <see cref="T:log4net.Util.PropertiesDictionary"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.LogicalThreadContextProperties.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.LogicalThreadContextProperties"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogicalThreadContextProperties.Remove(System.String)"> + <summary> + Remove a property + </summary> + <param name="key">the key for the entry to remove</param> + <remarks> + <para> + Remove the value for the specified <paramref name="key"/> from the context. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogicalThreadContextProperties.Clear"> + <summary> + Clear all the context properties + </summary> + <remarks> + <para> + Clear all the context properties + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogicalThreadContextProperties.GetProperties(System.Boolean)"> + <summary> + Get the PropertiesDictionary stored in the LocalDataStoreSlot for this thread. + </summary> + <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param> + <returns>the properties for this thread</returns> + <remarks> + <para> + The collection returned is only to be used on the calling thread. If the + caller needs to share the collection between different threads then the + caller must clone the collection before doings so. + </para> + </remarks> + </member> + <member name="P:log4net.Util.LogicalThreadContextProperties.Item(System.String)"> + <summary> + Gets or sets the value of a property + </summary> + <value> + The value for the property with the specified key + </value> + <remarks> + <para> + Get or set the property value for the <paramref name="key"/> specified. + </para> + </remarks> + </member> + <member name="T:log4net.Util.LogLog"> + <summary> + Outputs log statements from within the log4net assembly. + </summary> + <remarks> + <para> + Log4net components cannot make log4net logging calls. However, it is + sometimes useful for the user to learn about what log4net is + doing. + </para> + <para> + All log4net internal debug calls go to the standard output stream + whereas internal error messages are sent to the standard error output + stream. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.LogLog.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.LogLog"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to prevent instantiation of this class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.#cctor"> + <summary> + Static constructor that initializes logging by reading + settings from the application configuration file. + </summary> + <remarks> + <para> + The <c>log4net.Internal.Debug</c> application setting + controls internal debugging. This setting should be set + to <c>true</c> to enable debugging. + </para> + <para> + The <c>log4net.Internal.Quiet</c> application setting + suppresses all internal logging including error messages. + This setting should be set to <c>true</c> to enable message + suppression. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.Debug(System.String)"> + <summary> + Writes log4net internal debug messages to the + standard output stream. + </summary> + <param name="message">The message to log.</param> + <remarks> + <para> + All internal debug messages are prepended with + the string "log4net: ". + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.Debug(System.String,System.Exception)"> + <summary> + Writes log4net internal debug messages to the + standard output stream. + </summary> + <param name="message">The message to log.</param> + <param name="exception">An exception to log.</param> + <remarks> + <para> + All internal debug messages are prepended with + the string "log4net: ". + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.Warn(System.String)"> + <summary> + Writes log4net internal warning messages to the + standard error stream. + </summary> + <param name="message">The message to log.</param> + <remarks> + <para> + All internal warning messages are prepended with + the string "log4net:WARN ". + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.Warn(System.String,System.Exception)"> + <summary> + Writes log4net internal warning messages to the + standard error stream. + </summary> + <param name="message">The message to log.</param> + <param name="exception">An exception to log.</param> + <remarks> + <para> + All internal warning messages are prepended with + the string "log4net:WARN ". + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.Error(System.String)"> + <summary> + Writes log4net internal error messages to the + standard error stream. + </summary> + <param name="message">The message to log.</param> + <remarks> + <para> + All internal error messages are prepended with + the string "log4net:ERROR ". + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.Error(System.String,System.Exception)"> + <summary> + Writes log4net internal error messages to the + standard error stream. + </summary> + <param name="message">The message to log.</param> + <param name="exception">An exception to log.</param> + <remarks> + <para> + All internal debug messages are prepended with + the string "log4net:ERROR ". + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.EmitOutLine(System.String)"> + <summary> + Writes output to the standard output stream. + </summary> + <param name="message">The message to log.</param> + <remarks> + <para> + Writes to both Console.Out and System.Diagnostics.Trace. + Note that the System.Diagnostics.Trace is not supported + on the Compact Framework. + </para> + <para> + If the AppDomain is not configured with a config file then + the call to System.Diagnostics.Trace may fail. This is only + an issue if you are programmatically creating your own AppDomains. + </para> + </remarks> + </member> + <member name="M:log4net.Util.LogLog.EmitErrorLine(System.String)"> + <summary> + Writes output to the standard error stream. + </summary> + <param name="message">The message to log.</param> + <remarks> + <para> + Writes to both Console.Error and System.Diagnostics.Trace. + Note that the System.Diagnostics.Trace is not supported + on the Compact Framework. + </para> + <para> + If the AppDomain is not configured with a config file then + the call to System.Diagnostics.Trace may fail. This is only + an issue if you are programmatically creating your own AppDomains. + </para> + </remarks> + </member> + <member name="F:log4net.Util.LogLog.s_debugEnabled"> + <summary> + Default debug level + </summary> + </member> + <member name="F:log4net.Util.LogLog.s_quietMode"> + <summary> + In quietMode not even errors generate any output. + </summary> + </member> + <member name="P:log4net.Util.LogLog.InternalDebugging"> + <summary> + Gets or sets a value indicating whether log4net internal logging + is enabled or disabled. + </summary> + <value> + <c>true</c> if log4net internal logging is enabled, otherwise + <c>false</c>. + </value> + <remarks> + <para> + When set to <c>true</c>, internal debug level logging will be + displayed. + </para> + <para> + This value can be set by setting the application setting + <c>log4net.Internal.Debug</c> in the application configuration + file. + </para> + <para> + The default value is <c>false</c>, i.e. debugging is + disabled. + </para> + </remarks> + <example> + <para> + The following example enables internal debugging using the + application configuration file : + </para> + <code lang="XML" escaped="true"> + <configuration> + <appSettings> + <add key="log4net.Internal.Debug" value="true" /> + </appSettings> + </configuration> + </code> + </example> + </member> + <member name="P:log4net.Util.LogLog.QuietMode"> + <summary> + Gets or sets a value indicating whether log4net should generate no output + from internal logging, not even for errors. + </summary> + <value> + <c>true</c> if log4net should generate no output at all from internal + logging, otherwise <c>false</c>. + </value> + <remarks> + <para> + When set to <c>true</c> will cause internal logging at all levels to be + suppressed. This means that no warning or error reports will be logged. + This option overrides the <see cref="P:log4net.Util.LogLog.InternalDebugging"/> setting and + disables all debug also. + </para> + <para>This value can be set by setting the application setting + <c>log4net.Internal.Quiet</c> in the application configuration file. + </para> + <para> + The default value is <c>false</c>, i.e. internal logging is not + disabled. + </para> + </remarks> + <example> + The following example disables internal logging using the + application configuration file : + <code lang="XML" escaped="true"> + <configuration> + <appSettings> + <add key="log4net.Internal.Quiet" value="true"/> + </appSettings> + </configuration> + </code> + </example> + </member> + <member name="P:log4net.Util.LogLog.IsDebugEnabled"> + <summary> + Test if LogLog.Debug is enabled for output. + </summary> + <value> + <c>true</c> if Debug is enabled + </value> + <remarks> + <para> + Test if LogLog.Debug is enabled for output. + </para> + </remarks> + </member> + <member name="P:log4net.Util.LogLog.IsWarnEnabled"> + <summary> + Test if LogLog.Warn is enabled for output. + </summary> + <value> + <c>true</c> if Warn is enabled + </value> + <remarks> + <para> + Test if LogLog.Warn is enabled for output. + </para> + </remarks> + </member> + <member name="P:log4net.Util.LogLog.IsErrorEnabled"> + <summary> + Test if LogLog.Error is enabled for output. + </summary> + <value> + <c>true</c> if Error is enabled + </value> + <remarks> + <para> + Test if LogLog.Error is enabled for output. + </para> + </remarks> + </member> + <member name="T:log4net.Util.NativeError"> + <summary> + Represents a native error code and message. + </summary> + <remarks> + <para> + Represents a Win32 platform native error. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.NativeError.#ctor(System.Int32,System.String)"> + <summary> + Create an instance of the <see cref="T:log4net.Util.NativeError"/> class with the specified + error number and message. + </summary> + <param name="number">The number of the native error.</param> + <param name="message">The message of the native error.</param> + <remarks> + <para> + Create an instance of the <see cref="T:log4net.Util.NativeError"/> class with the specified + error number and message. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NativeError.GetLastError"> + <summary> + Create a new instance of the <see cref="T:log4net.Util.NativeError"/> class for the last Windows error. + </summary> + <returns> + An instance of the <see cref="T:log4net.Util.NativeError"/> class for the last windows error. + </returns> + <remarks> + <para> + The message for the <see cref="M:System.Runtime.InteropServices.Marshal.GetLastWin32Error"/> error number is lookup up using the + native Win32 <c>FormatMessage</c> function. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NativeError.GetError(System.Int32)"> + <summary> + Create a new instance of the <see cref="T:log4net.Util.NativeError"/> class. + </summary> + <param name="number">the error number for the native error</param> + <returns> + An instance of the <see cref="T:log4net.Util.NativeError"/> class for the specified + error number. + </returns> + <remarks> + <para> + The message for the specified error number is lookup up using the + native Win32 <c>FormatMessage</c> function. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NativeError.GetErrorMessage(System.Int32)"> + <summary> + Retrieves the message corresponding with a Win32 message identifier. + </summary> + <param name="messageId">Message identifier for the requested message.</param> + <returns> + The message corresponding with the specified message identifier. + </returns> + <remarks> + <para> + The message will be searched for in system message-table resource(s) + using the native <c>FormatMessage</c> function. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NativeError.ToString"> + <summary> + Return error information string + </summary> + <returns>error information string</returns> + <remarks> + <para> + Return error information string + </para> + </remarks> + </member> + <member name="M:log4net.Util.NativeError.FormatMessage(System.Int32,System.IntPtr@,System.Int32,System.Int32,System.String@,System.Int32,System.IntPtr)"> + <summary> + Formats a message string. + </summary> + <param name="dwFlags">Formatting options, and how to interpret the <paramref name="lpSource"/> parameter.</param> + <param name="lpSource">Location of the message definition.</param> + <param name="dwMessageId">Message identifier for the requested message.</param> + <param name="dwLanguageId">Language identifier for the requested message.</param> + <param name="lpBuffer">If <paramref name="dwFlags"/> includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the <c>LocalAlloc</c> function, and places the pointer to the buffer at the address specified in <paramref name="lpBuffer"/>.</param> + <param name="nSize">If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of TCHARs to allocate for an output buffer.</param> + <param name="Arguments">Pointer to an array of values that are used as insert values in the formatted message.</param> + <remarks> + <para> + The function requires a message definition as input. The message definition can come from a + buffer passed into the function. It can come from a message table resource in an + already-loaded module. Or the caller can ask the function to search the system's message + table resource(s) for the message definition. The function finds the message definition + in a message table resource based on a message identifier and a language identifier. + The function copies the formatted message text to an output buffer, processing any embedded + insert sequences if requested. + </para> + <para> + To prevent the usage of unsafe code, this stub does not support inserting values in the formatted message. + </para> + </remarks> + <returns> + <para> + If the function succeeds, the return value is the number of TCHARs stored in the output + buffer, excluding the terminating null character. + </para> + <para> + If the function fails, the return value is zero. To get extended error information, + call <see cref="M:System.Runtime.InteropServices.Marshal.GetLastWin32Error"/>. + </para> + </returns> + </member> + <member name="P:log4net.Util.NativeError.Number"> + <summary> + Gets the number of the native error. + </summary> + <value> + The number of the native error. + </value> + <remarks> + <para> + Gets the number of the native error. + </para> + </remarks> + </member> + <member name="P:log4net.Util.NativeError.Message"> + <summary> + Gets the message of the native error. + </summary> + <value> + The message of the native error. + </value> + <remarks> + <para> + </para> + Gets the message of the native error. + </remarks> + </member> + <member name="T:log4net.Util.NullDictionaryEnumerator"> + <summary> + An always empty <see cref="T:System.Collections.IDictionaryEnumerator"/>. + </summary> + <remarks> + <para> + A singleton implementation of the <see cref="T:System.Collections.IDictionaryEnumerator"/> over a collection + that is empty and not modifiable. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.NullDictionaryEnumerator.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to enforce the singleton pattern. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NullDictionaryEnumerator.MoveNext"> + <summary> + Test if the enumerator can advance, if so advance. + </summary> + <returns><c>false</c> as the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> cannot advance.</returns> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="M:log4net.Util.NullDictionaryEnumerator.MoveNext"/> + will always return <c>false</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NullDictionaryEnumerator.Reset"> + <summary> + Resets the enumerator back to the start. + </summary> + <remarks> + <para> + As the enumerator is over an empty collection <see cref="M:log4net.Util.NullDictionaryEnumerator.Reset"/> does nothing. + </para> + </remarks> + </member> + <member name="F:log4net.Util.NullDictionaryEnumerator.s_instance"> + <summary> + The singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>. + </summary> + </member> + <member name="P:log4net.Util.NullDictionaryEnumerator.Instance"> + <summary> + Gets the singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>. + </summary> + <returns>The singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.</returns> + <remarks> + <para> + Gets the singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.NullDictionaryEnumerator.Current"> + <summary> + Gets the current object from the enumerator. + </summary> + <remarks> + Throws an <see cref="T:System.InvalidOperationException"/> because the + <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value. + </remarks> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + will throw an <see cref="T:System.InvalidOperationException"/>. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + cannot be positioned over a valid location.</exception> + </member> + <member name="P:log4net.Util.NullDictionaryEnumerator.Key"> + <summary> + Gets the current key from the enumerator. + </summary> + <remarks> + Throws an exception because the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> + never has a current value. + </remarks> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Key"/> + will throw an <see cref="T:System.InvalidOperationException"/>. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + cannot be positioned over a valid location.</exception> + </member> + <member name="P:log4net.Util.NullDictionaryEnumerator.Value"> + <summary> + Gets the current value from the enumerator. + </summary> + <value>The current value from the enumerator.</value> + <remarks> + Throws an <see cref="T:System.InvalidOperationException"/> because the + <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value. + </remarks> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Value"/> + will throw an <see cref="T:System.InvalidOperationException"/>. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + cannot be positioned over a valid location.</exception> + </member> + <member name="P:log4net.Util.NullDictionaryEnumerator.Entry"> + <summary> + Gets the current entry from the enumerator. + </summary> + <remarks> + Throws an <see cref="T:System.InvalidOperationException"/> because the + <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current entry. + </remarks> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Entry"/> + will throw an <see cref="T:System.InvalidOperationException"/>. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/> + cannot be positioned over a valid location.</exception> + </member> + <member name="T:log4net.Util.NullEnumerator"> + <summary> + An always empty <see cref="T:System.Collections.IEnumerator"/>. + </summary> + <remarks> + <para> + A singleton implementation of the <see cref="T:System.Collections.IEnumerator"/> over a collection + that is empty and not modifiable. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.NullEnumerator.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.NullEnumerator"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to enforce the singleton pattern. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NullEnumerator.MoveNext"> + <summary> + Test if the enumerator can advance, if so advance + </summary> + <returns><c>false</c> as the <see cref="T:log4net.Util.NullEnumerator"/> cannot advance.</returns> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="M:log4net.Util.NullEnumerator.MoveNext"/> + will always return <c>false</c>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NullEnumerator.Reset"> + <summary> + Resets the enumerator back to the start. + </summary> + <remarks> + <para> + As the enumerator is over an empty collection <see cref="M:log4net.Util.NullEnumerator.Reset"/> does nothing. + </para> + </remarks> + </member> + <member name="F:log4net.Util.NullEnumerator.s_instance"> + <summary> + The singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>. + </summary> + </member> + <member name="P:log4net.Util.NullEnumerator.Instance"> + <summary> + Get the singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>. + </summary> + <returns>The singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.</returns> + <remarks> + <para> + Gets the singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.NullEnumerator.Current"> + <summary> + Gets the current object from the enumerator. + </summary> + <remarks> + Throws an <see cref="T:System.InvalidOperationException"/> because the + <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value. + </remarks> + <remarks> + <para> + As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullEnumerator.Current"/> + value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullEnumerator.Current"/> + will throw an <see cref="T:System.InvalidOperationException"/>. + </para> + </remarks> + <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullEnumerator.Current"/> + cannot be positioned over a valid location.</exception> + </member> + <member name="T:log4net.Util.NullSecurityContext"> + <summary> + A SecurityContext used when a SecurityContext is not required + </summary> + <remarks> + <para> + The <see cref="T:log4net.Util.NullSecurityContext"/> is a no-op implementation of the + <see cref="T:log4net.Core.SecurityContext"/> base class. It is used where a <see cref="T:log4net.Core.SecurityContext"/> + is required but one has not been provided. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.NullSecurityContext.Instance"> + <summary> + Singleton instance of <see cref="T:log4net.Util.NullSecurityContext"/> + </summary> + <remarks> + <para> + Singleton instance of <see cref="T:log4net.Util.NullSecurityContext"/> + </para> + </remarks> + </member> + <member name="M:log4net.Util.NullSecurityContext.#ctor"> + <summary> + Private constructor + </summary> + <remarks> + <para> + Private constructor for singleton pattern. + </para> + </remarks> + </member> + <member name="M:log4net.Util.NullSecurityContext.Impersonate(System.Object)"> + <summary> + Impersonate this SecurityContext + </summary> + <param name="state">State supplied by the caller</param> + <returns><c>null</c></returns> + <remarks> + <para> + No impersonation is done and <c>null</c> is always returned. + </para> + </remarks> + </member> + <member name="T:log4net.Util.OnlyOnceErrorHandler"> + <summary> + Implements log4net's default error handling policy which consists + of emitting a message for the first error in an appender and + ignoring all subsequent errors. + </summary> + <remarks> + <para> + The error message is printed on the standard error output stream. + </para> + <para> + This policy aims at protecting an otherwise working application + from being flooded with error messages when logging fails. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.OnlyOnceErrorHandler.#ctor"> + <summary> + Default Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OnlyOnceErrorHandler.#ctor(System.String)"> + <summary> + Constructor + </summary> + <param name="prefix">The prefix to use for each message.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/> class + with the specified prefix. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"> + <summary> + Log an Error + </summary> + <param name="message">The error message.</param> + <param name="e">The exception.</param> + <param name="errorCode">The internal error code.</param> + <remarks> + <para> + Prints the message and the stack trace of the exception on the standard + error output stream. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String,System.Exception)"> + <summary> + Log an Error + </summary> + <param name="message">The error message.</param> + <param name="e">The exception.</param> + <remarks> + <para> + Prints the message and the stack trace of the exception on the standard + error output stream. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String)"> + <summary> + Log an error + </summary> + <param name="message">The error message.</param> + <remarks> + <para> + Print a the error message passed as parameter on the standard + error output stream. + </para> + </remarks> + </member> + <member name="F:log4net.Util.OnlyOnceErrorHandler.m_firstTime"> + <summary> + Flag to indicate if it is the first error + </summary> + </member> + <member name="F:log4net.Util.OnlyOnceErrorHandler.m_prefix"> + <summary> + String to prefix each message with + </summary> + </member> + <member name="P:log4net.Util.OnlyOnceErrorHandler.IsEnabled"> + <summary> + Is error logging enabled + </summary> + <remarks> + <para> + Is error logging enabled. Logging is only enabled for the + first error delivered to the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/>. + </para> + </remarks> + </member> + <member name="T:log4net.Util.OptionConverter"> + <summary> + A convenience class to convert property values to specific types. + </summary> + <remarks> + <para> + Utility functions for converting types and parsing values. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.OptionConverter.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.OptionConverter"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to prevent instantiation of this class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.ToBoolean(System.String,System.Boolean)"> + <summary> + Converts a string to a <see cref="T:System.Boolean"/> value. + </summary> + <param name="argValue">String to convert.</param> + <param name="defaultValue">The default value.</param> + <returns>The <see cref="T:System.Boolean"/> value of <paramref name="argValue"/>.</returns> + <remarks> + <para> + If <paramref name="argValue"/> is "true", then <c>true</c> is returned. + If <paramref name="argValue"/> is "false", then <c>false</c> is returned. + Otherwise, <paramref name="defaultValue"/> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.ToFileSize(System.String,System.Int64)"> + <summary> + Parses a file size into a number. + </summary> + <param name="argValue">String to parse.</param> + <param name="defaultValue">The default value.</param> + <returns>The <see cref="T:System.Int64"/> value of <paramref name="argValue"/>.</returns> + <remarks> + <para> + Parses a file size of the form: number[KB|MB|GB] into a + long value. It is scaled with the appropriate multiplier. + </para> + <para> + <paramref name="defaultValue"/> is returned when <paramref name="argValue"/> + cannot be converted to a <see cref="T:System.Int64"/> value. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.ConvertStringTo(System.Type,System.String)"> + <summary> + Converts a string to an object. + </summary> + <param name="target">The target type to convert to.</param> + <param name="txt">The string to convert to an object.</param> + <returns> + The object converted from a string or <c>null</c> when the + conversion failed. + </returns> + <remarks> + <para> + Converts a string to an object. Uses the converter registry to try + to convert the string value into the specified target type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.CanConvertTypeTo(System.Type,System.Type)"> + <summary> + Checks if there is an appropriate type conversion from the source type to the target type. + </summary> + <param name="sourceType">The type to convert from.</param> + <param name="targetType">The type to convert to.</param> + <returns><c>true</c> if there is a conversion from the source type to the target type.</returns> + <remarks> + Checks if there is an appropriate type conversion from the source type to the target type. + <para> + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.ConvertTypeTo(System.Object,System.Type)"> + <summary> + Converts an object to the target type. + </summary> + <param name="sourceInstance">The object to convert to the target type.</param> + <param name="targetType">The type to convert to.</param> + <returns>The converted object.</returns> + <remarks> + <para> + Converts an object to the target type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.InstantiateByClassName(System.String,System.Type,System.Object)"> + <summary> + Instantiates an object given a class name. + </summary> + <param name="className">The fully qualified class name of the object to instantiate.</param> + <param name="superClass">The class to which the new object should belong.</param> + <param name="defaultValue">The object to return in case of non-fulfillment.</param> + <returns> + An instance of the <paramref name="className"/> or <paramref name="defaultValue"/> + if the object could not be instantiated. + </returns> + <remarks> + <para> + Checks that the <paramref name="className"/> is a subclass of + <paramref name="superClass"/>. If that test fails or the object could + not be instantiated, then <paramref name="defaultValue"/> is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.SubstituteVariables(System.String,System.Collections.IDictionary)"> + <summary> + Performs variable substitution in string <paramref name="val"/> from the + values of keys found in <paramref name="props"/>. + </summary> + <param name="value">The string on which variable substitution is performed.</param> + <param name="props">The dictionary to use to lookup variables.</param> + <returns>The result of the substitutions.</returns> + <remarks> + <para> + The variable substitution delimiters are <b>${</b> and <b>}</b>. + </para> + <para> + For example, if props contains <c>key=value</c>, then the call + </para> + <para> + <code lang="C#"> + string s = OptionConverter.SubstituteVariables("Value of key is ${key}."); + </code> + </para> + <para> + will set the variable <c>s</c> to "Value of key is value.". + </para> + <para> + If no value could be found for the specified key, then substitution + defaults to an empty string. + </para> + <para> + For example, if system properties contains no value for the key + "nonExistentKey", then the call + </para> + <para> + <code lang="C#"> + string s = OptionConverter.SubstituteVariables("Value of nonExistentKey is [${nonExistentKey}]"); + </code> + </para> + <para> + will set <s>s</s> to "Value of nonExistentKey is []". + </para> + <para> + An Exception is thrown if <paramref name="value"/> contains a start + delimiter "${" which is not balanced by a stop delimiter "}". + </para> + </remarks> + </member> + <member name="M:log4net.Util.OptionConverter.ParseEnum(System.Type,System.String,System.Boolean)"> + <summary> + Converts the string representation of the name or numeric value of one or + more enumerated constants to an equivalent enumerated object. + </summary> + <param name="enumType">The type to convert to.</param> + <param name="value">The enum string value.</param> + <param name="ignoreCase">If <c>true</c>, ignore case; otherwise, regard case.</param> + <returns>An object of type <paramref name="enumType" /> whose value is represented by <paramref name="value" />.</returns> + </member> + <member name="T:log4net.Util.PatternParser"> + <summary> + Most of the work of the <see cref="T:log4net.Layout.PatternLayout"/> class + is delegated to the PatternParser class. + </summary> + <remarks> + <para> + The <c>PatternParser</c> processes a pattern string and + returns a chain of <see cref="T:log4net.Util.PatternConverter"/> objects. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.PatternParser.#ctor(System.String)"> + <summary> + Constructor + </summary> + <param name="pattern">The pattern to parse.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.PatternParser"/> class + with the specified pattern string. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternParser.Parse"> + <summary> + Parses the pattern into a chain of pattern converters. + </summary> + <returns>The head of a chain of pattern converters.</returns> + <remarks> + <para> + Parses the pattern into a chain of pattern converters. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternParser.BuildCache"> + <summary> + Build the unified cache of converters from the static and instance maps + </summary> + <returns>the list of all the converter names</returns> + <remarks> + <para> + Build the unified cache of converters from the static and instance maps + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternParser.ParseInternal(System.String,System.String[])"> + <summary> + Internal method to parse the specified pattern to find specified matches + </summary> + <param name="pattern">the pattern to parse</param> + <param name="matches">the converter names to match in the pattern</param> + <remarks> + <para> + The matches param must be sorted such that longer strings come before shorter ones. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternParser.ProcessLiteral(System.String)"> + <summary> + Process a parsed literal + </summary> + <param name="text">the literal text</param> + </member> + <member name="M:log4net.Util.PatternParser.ProcessConverter(System.String,System.String,log4net.Util.FormattingInfo)"> + <summary> + Process a parsed converter pattern + </summary> + <param name="converterName">the name of the converter</param> + <param name="option">the optional option for the converter</param> + <param name="formattingInfo">the formatting info for the converter</param> + </member> + <member name="M:log4net.Util.PatternParser.AddConverter(log4net.Util.PatternConverter)"> + <summary> + Resets the internal state of the parser and adds the specified pattern converter + to the chain. + </summary> + <param name="pc">The pattern converter to add.</param> + </member> + <member name="F:log4net.Util.PatternParser.m_head"> + <summary> + The first pattern converter in the chain + </summary> + </member> + <member name="F:log4net.Util.PatternParser.m_tail"> + <summary> + the last pattern converter in the chain + </summary> + </member> + <member name="F:log4net.Util.PatternParser.m_pattern"> + <summary> + The pattern + </summary> + </member> + <member name="F:log4net.Util.PatternParser.m_patternConverters"> + <summary> + Internal map of converter identifiers to converter types + </summary> + <remarks> + <para> + This map overrides the static s_globalRulesRegistry map. + </para> + </remarks> + </member> + <member name="P:log4net.Util.PatternParser.PatternConverters"> + <summary> + Get the converter registry used by this parser + </summary> + <value> + The converter registry used by this parser + </value> + <remarks> + <para> + Get the converter registry used by this parser + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternParser.StringLengthComparer"> + <summary> + Sort strings by length + </summary> + <remarks> + <para> + <see cref="T:System.Collections.IComparer"/> that orders strings by string length. + The longest strings are placed first + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternString"> + <summary> + This class implements a patterned string. + </summary> + <remarks> + <para> + This string has embedded patterns that are resolved and expanded + when the string is formatted. + </para> + <para> + This class functions similarly to the <see cref="T:log4net.Layout.PatternLayout"/> + in that it accepts a pattern and renders it to a string. Unlike the + <see cref="T:log4net.Layout.PatternLayout"/> however the <c>PatternString</c> + does not render the properties of a specific <see cref="T:log4net.Core.LoggingEvent"/> but + of the process in general. + </para> + <para> + The recognized conversion pattern names are: + </para> + <list type="table"> + <listheader> + <term>Conversion Pattern Name</term> + <description>Effect</description> + </listheader> + <item> + <term>appdomain</term> + <description> + <para> + Used to output the friendly name of the current AppDomain. + </para> + </description> + </item> + <item> + <term>date</term> + <description> + <para> + Used to output the date of the logging event in the local time zone. + To output the date in universal time use the <c>%utcdate</c> pattern. + The date conversion + specifier may be followed by a <i>date format specifier</i> enclosed + between braces. For example, <b>%date{HH:mm:ss,fff}</b> or + <b>%date{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is + given then ISO8601 format is + assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>). + </para> + <para> + The date format specifier admits the same syntax as the + time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + <para> + For better results it is recommended to use the log4net date + formatters. These can be specified using one of the strings + "ABSOLUTE", "DATE" and "ISO8601" for specifying + <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>, + <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively + <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example, + <b>%date{ISO8601}</b> or <b>%date{ABSOLUTE}</b>. + </para> + <para> + These dedicated date formatters perform significantly + better than <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + </description> + </item> + <item> + <term>env</term> + <description> + <para> + Used to output the a specific environment variable. The key to + lookup must be specified within braces and directly following the + pattern specifier, e.g. <b>%env{COMPUTERNAME}</b> would include the value + of the <c>COMPUTERNAME</c> environment variable. + </para> + <para> + The <c>env</c> pattern is not supported on the .NET Compact Framework. + </para> + </description> + </item> + <item> + <term>identity</term> + <description> + <para> + Used to output the user name for the currently active user + (Principal.Identity.Name). + </para> + </description> + </item> + <item> + <term>newline</term> + <description> + <para> + Outputs the platform dependent line separator character or + characters. + </para> + <para> + This conversion pattern name offers the same performance as using + non-portable line separator strings such as "\n", or "\r\n". + Thus, it is the preferred way of specifying a line separator. + </para> + </description> + </item> + <item> + <term>processid</term> + <description> + <para> + Used to output the system process ID for the current process. + </para> + </description> + </item> + <item> + <term>property</term> + <description> + <para> + Used to output a specific context property. The key to + lookup must be specified within braces and directly following the + pattern specifier, e.g. <b>%property{user}</b> would include the value + from the property that is keyed by the string 'user'. Each property value + that is to be included in the log must be specified separately. + Properties are stored in logging contexts. By default + the <c>log4net:HostName</c> property is set to the name of machine on + which the event was originally logged. + </para> + <para> + If no key is specified, e.g. <b>%property</b> then all the keys and their + values are printed in a comma separated list. + </para> + <para> + The properties of an event are combined from a number of different + contexts. These are listed below in the order in which they are searched. + </para> + <list type="definition"> + <item> + <term>the thread properties</term> + <description> + The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current + thread. These properties are shared by all events logged on this thread. + </description> + </item> + <item> + <term>the global properties</term> + <description> + The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These + properties are shared by all the threads in the AppDomain. + </description> + </item> + </list> + </description> + </item> + <item> + <term>random</term> + <description> + <para> + Used to output a random string of characters. The string is made up of + uppercase letters and numbers. By default the string is 4 characters long. + The length of the string can be specified within braces directly following the + pattern specifier, e.g. <b>%random{8}</b> would output an 8 character string. + </para> + </description> + </item> + <item> + <term>username</term> + <description> + <para> + Used to output the WindowsIdentity for the currently + active user. + </para> + </description> + </item> + <item> + <term>utcdate</term> + <description> + <para> + Used to output the date of the logging event in universal time. + The date conversion + specifier may be followed by a <i>date format specifier</i> enclosed + between braces. For example, <b>%utcdate{HH:mm:ss,fff}</b> or + <b>%utcdate{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is + given then ISO8601 format is + assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>). + </para> + <para> + The date format specifier admits the same syntax as the + time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + <para> + For better results it is recommended to use the log4net date + formatters. These can be specified using one of the strings + "ABSOLUTE", "DATE" and "ISO8601" for specifying + <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>, + <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively + <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example, + <b>%utcdate{ISO8601}</b> or <b>%utcdate{ABSOLUTE}</b>. + </para> + <para> + These dedicated date formatters perform significantly + better than <see cref="M:System.DateTime.ToString(System.String)"/>. + </para> + </description> + </item> + <item> + <term>%</term> + <description> + <para> + The sequence %% outputs a single percent sign. + </para> + </description> + </item> + </list> + <para> + Additional pattern converters may be registered with a specific <see cref="T:log4net.Util.PatternString"/> + instance using <see cref="M:log4net.Util.PatternString.AddConverter(log4net.Util.PatternString.ConverterInfo)"/> or + <see cref="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"/>. + </para> + <para> + See the <see cref="T:log4net.Layout.PatternLayout"/> for details on the + <i>format modifiers</i> supported by the patterns. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.PatternString.s_globalRulesRegistry"> + <summary> + Internal map of converter identifiers to converter types. + </summary> + </member> + <member name="F:log4net.Util.PatternString.m_pattern"> + <summary> + the pattern + </summary> + </member> + <member name="F:log4net.Util.PatternString.m_head"> + <summary> + the head of the pattern converter chain + </summary> + </member> + <member name="F:log4net.Util.PatternString.m_instanceRulesRegistry"> + <summary> + patterns defined on this PatternString only + </summary> + </member> + <member name="M:log4net.Util.PatternString.#cctor"> + <summary> + Initialize the global registry + </summary> + </member> + <member name="M:log4net.Util.PatternString.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Initialize a new instance of <see cref="T:log4net.Util.PatternString"/> + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.#ctor(System.String)"> + <summary> + Constructs a PatternString + </summary> + <param name="pattern">The pattern to use with this PatternString</param> + <remarks> + <para> + Initialize a new instance of <see cref="T:log4net.Util.PatternString"/> with the pattern specified. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.ActivateOptions"> + <summary> + Initialize object options + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Util.PatternString.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Util.PatternString.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="M:log4net.Util.PatternString.ActivateOptions"/> must be called again. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.CreatePatternParser(System.String)"> + <summary> + Create the <see cref="T:log4net.Util.PatternParser"/> used to parse the pattern + </summary> + <param name="pattern">the pattern to parse</param> + <returns>The <see cref="T:log4net.Util.PatternParser"/></returns> + <remarks> + <para> + Returns PatternParser used to parse the conversion string. Subclasses + may override this to return a subclass of PatternParser which recognize + custom conversion pattern name. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.Format(System.IO.TextWriter)"> + <summary> + Produces a formatted string as specified by the conversion pattern. + </summary> + <param name="writer">The TextWriter to write the formatted event to</param> + <remarks> + <para> + Format the pattern to the <paramref name="writer"/>. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.Format"> + <summary> + Format the pattern as a string + </summary> + <returns>the pattern formatted as a string</returns> + <remarks> + <para> + Format the pattern to a string. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.AddConverter(log4net.Util.PatternString.ConverterInfo)"> + <summary> + Add a converter to this PatternString + </summary> + <param name="converterInfo">the converter info</param> + <remarks> + <para> + This version of the method is used by the configurator. + Programmatic users should use the alternative <see cref="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"/> method. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"> + <summary> + Add a converter to this PatternString + </summary> + <param name="name">the name of the conversion pattern for this converter</param> + <param name="type">the type of the converter</param> + <remarks> + <para> + Add a converter to this PatternString + </para> + </remarks> + </member> + <member name="P:log4net.Util.PatternString.ConversionPattern"> + <summary> + Gets or sets the pattern formatting string + </summary> + <value> + The pattern formatting string + </value> + <remarks> + <para> + The <b>ConversionPattern</b> option. This is the string which + controls formatting and consists of a mix of literal content and + conversion specifiers. + </para> + </remarks> + </member> + <member name="T:log4net.Util.PatternString.ConverterInfo"> + <summary> + Wrapper class used to map converter names to converter types + </summary> + <remarks> + <para> + Wrapper class used to map converter names to converter types + </para> + </remarks> + </member> + <member name="M:log4net.Util.PatternString.ConverterInfo.#ctor"> + <summary> + default constructor + </summary> + </member> + <member name="P:log4net.Util.PatternString.ConverterInfo.Name"> + <summary> + Gets or sets the name of the conversion pattern + </summary> + <value> + The name of the conversion pattern + </value> + <remarks> + <para> + Gets or sets the name of the conversion pattern + </para> + </remarks> + </member> + <member name="P:log4net.Util.PatternString.ConverterInfo.Type"> + <summary> + Gets or sets the type of the converter + </summary> + <value> + The type of the converter + </value> + <remarks> + <para> + Gets or sets the type of the converter + </para> + </remarks> + </member> + <member name="T:log4net.Util.PropertiesDictionary"> + <summary> + String keyed object map. + </summary> + <remarks> + <para> + While this collection is serializable only member + objects that are serializable will + be serialized along with this collection. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="T:log4net.Util.ReadOnlyPropertiesDictionary"> + <summary> + String keyed object map that is read only. + </summary> + <remarks> + <para> + This collection is readonly and cannot be modified. + </para> + <para> + While this collection is serializable only member + objects that are serializable will + be serialized along with this collection. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="F:log4net.Util.ReadOnlyPropertiesDictionary.m_hashtable"> + <summary> + The Hashtable used to store the properties data + </summary> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor(log4net.Util.ReadOnlyPropertiesDictionary)"> + <summary> + Copy Constructor + </summary> + <param name="propertiesDictionary">properties to copy</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Deserialization constructor + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param> + <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class + with serialized data. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.GetKeys"> + <summary> + Gets the key names. + </summary> + <returns>An array of all the keys.</returns> + <remarks> + <para> + Gets the key names. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.Contains(System.String)"> + <summary> + Test if the dictionary contains a specified key + </summary> + <param name="key">the key to look for</param> + <returns>true if the dictionary contains the specified key</returns> + <remarks> + <para> + Test if the dictionary contains a specified key + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided. + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param> + <param name="context">The destination for this serialization.</param> + <remarks> + <para> + Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#GetEnumerator"> + <summary> + See <see cref="M:System.Collections.IDictionary.GetEnumerator"/> + </summary> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Remove(System.Object)"> + <summary> + See <see cref="M:System.Collections.IDictionary.Remove(System.Object)"/> + </summary> + <param name="key"></param> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Contains(System.Object)"> + <summary> + See <see cref="M:System.Collections.IDictionary.Contains(System.Object)"/> + </summary> + <param name="key"></param> + <returns></returns> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.Clear"> + <summary> + Remove all properties from the properties collection + </summary> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Add(System.Object,System.Object)"> + <summary> + See <see cref="M:System.Collections.IDictionary.Add(System.Object,System.Object)"/> + </summary> + <param name="key"></param> + <param name="value"></param> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#CopyTo(System.Array,System.Int32)"> + <summary> + See <see cref="M:System.Collections.ICollection.CopyTo(System.Array,System.Int32)"/> + </summary> + <param name="array"></param> + <param name="index"></param> + </member> + <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IEnumerable#GetEnumerator"> + <summary> + See <see cref="M:System.Collections.IEnumerable.GetEnumerator"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.Item(System.String)"> + <summary> + Gets or sets the value of the property with the specified key. + </summary> + <value> + The value of the property with the specified key. + </value> + <param name="key">The key of the property to get or set.</param> + <remarks> + <para> + The property value will only be serialized if it is serializable. + If it cannot be serialized it will be silently ignored if + a serialization operation is performed. + </para> + </remarks> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.InnerHashtable"> + <summary> + The hashtable used to store the properties + </summary> + <value> + The internal collection used to store the properties + </value> + <remarks> + <para> + The hashtable used to store the properties + </para> + </remarks> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#IsReadOnly"> + <summary> + See <see cref="P:System.Collections.IDictionary.IsReadOnly"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Item(System.Object)"> + <summary> + See <see cref="P:System.Collections.IDictionary.Item(System.Object)"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Values"> + <summary> + See <see cref="P:System.Collections.IDictionary.Values"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Keys"> + <summary> + See <see cref="P:System.Collections.IDictionary.Keys"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#IsFixedSize"> + <summary> + See <see cref="P:System.Collections.IDictionary.IsFixedSize"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#IsSynchronized"> + <summary> + See <see cref="P:System.Collections.ICollection.IsSynchronized"/> + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.Count"> + <summary> + The number of properties in this collection + </summary> + </member> + <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#SyncRoot"> + <summary> + See <see cref="P:System.Collections.ICollection.SyncRoot"/> + </summary> + </member> + <member name="M:log4net.Util.PropertiesDictionary.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.#ctor(log4net.Util.ReadOnlyPropertiesDictionary)"> + <summary> + Constructor + </summary> + <param name="propertiesDictionary">properties to copy</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class + with serialized data. + </summary> + <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param> + <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param> + <remarks> + <para> + Because this class is sealed the serialization constructor is private. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.Remove(System.String)"> + <summary> + Remove the entry with the specified key from this dictionary + </summary> + <param name="key">the key for the entry to remove</param> + <remarks> + <para> + Remove the entry with the specified key from this dictionary + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#GetEnumerator"> + <summary> + See <see cref="M:System.Collections.IDictionary.GetEnumerator"/> + </summary> + <returns>an enumerator</returns> + <remarks> + <para> + Returns a <see cref="T:System.Collections.IDictionaryEnumerator"/> over the contest of this collection. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Remove(System.Object)"> + <summary> + See <see cref="M:System.Collections.IDictionary.Remove(System.Object)"/> + </summary> + <param name="key">the key to remove</param> + <remarks> + <para> + Remove the entry with the specified key from this dictionary + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Contains(System.Object)"> + <summary> + See <see cref="M:System.Collections.IDictionary.Contains(System.Object)"/> + </summary> + <param name="key">the key to lookup in the collection</param> + <returns><c>true</c> if the collection contains the specified key</returns> + <remarks> + <para> + Test if this collection contains a specified key. + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.Clear"> + <summary> + Remove all properties from the properties collection + </summary> + <remarks> + <para> + Remove all properties from the properties collection + </para> + </remarks> + </member> + <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Add(System.Object,System.Object)"> + <summary> + See <see cref="M:System.Collections.IDictionary.Add(System.Object,System.Object)"/> + </summary> + <param name="key">the key</param> + <param name="value">the value to store for the key</param> + <remarks> + <para> + Store a value for the specified <see cref="T:System.String"/> <paramref name="key"/>. + </para> + </remarks> + <exception cref="T:System.ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception> + </member> + <member name="M:log4net.Util.PropertiesDictionary.System#Collections#ICollection#CopyTo(System.Array,System.Int32)"> + <summary> + See <see cref="M:System.Collections.ICollection.CopyTo(System.Array,System.Int32)"/> + </summary> + <param name="array"></param> + <param name="index"></param> + </member> + <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IEnumerable#GetEnumerator"> + <summary> + See <see cref="M:System.Collections.IEnumerable.GetEnumerator"/> + </summary> + </member> + <member name="P:log4net.Util.PropertiesDictionary.Item(System.String)"> + <summary> + Gets or sets the value of the property with the specified key. + </summary> + <value> + The value of the property with the specified key. + </value> + <param name="key">The key of the property to get or set.</param> + <remarks> + <para> + The property value will only be serialized if it is serializable. + If it cannot be serialized it will be silently ignored if + a serialization operation is performed. + </para> + </remarks> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#IsReadOnly"> + <summary> + See <see cref="P:System.Collections.IDictionary.IsReadOnly"/> + </summary> + <value> + <c>false</c> + </value> + <remarks> + <para> + This collection is modifiable. This property always + returns <c>false</c>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Item(System.Object)"> + <summary> + See <see cref="P:System.Collections.IDictionary.Item(System.Object)"/> + </summary> + <value> + The value for the key specified. + </value> + <remarks> + <para> + Get or set a value for the specified <see cref="T:System.String"/> <paramref name="key"/>. + </para> + </remarks> + <exception cref="T:System.ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Values"> + <summary> + See <see cref="P:System.Collections.IDictionary.Values"/> + </summary> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Keys"> + <summary> + See <see cref="P:System.Collections.IDictionary.Keys"/> + </summary> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#IsFixedSize"> + <summary> + See <see cref="P:System.Collections.IDictionary.IsFixedSize"/> + </summary> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#ICollection#IsSynchronized"> + <summary> + See <see cref="P:System.Collections.ICollection.IsSynchronized"/> + </summary> + </member> + <member name="P:log4net.Util.PropertiesDictionary.System#Collections#ICollection#SyncRoot"> + <summary> + See <see cref="P:System.Collections.ICollection.SyncRoot"/> + </summary> + </member> + <member name="T:log4net.Util.ProtectCloseTextWriter"> + <summary> + A <see cref="T:System.IO.TextWriter"/> that ignores the <see cref="M:log4net.Util.ProtectCloseTextWriter.Close"/> message + </summary> + <remarks> + <para> + This writer is used in special cases where it is necessary + to protect a writer from being closed by a client. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.ProtectCloseTextWriter.#ctor(System.IO.TextWriter)"> + <summary> + Constructor + </summary> + <param name="writer">the writer to actually write to</param> + <remarks> + <para> + Create a new ProtectCloseTextWriter using a writer + </para> + </remarks> + </member> + <member name="M:log4net.Util.ProtectCloseTextWriter.Attach(System.IO.TextWriter)"> + <summary> + Attach this instance to a different underlying <see cref="T:System.IO.TextWriter"/> + </summary> + <param name="writer">the writer to attach to</param> + <remarks> + <para> + Attach this instance to a different underlying <see cref="T:System.IO.TextWriter"/> + </para> + </remarks> + </member> + <member name="M:log4net.Util.ProtectCloseTextWriter.Close"> + <summary> + Does not close the underlying output writer. + </summary> + <remarks> + <para> + Does not close the underlying output writer. + This method does nothing. + </para> + </remarks> + </member> + <member name="T:log4net.Util.ReaderWriterLock"> + <summary> + Defines a lock that supports single writers and multiple readers + </summary> + <remarks> + <para> + <c>ReaderWriterLock</c> is used to synchronize access to a resource. + At any given time, it allows either concurrent read access for + multiple threads, or write access for a single thread. In a + situation where a resource is changed infrequently, a + <c>ReaderWriterLock</c> provides better throughput than a simple + one-at-a-time lock, such as <see cref="T:System.Threading.Monitor"/>. + </para> + <para> + If a platform does not support a <c>System.Threading.ReaderWriterLock</c> + implementation then all readers and writers are serialized. Therefore + the caller must not rely on multiple simultaneous readers. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.ReaderWriterLock.#ctor"> + <summary> + Constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ReaderWriterLock"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReaderWriterLock.AcquireReaderLock"> + <summary> + Acquires a reader lock + </summary> + <remarks> + <para> + <see cref="M:log4net.Util.ReaderWriterLock.AcquireReaderLock"/> blocks if a different thread has the writer + lock, or if at least one thread is waiting for the writer lock. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReaderWriterLock.ReleaseReaderLock"> + <summary> + Decrements the lock count + </summary> + <remarks> + <para> + <see cref="M:log4net.Util.ReaderWriterLock.ReleaseReaderLock"/> decrements the lock count. When the count + reaches zero, the lock is released. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReaderWriterLock.AcquireWriterLock"> + <summary> + Acquires the writer lock + </summary> + <remarks> + <para> + This method blocks if another thread has a reader lock or writer lock. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReaderWriterLock.ReleaseWriterLock"> + <summary> + Decrements the lock count on the writer lock + </summary> + <remarks> + <para> + ReleaseWriterLock decrements the writer lock count. + When the count reaches zero, the writer lock is released. + </para> + </remarks> + </member> + <member name="T:log4net.Util.ReusableStringWriter"> + <summary> + A <see cref="T:System.IO.StringWriter"/> that can be <see cref="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"/> and reused + </summary> + <remarks> + <para> + A <see cref="T:System.IO.StringWriter"/> that can be <see cref="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"/> and reused. + This uses a single buffer for string operations. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.ReusableStringWriter.#ctor(System.IFormatProvider)"> + <summary> + Create an instance of <see cref="T:log4net.Util.ReusableStringWriter"/> + </summary> + <param name="formatProvider">the format provider to use</param> + <remarks> + <para> + Create an instance of <see cref="T:log4net.Util.ReusableStringWriter"/> + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReusableStringWriter.Dispose(System.Boolean)"> + <summary> + Override Dispose to prevent closing of writer + </summary> + <param name="disposing">flag</param> + <remarks> + <para> + Override Dispose to prevent closing of writer + </para> + </remarks> + </member> + <member name="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"> + <summary> + Reset this string writer so that it can be reused. + </summary> + <param name="maxCapacity">the maximum buffer capacity before it is trimmed</param> + <param name="defaultSize">the default size to make the buffer</param> + <remarks> + <para> + Reset this string writer so that it can be reused. + The internal buffers are cleared and reset. + </para> + </remarks> + </member> + <member name="T:log4net.Util.SystemInfo"> + <summary> + Utility class for system specific information. + </summary> + <remarks> + <para> + Utility class of static methods for system specific information. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + <author>Alexey Solofnenko</author> + </member> + <member name="M:log4net.Util.SystemInfo.#ctor"> + <summary> + Private constructor to prevent instances. + </summary> + <remarks> + <para> + Only static methods are exposed from this type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.#cctor"> + <summary> + Initialize default values for private static fields. + </summary> + <remarks> + <para> + Only static methods are exposed from this type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.AssemblyLocationInfo(System.Reflection.Assembly)"> + <summary> + Gets the assembly location path for the specified assembly. + </summary> + <param name="myAssembly">The assembly to get the location for.</param> + <returns>The location of the assembly.</returns> + <remarks> + <para> + This method does not guarantee to return the correct path + to the assembly. If only tries to give an indication as to + where the assembly was loaded from. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.AssemblyQualifiedName(System.Type)"> + <summary> + Gets the fully qualified name of the <see cref="T:System.Type"/>, including + the name of the assembly from which the <see cref="T:System.Type"/> was + loaded. + </summary> + <param name="type">The <see cref="T:System.Type"/> to get the fully qualified name for.</param> + <returns>The fully qualified name for the <see cref="T:System.Type"/>.</returns> + <remarks> + <para> + This is equivalent to the <c>Type.AssemblyQualifiedName</c> property, + but this method works on the .NET Compact Framework 1.0 as well as + the full .NET runtime. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.AssemblyShortName(System.Reflection.Assembly)"> + <summary> + Gets the short name of the <see cref="T:System.Reflection.Assembly"/>. + </summary> + <param name="myAssembly">The <see cref="T:System.Reflection.Assembly"/> to get the name for.</param> + <returns>The short name of the <see cref="T:System.Reflection.Assembly"/>.</returns> + <remarks> + <para> + The short name of the assembly is the <see cref="P:System.Reflection.Assembly.FullName"/> + without the version, culture, or public key. i.e. it is just the + assembly's file name without the extension. + </para> + <para> + Use this rather than <c>Assembly.GetName().Name</c> because that + is not available on the Compact Framework. + </para> + <para> + Because of a FileIOPermission security demand we cannot do + the obvious Assembly.GetName().Name. We are allowed to get + the <see cref="P:System.Reflection.Assembly.FullName"/> of the assembly so we + start from there and strip out just the assembly name. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.AssemblyFileName(System.Reflection.Assembly)"> + <summary> + Gets the file name portion of the <see cref="T:System.Reflection.Assembly"/>, including the extension. + </summary> + <param name="myAssembly">The <see cref="T:System.Reflection.Assembly"/> to get the file name for.</param> + <returns>The file name of the assembly.</returns> + <remarks> + <para> + Gets the file name portion of the <see cref="T:System.Reflection.Assembly"/>, including the extension. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.Type,System.String,System.Boolean,System.Boolean)"> + <summary> + Loads the type specified in the type string. + </summary> + <param name="relativeType">A sibling type to use to load the type.</param> + <param name="typeName">The name of the type to load.</param> + <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param> + <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param> + <returns>The type loaded or <c>null</c> if it could not be loaded.</returns> + <remarks> + <para> + If the type name is fully qualified, i.e. if contains an assembly name in + the type name, the type will be loaded from the system using + <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>. + </para> + <para> + If the type name is not fully qualified, it will be loaded from the assembly + containing the specified relative type. If the type is not found in the assembly + then all the loaded assemblies will be searched for the type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.String,System.Boolean,System.Boolean)"> + <summary> + Loads the type specified in the type string. + </summary> + <param name="typeName">The name of the type to load.</param> + <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param> + <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param> + <returns>The type loaded or <c>null</c> if it could not be loaded.</returns> + <remarks> + <para> + If the type name is fully qualified, i.e. if contains an assembly name in + the type name, the type will be loaded from the system using + <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>. + </para> + <para> + If the type name is not fully qualified it will be loaded from the + assembly that is directly calling this method. If the type is not found + in the assembly then all the loaded assemblies will be searched for the type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.Reflection.Assembly,System.String,System.Boolean,System.Boolean)"> + <summary> + Loads the type specified in the type string. + </summary> + <param name="relativeAssembly">An assembly to load the type from.</param> + <param name="typeName">The name of the type to load.</param> + <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param> + <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param> + <returns>The type loaded or <c>null</c> if it could not be loaded.</returns> + <remarks> + <para> + If the type name is fully qualified, i.e. if contains an assembly name in + the type name, the type will be loaded from the system using + <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>. + </para> + <para> + If the type name is not fully qualified it will be loaded from the specified + assembly. If the type is not found in the assembly then all the loaded assemblies + will be searched for the type. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.NewGuid"> + <summary> + Generate a new guid + </summary> + <returns>A new Guid</returns> + <remarks> + <para> + Generate a new guid + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.CreateArgumentOutOfRangeException(System.String,System.Object,System.String)"> + <summary> + Create an <see cref="T:System.ArgumentOutOfRangeException"/> + </summary> + <param name="parameterName">The name of the parameter that caused the exception</param> + <param name="actualValue">The value of the argument that causes this exception</param> + <param name="message">The message that describes the error</param> + <returns>the ArgumentOutOfRangeException object</returns> + <remarks> + <para> + Create a new instance of the <see cref="T:System.ArgumentOutOfRangeException"/> class + with a specified error message, the parameter name, and the value + of the argument. + </para> + <para> + The Compact Framework does not support the 3 parameter constructor for the + <see cref="T:System.ArgumentOutOfRangeException"/> type. This method provides an + implementation that works for all platforms. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.TryParse(System.String,System.Int32@)"> + <summary> + Parse a string into an <see cref="T:System.Int32"/> value + </summary> + <param name="s">the string to parse</param> + <param name="val">out param where the parsed value is placed</param> + <returns><c>true</c> if the string was able to be parsed into an integer</returns> + <remarks> + <para> + Attempts to parse the string into an integer. If the string cannot + be parsed then this method returns <c>false</c>. The method does not throw an exception. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.TryParse(System.String,System.Int64@)"> + <summary> + Parse a string into an <see cref="T:System.Int64"/> value + </summary> + <param name="s">the string to parse</param> + <param name="val">out param where the parsed value is placed</param> + <returns><c>true</c> if the string was able to be parsed into an integer</returns> + <remarks> + <para> + Attempts to parse the string into an integer. If the string cannot + be parsed then this method returns <c>false</c>. The method does not throw an exception. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.GetAppSetting(System.String)"> + <summary> + Lookup an application setting + </summary> + <param name="key">the application settings key to lookup</param> + <returns>the value for the key, or <c>null</c></returns> + <remarks> + <para> + Configuration APIs are not supported under the Compact Framework + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.ConvertToFullPath(System.String)"> + <summary> + Convert a path into a fully qualified local file path. + </summary> + <param name="path">The path to convert.</param> + <returns>The fully qualified path.</returns> + <remarks> + <para> + Converts the path specified to a fully + qualified path. If the path is relative it is + taken as relative from the application base + directory. + </para> + <para> + The path specified must be a local file path, a URI is not supported. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemInfo.CreateCaseInsensitiveHashtable"> + <summary> + Creates a new case-insensitive instance of the <see cref="T:System.Collections.Hashtable"/> class with the default initial capacity. + </summary> + <returns>A new case-insensitive instance of the <see cref="T:System.Collections.Hashtable"/> class with the default initial capacity</returns> + <remarks> + <para> + The new Hashtable instance uses the default load factor, the CaseInsensitiveHashCodeProvider, and the CaseInsensitiveComparer. + </para> + </remarks> + </member> + <member name="F:log4net.Util.SystemInfo.EmptyTypes"> + <summary> + Gets an empty array of types. + </summary> + <remarks> + <para> + The <c>Type.EmptyTypes</c> field is not available on + the .NET Compact Framework 1.0. + </para> + </remarks> + </member> + <member name="F:log4net.Util.SystemInfo.s_hostName"> + <summary> + Cache the host name for the current machine + </summary> + </member> + <member name="F:log4net.Util.SystemInfo.s_appFriendlyName"> + <summary> + Cache the application friendly name + </summary> + </member> + <member name="F:log4net.Util.SystemInfo.s_nullText"> + <summary> + Text to output when a <c>null</c> is encountered. + </summary> + </member> + <member name="F:log4net.Util.SystemInfo.s_notAvailableText"> + <summary> + Text to output when an unsupported feature is requested. + </summary> + </member> + <member name="F:log4net.Util.SystemInfo.s_processStartTime"> + <summary> + Start time for the current process. + </summary> + </member> + <member name="P:log4net.Util.SystemInfo.NewLine"> + <summary> + Gets the system dependent line terminator. + </summary> + <value> + The system dependent line terminator. + </value> + <remarks> + <para> + Gets the system dependent line terminator. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.ApplicationBaseDirectory"> + <summary> + Gets the base directory for this <see cref="T:System.AppDomain"/>. + </summary> + <value>The base directory path for the current <see cref="T:System.AppDomain"/>.</value> + <remarks> + <para> + Gets the base directory for this <see cref="T:System.AppDomain"/>. + </para> + <para> + The value returned may be either a local file path or a URI. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.ConfigurationFileLocation"> + <summary> + Gets the path to the configuration file for the current <see cref="T:System.AppDomain"/>. + </summary> + <value>The path to the configuration file for the current <see cref="T:System.AppDomain"/>.</value> + <remarks> + <para> + The .NET Compact Framework 1.0 does not have a concept of a configuration + file. For this runtime, we use the entry assembly location as the root for + the configuration file name. + </para> + <para> + The value returned may be either a local file path or a URI. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.EntryAssemblyLocation"> + <summary> + Gets the path to the file that first executed in the current <see cref="T:System.AppDomain"/>. + </summary> + <value>The path to the entry assembly.</value> + <remarks> + <para> + Gets the path to the file that first executed in the current <see cref="T:System.AppDomain"/>. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.CurrentThreadId"> + <summary> + Gets the ID of the current thread. + </summary> + <value>The ID of the current thread.</value> + <remarks> + <para> + On the .NET framework, the <c>AppDomain.GetCurrentThreadId</c> method + is used to obtain the thread ID for the current thread. This is the + operating system ID for the thread. + </para> + <para> + On the .NET Compact Framework 1.0 it is not possible to get the + operating system thread ID for the current thread. The native method + <c>GetCurrentThreadId</c> is implemented inline in a header file + and cannot be called. + </para> + <para> + On the .NET Framework 2.0 the <c>Thread.ManagedThreadId</c> is used as this + gives a stable id unrelated to the operating system thread ID which may + change if the runtime is using fibers. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.HostName"> + <summary> + Get the host name or machine name for the current machine + </summary> + <value> + The hostname or machine name + </value> + <remarks> + <para> + Get the host name or machine name for the current machine + </para> + <para> + The host name (<see cref="M:System.Net.Dns.GetHostName"/>) or + the machine name (<c>Environment.MachineName</c>) for + the current machine, or if neither of these are available + then <c>NOT AVAILABLE</c> is returned. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.ApplicationFriendlyName"> + <summary> + Get this application's friendly name + </summary> + <value> + The friendly name of this application as a string + </value> + <remarks> + <para> + If available the name of the application is retrieved from + the <c>AppDomain</c> using <c>AppDomain.CurrentDomain.FriendlyName</c>. + </para> + <para> + Otherwise the file name of the entry assembly is used. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.ProcessStartTime"> + <summary> + Get the start time for the current process. + </summary> + <remarks> + <para> + This is the time at which the log4net library was loaded into the + AppDomain. Due to reports of a hang in the call to <c>System.Diagnostics.Process.StartTime</c> + this is not the start time for the current process. + </para> + <para> + The log4net library should be loaded by an application early during its + startup, therefore this start time should be a good approximation for + the actual start time. + </para> + <para> + Note that AppDomains may be loaded and unloaded within the + same process without the process terminating, however this start time + will be set per AppDomain. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.NullText"> + <summary> + Text to output when a <c>null</c> is encountered. + </summary> + <remarks> + <para> + Use this value to indicate a <c>null</c> has been encountered while + outputting a string representation of an item. + </para> + <para> + The default value is <c>(null)</c>. This value can be overridden by specifying + a value for the <c>log4net.NullText</c> appSetting in the application's + .config file. + </para> + </remarks> + </member> + <member name="P:log4net.Util.SystemInfo.NotAvailableText"> + <summary> + Text to output when an unsupported feature is requested. + </summary> + <remarks> + <para> + Use this value when an unsupported feature is requested. + </para> + <para> + The default value is <c>NOT AVAILABLE</c>. This value can be overridden by specifying + a value for the <c>log4net.NotAvailableText</c> appSetting in the application's + .config file. + </para> + </remarks> + </member> + <member name="T:log4net.Util.SystemStringFormat"> + <summary> + Utility class that represents a format string. + </summary> + <remarks> + <para> + Utility class that represents a format string. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.SystemStringFormat.#ctor(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Initialise the <see cref="T:log4net.Util.SystemStringFormat"/> + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param> + <param name="format">A <see cref="T:System.String"/> containing zero or more format items.</param> + <param name="args">An <see cref="T:System.Object"/> array containing zero or more objects to format.</param> + </member> + <member name="M:log4net.Util.SystemStringFormat.ToString"> + <summary> + Format the string and arguments + </summary> + <returns>the formatted string</returns> + </member> + <member name="M:log4net.Util.SystemStringFormat.StringFormat(System.IFormatProvider,System.String,System.Object[])"> + <summary> + Replaces the format item in a specified <see cref="T:System.String"/> with the text equivalent + of the value of a corresponding <see cref="T:System.Object"/> instance in a specified array. + A specified parameter supplies culture-specific formatting information. + </summary> + <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param> + <param name="format">A <see cref="T:System.String"/> containing zero or more format items.</param> + <param name="args">An <see cref="T:System.Object"/> array containing zero or more objects to format.</param> + <returns> + A copy of format in which the format items have been replaced by the <see cref="T:System.String"/> + equivalent of the corresponding instances of <see cref="T:System.Object"/> in args. + </returns> + <remarks> + <para> + This method does not throw exceptions. If an exception thrown while formatting the result the + exception and arguments are returned in the result string. + </para> + </remarks> + </member> + <member name="M:log4net.Util.SystemStringFormat.StringFormatError(System.Exception,System.String,System.Object[])"> + <summary> + Process an error during StringFormat + </summary> + </member> + <member name="M:log4net.Util.SystemStringFormat.RenderArray(System.Array,System.Text.StringBuilder)"> + <summary> + Dump the contents of an array into a string builder + </summary> + </member> + <member name="M:log4net.Util.SystemStringFormat.RenderObject(System.Object,System.Text.StringBuilder)"> + <summary> + Dump an object to a string + </summary> + </member> + <member name="T:log4net.Util.ThreadContextProperties"> + <summary> + Implementation of Properties collection for the <see cref="T:log4net.ThreadContext"/> + </summary> + <remarks> + <para> + Class implements a collection of properties that is specific to each thread. + The class is not synchronized as each thread has its own <see cref="T:log4net.Util.PropertiesDictionary"/>. + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.ThreadContextProperties.s_threadLocalSlot"> + <summary> + The thread local data slot to use to store a PropertiesDictionary. + </summary> + </member> + <member name="M:log4net.Util.ThreadContextProperties.#ctor"> + <summary> + Internal constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextProperties"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextProperties.Remove(System.String)"> + <summary> + Remove a property + </summary> + <param name="key">the key for the entry to remove</param> + <remarks> + <para> + Remove a property + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextProperties.Clear"> + <summary> + Clear all properties + </summary> + <remarks> + <para> + Clear all properties + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextProperties.GetProperties(System.Boolean)"> + <summary> + Get the <c>PropertiesDictionary</c> for this thread. + </summary> + <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param> + <returns>the properties for this thread</returns> + <remarks> + <para> + The collection returned is only to be used on the calling thread. If the + caller needs to share the collection between different threads then the + caller must clone the collection before doing so. + </para> + </remarks> + </member> + <member name="P:log4net.Util.ThreadContextProperties.Item(System.String)"> + <summary> + Gets or sets the value of a property + </summary> + <value> + The value for the property with the specified key + </value> + <remarks> + <para> + Gets or sets the value of a property + </para> + </remarks> + </member> + <member name="T:log4net.Util.ThreadContextStack"> + <summary> + Implementation of Stack for the <see cref="T:log4net.ThreadContext"/> + </summary> + <remarks> + <para> + Implementation of Stack for the <see cref="T:log4net.ThreadContext"/> + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="F:log4net.Util.ThreadContextStack.m_stack"> + <summary> + The stack store. + </summary> + </member> + <member name="M:log4net.Util.ThreadContextStack.#ctor"> + <summary> + Internal constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack"/> class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextStack.Clear"> + <summary> + Clears all the contextual information held in this stack. + </summary> + <remarks> + <para> + Clears all the contextual information held in this stack. + Only call this if you think that this tread is being reused after + a previous call execution which may not have completed correctly. + You do not need to use this method if you always guarantee to call + the <see cref="M:System.IDisposable.Dispose"/> method of the <see cref="T:System.IDisposable"/> + returned from <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> even in exceptional circumstances, + for example by using the <c>using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message"))</c> + syntax. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextStack.Pop"> + <summary> + Removes the top context from this stack. + </summary> + <returns>The message in the context that was removed from the top of this stack.</returns> + <remarks> + <para> + Remove the top context from this stack, and return + it to the caller. If this stack is empty then an + empty string (not <see langword="null"/>) is returned. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextStack.Push(System.String)"> + <summary> + Pushes a new context message into this stack. + </summary> + <param name="message">The new context message.</param> + <returns> + An <see cref="T:System.IDisposable"/> that can be used to clean up the context stack. + </returns> + <remarks> + <para> + Pushes a new context onto this stack. An <see cref="T:System.IDisposable"/> + is returned that can be used to clean up this stack. This + can be easily combined with the <c>using</c> keyword to scope the + context. + </para> + </remarks> + <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword. + <code lang="C#"> + using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message")) + { + log.Warn("This should have an ThreadContext Stack message"); + } + </code> + </example> + </member> + <member name="M:log4net.Util.ThreadContextStack.GetFullMessage"> + <summary> + Gets the current context information for this stack. + </summary> + <returns>The current context information.</returns> + </member> + <member name="M:log4net.Util.ThreadContextStack.ToString"> + <summary> + Gets the current context information for this stack. + </summary> + <returns>Gets the current context information</returns> + <remarks> + <para> + Gets the current context information for this stack. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextStack.log4net#Core#IFixingRequired#GetFixedObject"> + <summary> + Get a portable version of this object + </summary> + <returns>the portable instance of this object</returns> + <remarks> + <para> + Get a cross thread portable version of this object + </para> + </remarks> + </member> + <member name="P:log4net.Util.ThreadContextStack.Count"> + <summary> + The number of messages in the stack + </summary> + <value> + The current number of messages in the stack + </value> + <remarks> + <para> + The current number of messages in the stack. That is + the number of times <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> has been called + minus the number of times <see cref="M:log4net.Util.ThreadContextStack.Pop"/> has been called. + </para> + </remarks> + </member> + <member name="P:log4net.Util.ThreadContextStack.InternalStack"> + <summary> + Gets and sets the internal stack used by this <see cref="T:log4net.Util.ThreadContextStack"/> + </summary> + <value>The internal storage stack</value> + <remarks> + <para> + This property is provided only to support backward compatability + of the <see cref="T:log4net.NDC"/>. Tytpically the internal stack should not + be modified. + </para> + </remarks> + </member> + <member name="T:log4net.Util.ThreadContextStack.StackFrame"> + <summary> + Inner class used to represent a single context frame in the stack. + </summary> + <remarks> + <para> + Inner class used to represent a single context frame in the stack. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextStack.StackFrame.#ctor(System.String,log4net.Util.ThreadContextStack.StackFrame)"> + <summary> + Constructor + </summary> + <param name="message">The message for this context.</param> + <param name="parent">The parent context in the chain.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack.StackFrame"/> class + with the specified message and parent context. + </para> + </remarks> + </member> + <member name="P:log4net.Util.ThreadContextStack.StackFrame.Message"> + <summary> + Get the message. + </summary> + <value>The message.</value> + <remarks> + <para> + Get the message. + </para> + </remarks> + </member> + <member name="P:log4net.Util.ThreadContextStack.StackFrame.FullMessage"> + <summary> + Gets the full text of the context down to the root level. + </summary> + <value> + The full text of the context down to the root level. + </value> + <remarks> + <para> + Gets the full text of the context down to the root level. + </para> + </remarks> + </member> + <member name="T:log4net.Util.ThreadContextStack.AutoPopStackFrame"> + <summary> + Struct returned from the <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> method. + </summary> + <remarks> + <para> + This struct implements the <see cref="T:System.IDisposable"/> and is designed to be used + with the <see langword="using"/> pattern to remove the stack frame at the end of the scope. + </para> + </remarks> + </member> + <member name="F:log4net.Util.ThreadContextStack.AutoPopStackFrame.m_frameStack"> + <summary> + The ThreadContextStack internal stack + </summary> + </member> + <member name="F:log4net.Util.ThreadContextStack.AutoPopStackFrame.m_frameDepth"> + <summary> + The depth to trim the stack to when this instance is disposed + </summary> + </member> + <member name="M:log4net.Util.ThreadContextStack.AutoPopStackFrame.#ctor(System.Collections.Stack,System.Int32)"> + <summary> + Constructor + </summary> + <param name="frameStack">The internal stack used by the ThreadContextStack.</param> + <param name="frameDepth">The depth to return the stack to when this object is disposed.</param> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack.AutoPopStackFrame"/> class with + the specified stack and return depth. + </para> + </remarks> + </member> + <member name="M:log4net.Util.ThreadContextStack.AutoPopStackFrame.Dispose"> + <summary> + Returns the stack to the correct depth. + </summary> + <remarks> + <para> + Returns the stack to the correct depth. + </para> + </remarks> + </member> + <member name="T:log4net.Util.ThreadContextStacks"> + <summary> + Implementation of Stacks collection for the <see cref="T:log4net.ThreadContext"/> + </summary> + <remarks> + <para> + Implementation of Stacks collection for the <see cref="T:log4net.ThreadContext"/> + </para> + </remarks> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.Util.ThreadContextStacks.#ctor(log4net.Util.ContextPropertiesBase)"> + <summary> + Internal constructor + </summary> + <remarks> + <para> + Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStacks"/> class. + </para> + </remarks> + </member> + <member name="P:log4net.Util.ThreadContextStacks.Item(System.String)"> + <summary> + Gets the named thread context stack + </summary> + <value> + The named stack + </value> + <remarks> + <para> + Gets the named thread context stack + </para> + </remarks> + </member> + <member name="T:log4net.Util.Transform"> + <summary> + Utility class for transforming strings. + </summary> + <remarks> + <para> + Utility class for transforming strings. + </para> + </remarks> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.Util.Transform.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.Util.Transform"/> class. + </summary> + <remarks> + <para> + Uses a private access modifier to prevent instantiation of this class. + </para> + </remarks> + </member> + <member name="M:log4net.Util.Transform.WriteEscapedXmlString(System.Xml.XmlWriter,System.String,System.String)"> + <summary> + Write a string to an <see cref="T:System.Xml.XmlWriter"/> + </summary> + <param name="writer">the writer to write to</param> + <param name="textData">the string to write</param> + <param name="invalidCharReplacement">The string to replace non XML compliant chars with</param> + <remarks> + <para> + The test is escaped either using XML escape entities + or using CDATA sections. + </para> + </remarks> + </member> + <member name="M:log4net.Util.Transform.MaskXmlInvalidCharacters(System.String,System.String)"> + <summary> + Replace invalid XML characters in text string + </summary> + <param name="textData">the XML text input string</param> + <param name="mask">the string to use in place of invalid characters</param> + <returns>A string that does not contain invalid XML characters.</returns> + <remarks> + <para> + Certain Unicode code points are not allowed in the XML InfoSet, for + details see: <a href="http://www.w3.org/TR/REC-xml/#charsets">http://www.w3.org/TR/REC-xml/#charsets</a>. + </para> + <para> + This method replaces any illegal characters in the input string + with the mask string specified. + </para> + </remarks> + </member> + <member name="M:log4net.Util.Transform.CountSubstrings(System.String,System.String)"> + <summary> + Count the number of times that the substring occurs in the text + </summary> + <param name="text">the text to search</param> + <param name="substring">the substring to find</param> + <returns>the number of times the substring occurs in the text</returns> + <remarks> + <para> + The substring is assumed to be non repeating within itself. + </para> + </remarks> + </member> + <member name="T:log4net.Util.WindowsSecurityContext"> + <summary> + Impersonate a Windows Account + </summary> + <remarks> + <para> + This <see cref="T:log4net.Core.SecurityContext"/> impersonates a Windows account. + </para> + <para> + How the impersonation is done depends on the value of <see cref="M:log4net.Util.WindowsSecurityContext.Impersonate(System.Object)"/>. + This allows the context to either impersonate a set of user credentials specified + using username, domain name and password or to revert to the process credentials. + </para> + </remarks> + </member> + <member name="M:log4net.Util.WindowsSecurityContext.#ctor"> + <summary> + Default constructor + </summary> + <remarks> + <para> + Default constructor + </para> + </remarks> + </member> + <member name="M:log4net.Util.WindowsSecurityContext.ActivateOptions"> + <summary> + Initialize the SecurityContext based on the options set. + </summary> + <remarks> + <para> + This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object + activation scheme. The <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> method must + be called on this object after the configuration properties have + been set. Until <see cref="M:log4net.Util.WindowsSecurityContext.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="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> must be called again. + </para> + <para> + The security context will try to Logon the specified user account and + capture a primary token for impersonation. + </para> + </remarks> + <exception cref="T:System.ArgumentNullException">The required <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/>, + <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> or <see cref="P:log4net.Util.WindowsSecurityContext.Password"/> properties were not specified.</exception> + </member> + <member name="M:log4net.Util.WindowsSecurityContext.Impersonate(System.Object)"> + <summary> + Impersonate the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties. + </summary> + <param name="state">caller provided state</param> + <returns> + An <see cref="T:System.IDisposable"/> instance that will revoke the impersonation of this SecurityContext + </returns> + <remarks> + <para> + Depending on the <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> property either + impersonate a user using credentials supplied or revert + to the process credentials. + </para> + </remarks> + </member> + <member name="M:log4net.Util.WindowsSecurityContext.LogonUser(System.String,System.String,System.String)"> + <summary> + Create a <see cref="T:System.Security.Principal.WindowsIdentity"/> given the userName, domainName and password. + </summary> + <param name="userName">the user name</param> + <param name="domainName">the domain name</param> + <param name="password">the password</param> + <returns>the <see cref="T:System.Security.Principal.WindowsIdentity"/> for the account specified</returns> + <remarks> + <para> + Uses the Windows API call LogonUser to get a principal token for the account. This + token is used to initialize the WindowsIdentity. + </para> + </remarks> + </member> + <member name="P:log4net.Util.WindowsSecurityContext.Credentials"> + <summary> + Gets or sets the impersonation mode for this security context + </summary> + <value> + The impersonation mode for this security context + </value> + <remarks> + <para> + Impersonate either a user with user credentials or + revert this thread to the credentials of the process. + The value is one of the <see cref="T:log4net.Util.WindowsSecurityContext.ImpersonationMode"/> + enum. + </para> + <para> + The default value is <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> + </para> + <para> + When the mode is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> + the user's credentials are established using the + <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/>, <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.Password"/> + values. + </para> + <para> + When the mode is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.Process"/> + no other properties need to be set. If the calling thread is + impersonating then it will be reverted back to the process credentials. + </para> + </remarks> + </member> + <member name="P:log4net.Util.WindowsSecurityContext.UserName"> + <summary> + Gets or sets the Windows username for this security context + </summary> + <value> + The Windows username for this security context + </value> + <remarks> + <para> + This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> + is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting). + </para> + </remarks> + </member> + <member name="P:log4net.Util.WindowsSecurityContext.DomainName"> + <summary> + Gets or sets the Windows domain name for this security context + </summary> + <value> + The Windows domain name for this security context + </value> + <remarks> + <para> + The default value for <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> is the local machine name + taken from the <see cref="P:System.Environment.MachineName"/> property. + </para> + <para> + This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> + is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting). + </para> + </remarks> + </member> + <member name="P:log4net.Util.WindowsSecurityContext.Password"> + <summary> + Sets the password for the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties. + </summary> + <value> + The password for the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties. + </value> + <remarks> + <para> + This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> + is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting). + </para> + </remarks> + </member> + <member name="T:log4net.Util.WindowsSecurityContext.ImpersonationMode"> + <summary> + The impersonation modes for the <see cref="T:log4net.Util.WindowsSecurityContext"/> + </summary> + <remarks> + <para> + See the <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> property for + details. + </para> + </remarks> + </member> + <member name="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"> + <summary> + Impersonate a user using the credentials supplied + </summary> + </member> + <member name="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.Process"> + <summary> + Revert this the thread to the credentials of the process + </summary> + </member> + <member name="T:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext"> + <summary> + Adds <see cref="T:System.IDisposable"/> to <see cref="T:System.Security.Principal.WindowsImpersonationContext"/> + </summary> + <remarks> + <para> + Helper class to expose the <see cref="T:System.Security.Principal.WindowsImpersonationContext"/> + through the <see cref="T:System.IDisposable"/> interface. + </para> + </remarks> + </member> + <member name="M:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext.#ctor(System.Security.Principal.WindowsImpersonationContext)"> + <summary> + Constructor + </summary> + <param name="impersonationContext">the impersonation context being wrapped</param> + <remarks> + <para> + Constructor + </para> + </remarks> + </member> + <member name="M:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext.Dispose"> + <summary> + Revert the impersonation + </summary> + <remarks> + <para> + Revert the impersonation + </para> + </remarks> + </member> + <member name="T:log4net.GlobalContext"> + <summary> + The log4net Global Context. + </summary> + <remarks> + <para> + The <c>GlobalContext</c> provides a location for global debugging + information to be stored. + </para> + <para> + The global context has a properties map and these properties can + be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/> + supports selecting and outputing these properties. + </para> + <para> + By default the <c>log4net:HostName</c> property is set to the name of + the current machine. + </para> + </remarks> + <example> + <code lang="C#"> + GlobalContext.Properties["hostname"] = Environment.MachineName; + </code> + </example> + <threadsafety static="true" instance="true"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.GlobalContext.#ctor"> + <summary> + Private Constructor. + </summary> + <remarks> + Uses a private access modifier to prevent instantiation of this class. + </remarks> + </member> + <member name="F:log4net.GlobalContext.s_properties"> + <summary> + The global context properties instance + </summary> + </member> + <member name="P:log4net.GlobalContext.Properties"> + <summary> + The global properties map. + </summary> + <value> + The global properties map. + </value> + <remarks> + <para> + The global properties map. + </para> + </remarks> + </member> + <member name="T:log4net.LogicalThreadContext"> + <summary> + The log4net Logical Thread Context. + </summary> + <remarks> + <para> + The <c>LogicalThreadContext</c> provides a location for <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/> specific debugging + information to be stored. + The <c>LogicalThreadContext</c> properties override any <see cref="T:log4net.ThreadContext"/> or <see cref="T:log4net.GlobalContext"/> + properties with the same name. + </para> + <para> + The Logical Thread Context has a properties map and a stack. + The properties and stack can + be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/> + supports selecting and outputting these properties. + </para> + <para> + The Logical Thread Context provides a diagnostic context for the current call context. + This is an instrument for distinguishing interleaved log + output from different sources. Log output is typically interleaved + when a server handles multiple clients near-simultaneously. + </para> + <para> + The Logical Thread Context is managed on a per <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/> basis. + </para> + </remarks> + <example>Example of using the thread context properties to store a username. + <code lang="C#"> + LogicalThreadContext.Properties["user"] = userName; + log.Info("This log message has a LogicalThreadContext Property called 'user'"); + </code> + </example> + <example>Example of how to push a message into the context stack + <code lang="C#"> + using(LogicalThreadContext.Stacks["LDC"].Push("my context message")) + { + log.Info("This log message has a LogicalThreadContext Stack message that includes 'my context message'"); + + } // at the end of the using block the message is automatically popped + </code> + </example> + <threadsafety static="true" instance="true"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.LogicalThreadContext.#ctor"> + <summary> + Private Constructor. + </summary> + <remarks> + <para> + Uses a private access modifier to prevent instantiation of this class. + </para> + </remarks> + </member> + <member name="F:log4net.LogicalThreadContext.s_properties"> + <summary> + The thread context properties instance + </summary> + </member> + <member name="F:log4net.LogicalThreadContext.s_stacks"> + <summary> + The thread context stacks instance + </summary> + </member> + <member name="P:log4net.LogicalThreadContext.Properties"> + <summary> + The thread properties map + </summary> + <value> + The thread properties map + </value> + <remarks> + <para> + The <c>LogicalThreadContext</c> properties override any <see cref="T:log4net.ThreadContext"/> + or <see cref="T:log4net.GlobalContext"/> properties with the same name. + </para> + </remarks> + </member> + <member name="P:log4net.LogicalThreadContext.Stacks"> + <summary> + The thread stacks + </summary> + <value> + stack map + </value> + <remarks> + <para> + The logical thread stacks. + </para> + </remarks> + </member> + <member name="T:log4net.LogManager"> + <summary> + This class is used by client applications to request logger instances. + </summary> + <remarks> + <para> + This class has static methods that are used by a client to request + a logger instance. The <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method is + used to retrieve a logger. + </para> + <para> + See the <see cref="T:log4net.ILog"/> interface for more details. + </para> + </remarks> + <example>Simple example of logging messages + <code lang="C#"> + ILog log = LogManager.GetLogger("application-log"); + + log.Info("Application Start"); + log.Debug("This is a debug message"); + + if (log.IsDebugEnabled) + { + log.Debug("This is another debug message"); + } + </code> + </example> + <threadsafety static="true" instance="true"/> + <seealso cref="T:log4net.ILog"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.LogManager.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.LogManager"/> class. + </summary> + <remarks> + Uses a private access modifier to prevent instantiation of this class. + </remarks> + </member> + <member name="M:log4net.LogManager.Exists(System.String)"> + <overloads>Returns the named logger if it exists.</overloads> + <summary> + Returns the named logger if it exists. + </summary> + <remarks> + <para> + If the named logger exists (in the default repository) then it + returns a reference to the logger, otherwise it returns <c>null</c>. + </para> + </remarks> + <param name="name">The fully qualified logger name to look for.</param> + <returns>The logger found, or <c>null</c> if no logger could be found.</returns> + </member> + <member name="M:log4net.LogManager.Exists(System.String,System.String)"> + <summary> + Returns the named logger if it exists. + </summary> + <remarks> + <para> + If the named logger exists (in the specified repository) then it + returns a reference to the logger, otherwise it returns + <c>null</c>. + </para> + </remarks> + <param name="repository">The repository to lookup in.</param> + <param name="name">The fully qualified logger name to look for.</param> + <returns> + The logger found, or <c>null</c> if the logger doesn't exist in the specified + repository. + </returns> + </member> + <member name="M:log4net.LogManager.Exists(System.Reflection.Assembly,System.String)"> + <summary> + Returns the named logger if it exists. + </summary> + <remarks> + <para> + If the named logger exists (in the repository for the specified assembly) then it + returns a reference to the logger, otherwise it returns + <c>null</c>. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <param name="name">The fully qualified logger name to look for.</param> + <returns> + The logger, or <c>null</c> if the logger doesn't exist in the specified + assembly's repository. + </returns> + </member> + <member name="M:log4net.LogManager.GetCurrentLoggers"> + <overloads>Get the currently defined loggers.</overloads> + <summary> + Returns all the currently defined loggers in the default repository. + </summary> + <remarks> + <para>The root logger is <b>not</b> included in the returned array.</para> + </remarks> + <returns>All the defined loggers.</returns> + </member> + <member name="M:log4net.LogManager.GetCurrentLoggers(System.String)"> + <summary> + Returns all the currently defined loggers in the specified repository. + </summary> + <param name="repository">The repository to lookup in.</param> + <remarks> + The root logger is <b>not</b> included in the returned array. + </remarks> + <returns>All the defined loggers.</returns> + </member> + <member name="M:log4net.LogManager.GetCurrentLoggers(System.Reflection.Assembly)"> + <summary> + Returns all the currently defined loggers in the specified assembly's repository. + </summary> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <remarks> + The root logger is <b>not</b> included in the returned array. + </remarks> + <returns>All the defined loggers.</returns> + </member> + <member name="M:log4net.LogManager.GetLogger(System.String)"> + <overloads>Get or create a logger.</overloads> + <summary> + Retrieves or creates a named logger. + </summary> + <remarks> + <para> + Retrieves a logger named as the <paramref name="name"/> + parameter. If the named logger already exists, then the + existing instance will be returned. Otherwise, a new instance is + created. + </para> + <para>By default, loggers do not have a set level but inherit + it from the hierarchy. This is one of the central features of + log4net. + </para> + </remarks> + <param name="name">The name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + </member> + <member name="M:log4net.LogManager.GetLogger(System.String,System.String)"> + <summary> + Retrieves or creates a named logger. + </summary> + <remarks> + <para> + Retrieve a logger named as the <paramref name="name"/> + parameter. If the named logger already exists, then the + existing instance will be returned. Otherwise, a new instance is + created. + </para> + <para> + By default, loggers do not have a set level but inherit + it from the hierarchy. This is one of the central features of + log4net. + </para> + </remarks> + <param name="repository">The repository to lookup in.</param> + <param name="name">The name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + </member> + <member name="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.String)"> + <summary> + Retrieves or creates a named logger. + </summary> + <remarks> + <para> + Retrieve a logger named as the <paramref name="name"/> + parameter. If the named logger already exists, then the + existing instance will be returned. Otherwise, a new instance is + created. + </para> + <para> + By default, loggers do not have a set level but inherit + it from the hierarchy. This is one of the central features of + log4net. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <param name="name">The name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + </member> + <member name="M:log4net.LogManager.GetLogger(System.Type)"> + <summary> + Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>. + </summary> + <remarks> + Get the logger for the fully qualified name of the type specified. + </remarks> + <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + </member> + <member name="M:log4net.LogManager.GetLogger(System.String,System.Type)"> + <summary> + Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>. + </summary> + <remarks> + Gets the logger for the fully qualified name of the type specified. + </remarks> + <param name="repository">The repository to lookup in.</param> + <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + </member> + <member name="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"> + <summary> + Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>. + </summary> + <remarks> + Gets the logger for the fully qualified name of the type specified. + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param> + <returns>The logger with the name specified.</returns> + </member> + <member name="M:log4net.LogManager.Shutdown"> + <summary> + Shuts down the log4net system. + </summary> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in all the + default repositories. + </para> + <para> + Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para>The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.LogManager.ShutdownRepository"> + <overloads>Shutdown a logger repository.</overloads> + <summary> + Shuts down the default repository. + </summary> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in the + default repository. + </para> + <para>Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para>The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + </member> + <member name="M:log4net.LogManager.ShutdownRepository(System.String)"> + <summary> + Shuts down the repository for the repository specified. + </summary> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in the + <paramref name="repository"/> specified. + </para> + <para> + Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para>The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + <param name="repository">The repository to shutdown.</param> + </member> + <member name="M:log4net.LogManager.ShutdownRepository(System.Reflection.Assembly)"> + <summary> + Shuts down the repository specified. + </summary> + <remarks> + <para> + Calling this method will <b>safely</b> close and remove all + appenders in all the loggers including root contained in the + repository. The repository is looked up using + the <paramref name="repositoryAssembly"/> specified. + </para> + <para> + Some appenders need to be closed before the application exists. + Otherwise, pending logging events might be lost. + </para> + <para> + The <c>shutdown</c> method is careful to close nested + appenders before closing regular appenders. This is allows + configurations where a regular appender is attached to a logger + and again to a nested appender. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + </member> + <member name="M:log4net.LogManager.ResetConfiguration"> + <overloads>Reset the configuration of a repository</overloads> + <summary> + Resets all values contained in this repository instance to their defaults. + </summary> + <remarks> + <para> + Resets all values contained in the repository instance to their + defaults. This removes all appenders from all loggers, sets + the level of all non-root loggers to <c>null</c>, + sets their additivity flag to <c>true</c> and sets the level + of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover, + message disabling is set to its default "off" value. + </para> + </remarks> + </member> + <member name="M:log4net.LogManager.ResetConfiguration(System.String)"> + <summary> + Resets all values contained in this repository instance to their defaults. + </summary> + <remarks> + <para> + Reset all values contained in the repository instance to their + defaults. This removes all appenders from all loggers, sets + the level of all non-root loggers to <c>null</c>, + sets their additivity flag to <c>true</c> and sets the level + of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover, + message disabling is set to its default "off" value. + </para> + </remarks> + <param name="repository">The repository to reset.</param> + </member> + <member name="M:log4net.LogManager.ResetConfiguration(System.Reflection.Assembly)"> + <summary> + Resets all values contained in this repository instance to their defaults. + </summary> + <remarks> + <para> + Reset all values contained in the repository instance to their + defaults. This removes all appenders from all loggers, sets + the level of all non-root loggers to <c>null</c>, + sets their additivity flag to <c>true</c> and sets the level + of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover, + message disabling is set to its default "off" value. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param> + </member> + <member name="M:log4net.LogManager.GetLoggerRepository"> + <overloads>Get the logger repository.</overloads> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the callers assembly (<see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>). + </para> + </remarks> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> instance for the default repository.</returns> + </member> + <member name="M:log4net.LogManager.GetLoggerRepository(System.String)"> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the <paramref name="repository"/> argument. + </para> + </remarks> + <param name="repository">The repository to lookup in.</param> + </member> + <member name="M:log4net.LogManager.GetLoggerRepository(System.Reflection.Assembly)"> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the <paramref name="repositoryAssembly"/> argument. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + </member> + <member name="M:log4net.LogManager.GetRepository"> + <overloads>Get a logger repository.</overloads> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the callers assembly (<see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>). + </para> + </remarks> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> instance for the default repository.</returns> + </member> + <member name="M:log4net.LogManager.GetRepository(System.String)"> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the <paramref name="repository"/> argument. + </para> + </remarks> + <param name="repository">The repository to lookup in.</param> + </member> + <member name="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"> + <summary> + Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance. + </summary> + <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns> + <remarks> + <para> + Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified + by the <paramref name="repositoryAssembly"/> argument. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to lookup the repository.</param> + </member> + <member name="M:log4net.LogManager.CreateDomain(System.Type)"> + <overloads>Create a domain</overloads> + <summary> + Creates a repository with the specified repository type. + </summary> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.LogManager.GetRepository"/> will return + the same repository instance. + </para> + </remarks> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + </member> + <member name="M:log4net.LogManager.CreateRepository(System.Type)"> + <overloads>Create a logger repository.</overloads> + <summary> + Creates a repository with the specified repository type. + </summary> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.LogManager.GetRepository"/> will return + the same repository instance. + </para> + </remarks> + </member> + <member name="M:log4net.LogManager.CreateDomain(System.String)"> + <summary> + Creates a repository with the specified name. + </summary> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a + <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object. + </para> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An <see cref="T:System.Exception"/> will be thrown if the repository already exists. + </para> + </remarks> + <param name="repository">The name of the repository, this must be unique amongst repositories.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.LogManager.CreateRepository(System.String)"> + <summary> + Creates a repository with the specified name. + </summary> + <remarks> + <para> + Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a + <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object. + </para> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An <see cref="T:System.Exception"/> will be thrown if the repository already exists. + </para> + </remarks> + <param name="repository">The name of the repository, this must be unique amongst repositories.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.LogManager.CreateDomain(System.String,System.Type)"> + <summary> + Creates a repository with the specified name and repository type. + </summary> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An <see cref="T:System.Exception"/> will be thrown if the repository already exists. + </para> + </remarks> + <param name="repository">The name of the repository, this must be unique to the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.LogManager.CreateRepository(System.String,System.Type)"> + <summary> + Creates a repository with the specified name and repository type. + </summary> + <remarks> + <para> + The <paramref name="repository"/> name must be unique. Repositories cannot be redefined. + An <see cref="T:System.Exception"/> will be thrown if the repository already exists. + </para> + </remarks> + <param name="repository">The name of the repository, this must be unique to the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception> + </member> + <member name="M:log4net.LogManager.CreateDomain(System.Reflection.Assembly,System.Type)"> + <summary> + Creates a repository for the specified assembly and repository type. + </summary> + <remarks> + <para> + <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b> + </para> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + </member> + <member name="M:log4net.LogManager.CreateRepository(System.Reflection.Assembly,System.Type)"> + <summary> + Creates a repository for the specified assembly and repository type. + </summary> + <remarks> + <para> + The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository + specified such that a call to <see cref="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"/> with the + same assembly specified will return the same repository instance. + </para> + </remarks> + <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param> + <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/> + and has a no arg constructor. An instance of this type will be created to act + as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param> + <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns> + </member> + <member name="M:log4net.LogManager.GetAllRepositories"> + <summary> + Gets the list of currently defined repositories. + </summary> + <remarks> + <para> + Get an array of all the <see cref="T:log4net.Repository.ILoggerRepository"/> objects that have been created. + </para> + </remarks> + <returns>An array of all the known <see cref="T:log4net.Repository.ILoggerRepository"/> objects.</returns> + </member> + <member name="M:log4net.LogManager.WrapLogger(log4net.Core.ILogger)"> + <summary> + Looks up the wrapper object for the logger specified. + </summary> + <param name="logger">The logger to get the wrapper for.</param> + <returns>The wrapper for the logger specified.</returns> + </member> + <member name="M:log4net.LogManager.WrapLoggers(log4net.Core.ILogger[])"> + <summary> + Looks up the wrapper objects for the loggers specified. + </summary> + <param name="loggers">The loggers to get the wrappers for.</param> + <returns>The wrapper objects for the loggers specified.</returns> + </member> + <member name="M:log4net.LogManager.WrapperCreationHandler(log4net.Core.ILogger)"> + <summary> + Create the <see cref="T:log4net.Core.ILoggerWrapper"/> objects used by + this manager. + </summary> + <param name="logger">The logger to wrap.</param> + <returns>The wrapper for the logger specified.</returns> + </member> + <member name="F:log4net.LogManager.s_wrapperMap"> + <summary> + The wrapper map to use to hold the <see cref="T:log4net.Core.LogImpl"/> objects. + </summary> + </member> + <member name="T:log4net.MDC"> + <summary> + Implementation of Mapped Diagnostic Contexts. + </summary> + <remarks> + <note> + <para> + The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>. + The current MDC implementation forwards to the <c>ThreadContext.Properties</c>. + </para> + </note> + <para> + The MDC class is similar to the <see cref="T:log4net.NDC"/> class except that it is + based on a map instead of a stack. It provides <i>mapped + diagnostic contexts</i>. A <i>Mapped Diagnostic Context</i>, or + MDC in short, is an instrument for distinguishing interleaved log + output from different sources. Log output is typically interleaved + when a server handles multiple clients near-simultaneously. + </para> + <para> + The MDC is managed on a per thread basis. + </para> + </remarks> + <threadsafety static="true" instance="true"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.MDC.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.MDC"/> class. + </summary> + <remarks> + Uses a private access modifier to prevent instantiation of this class. + </remarks> + </member> + <member name="M:log4net.MDC.Get(System.String)"> + <summary> + Gets the context value identified by the <paramref name="key"/> parameter. + </summary> + <param name="key">The key to lookup in the MDC.</param> + <returns>The string value held for the key, or a <c>null</c> reference if no corresponding value is found.</returns> + <remarks> + <note> + <para> + The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>. + The current MDC implementation forwards to the <c>ThreadContext.Properties</c>. + </para> + </note> + <para> + If the <paramref name="key"/> parameter does not look up to a + previously defined context then <c>null</c> will be returned. + </para> + </remarks> + </member> + <member name="M:log4net.MDC.Set(System.String,System.String)"> + <summary> + Add an entry to the MDC + </summary> + <param name="key">The key to store the value under.</param> + <param name="value">The value to store.</param> + <remarks> + <note> + <para> + The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>. + The current MDC implementation forwards to the <c>ThreadContext.Properties</c>. + </para> + </note> + <para> + Puts a context value (the <paramref name="val"/> parameter) as identified + with the <paramref name="key"/> parameter into the current thread's + context map. + </para> + <para> + If a value is already defined for the <paramref name="key"/> + specified then the value will be replaced. If the <paramref name="val"/> + is specified as <c>null</c> then the key value mapping will be removed. + </para> + </remarks> + </member> + <member name="M:log4net.MDC.Remove(System.String)"> + <summary> + Removes the key value mapping for the key specified. + </summary> + <param name="key">The key to remove.</param> + <remarks> + <note> + <para> + The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>. + The current MDC implementation forwards to the <c>ThreadContext.Properties</c>. + </para> + </note> + <para> + Remove the specified entry from this thread's MDC + </para> + </remarks> + </member> + <member name="M:log4net.MDC.Clear"> + <summary> + Clear all entries in the MDC + </summary> + <remarks> + <note> + <para> + The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>. + The current MDC implementation forwards to the <c>ThreadContext.Properties</c>. + </para> + </note> + <para> + Remove all the entries from this thread's MDC + </para> + </remarks> + </member> + <member name="T:log4net.NDC"> + <summary> + Implementation of Nested Diagnostic Contexts. + </summary> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + A Nested Diagnostic Context, or NDC in short, is an instrument + to distinguish interleaved log output from different sources. Log + output is typically interleaved when a server handles multiple + clients near-simultaneously. + </para> + <para> + Interleaved log output can still be meaningful if each log entry + from different contexts had a distinctive stamp. This is where NDCs + come into play. + </para> + <para> + Note that NDCs are managed on a per thread basis. The NDC class + is made up of static methods that operate on the context of the + calling thread. + </para> + </remarks> + <example>How to push a message into the context + <code lang="C#"> + using(NDC.Push("my context message")) + { + ... all log calls will have 'my context message' included ... + + } // at the end of the using block the message is automatically removed + </code> + </example> + <threadsafety static="true" instance="true"/> + <author>Nicko Cadell</author> + <author>Gert Driesen</author> + </member> + <member name="M:log4net.NDC.#ctor"> + <summary> + Initializes a new instance of the <see cref="T:log4net.NDC"/> class. + </summary> + <remarks> + Uses a private access modifier to prevent instantiation of this class. + </remarks> + </member> + <member name="M:log4net.NDC.Clear"> + <summary> + Clears all the contextual information held on the current thread. + </summary> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + Clears the stack of NDC data held on the current thread. + </para> + </remarks> + </member> + <member name="M:log4net.NDC.CloneStack"> + <summary> + Creates a clone of the stack of context information. + </summary> + <returns>A clone of the context info for this thread.</returns> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + The results of this method can be passed to the <see cref="M:log4net.NDC.Inherit(System.Collections.Stack)"/> + method to allow child threads to inherit the context of their + parent thread. + </para> + </remarks> + </member> + <member name="M:log4net.NDC.Inherit(System.Collections.Stack)"> + <summary> + Inherits the contextual information from another thread. + </summary> + <param name="stack">The context stack to inherit.</param> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + This thread will use the context information from the stack + supplied. This can be used to initialize child threads with + the same contextual information as their parent threads. These + contexts will <b>NOT</b> be shared. Any further contexts that + are pushed onto the stack will not be visible to the other. + Call <see cref="M:log4net.NDC.CloneStack"/> to obtain a stack to pass to + this method. + </para> + </remarks> + </member> + <member name="M:log4net.NDC.Pop"> + <summary> + Removes the top context from the stack. + </summary> + <returns> + The message in the context that was removed from the top + of the stack. + </returns> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + Remove the top context from the stack, and return + it to the caller. If the stack is empty then an + empty string (not <c>null</c>) is returned. + </para> + </remarks> + </member> + <member name="M:log4net.NDC.Push(System.String)"> + <summary> + Pushes a new context message. + </summary> + <param name="message">The new context message.</param> + <returns> + An <see cref="T:System.IDisposable"/> that can be used to clean up + the context stack. + </returns> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + Pushes a new context onto the context stack. An <see cref="T:System.IDisposable"/> + is returned that can be used to clean up the context stack. This + can be easily combined with the <c>using</c> keyword to scope the + context. + </para> + </remarks> + <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword. + <code lang="C#"> + using(log4net.NDC.Push("NDC_Message")) + { + log.Warn("This should have an NDC message"); + } + </code> + </example> + </member> + <member name="M:log4net.NDC.Remove"> + <summary> + Removes the context information for this thread. It is + not required to call this method. + </summary> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + This method is not implemented. + </para> + </remarks> + </member> + <member name="M:log4net.NDC.SetMaxDepth(System.Int32)"> + <summary> + Forces the stack depth to be at most <paramref name="maxDepth"/>. + </summary> + <param name="maxDepth">The maximum depth of the stack</param> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + Forces the stack depth to be at most <paramref name="maxDepth"/>. + This may truncate the head of the stack. This only affects the + stack in the current thread. Also it does not prevent it from + growing, it only sets the maximum depth at the time of the + call. This can be used to return to a known context depth. + </para> + </remarks> + </member> + <member name="P:log4net.NDC.Depth"> + <summary> + Gets the current context depth. + </summary> + <value>The current context depth.</value> + <remarks> + <note> + <para> + The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>. + The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>. + </para> + </note> + <para> + The number of context values pushed onto the context stack. + </para> + <para> + Used to record the current depth of the context. This can then + be restored using the <see cref="M:log4net.NDC.SetMaxDepth(System.Int32)"/> method. + </para> + </remarks> + <seealso cref="M:log4net.NDC.SetMaxDepth(System.Int32)"/> + </member> + <member name="T:log4net.ThreadContext"> + <summary> + The log4net Thread Context. + </summary> + <remarks> + <para> + The <c>ThreadContext</c> provides a location for thread specific debugging + information to be stored. + The <c>ThreadContext</c> properties override any <see cref="T:log4net.GlobalContext"/> + properties with the same name. + </para> + <para> + The thread context has a properties map and a stack. + The properties and stack can + be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/> + supports selecting and outputting these properties. + </para> + <para> + The Thread Context provides a diagnostic context for the current thread. + This is an instrument for distinguishing interleaved log + output from different sources. Log output is typically interleaved + when a server handles multiple clients near-simultaneously. + </para> + <para> + The Thread Context is managed on a per thread basis. + </para> + </remarks> + <example>Example of using the thread context properties to store a username. + <code lang="C#"> + ThreadContext.Properties["user"] = userName; + log.Info("This log message has a ThreadContext Property called 'user'"); + </code> + </example> + <example>Example of how to push a message into the context stack + <code lang="C#"> + using(ThreadContext.Stacks["NDC"].Push("my context message")) + { + log.Info("This log message has a ThreadContext Stack message that includes 'my context message'"); + + } // at the end of the using block the message is automatically popped + </code> + </example> + <threadsafety static="true" instance="true"/> + <author>Nicko Cadell</author> + </member> + <member name="M:log4net.ThreadContext.#ctor"> + <summary> + Private Constructor. + </summary> + <remarks> + <para> + Uses a private access modifier to prevent instantiation of this class. + </para> + </remarks> + </member> + <member name="F:log4net.ThreadContext.s_properties"> + <summary> + The thread context properties instance + </summary> + </member> + <member name="F:log4net.ThreadContext.s_stacks"> + <summary> + The thread context stacks instance + </summary> + </member> + <member name="P:log4net.ThreadContext.Properties"> + <summary> + The thread properties map + </summary> + <value> + The thread properties map + </value> + <remarks> + <para> + The <c>ThreadContext</c> properties override any <see cref="T:log4net.GlobalContext"/> + properties with the same name. + </para> + </remarks> + </member> + <member name="P:log4net.ThreadContext.Stacks"> + <summary> + The thread stacks + </summary> + <value> + stack map + </value> + <remarks> + <para> + The thread local stacks. + </para> + </remarks> + </member> + </members> +</doc> diff --git a/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt b/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt new file mode 100644 index 0000000000..1bf2b1279d --- /dev/null +++ b/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt @@ -0,0 +1,471 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (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.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + diff --git a/dotnet/Qpid.Common/lib/saxon/saxon8.jar b/dotnet/Qpid.Common/lib/saxon/saxon8.jar Binary files differnew file mode 100644 index 0000000000..197ce75c5b --- /dev/null +++ b/dotnet/Qpid.Common/lib/saxon/saxon8.jar diff --git a/dotnet/Qpid.Common/resources/registry.template b/dotnet/Qpid.Common/resources/registry.template new file mode 100644 index 0000000000..1c0a695f10 --- /dev/null +++ b/dotnet/Qpid.Common/resources/registry.template @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<registries> + <registry name="MainRegistry"/> +</registries> diff --git a/dotnet/Qpid.Common/stylesheets/csharp.xsl b/dotnet/Qpid.Common/stylesheets/csharp.xsl new file mode 100644 index 0000000000..588ac3145f --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/csharp.xsl @@ -0,0 +1,230 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<!-- this class contains the templates for generating C# source code for a given framing model --> +<xsl:import href="utils.xsl"/> +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:param name="registry_name"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="generate-multi" select="frames"/> + <xsl:apply-templates mode="generate-registry" select="frames"/> +</xsl:template> + +<!-- processes all frames outputting the classes in a single stream --> +<!-- (useful for debugging etc) --> +<xsl:template match="frame" mode="generate-single"> + <xsl:call-template name="generate-class"> + <xsl:with-param name="f" select="."/> + </xsl:call-template> +</xsl:template> + +<!-- generates seperate file for each class/frame --> +<xsl:template match="frame" mode="generate-multi"> + <xsl:variable name="uri" select="concat(@name, '.cs')"/> + wrote <xsl:value-of select="$uri"/> + <xsl:result-document href="{$uri}" format="textFormat"> + <xsl:call-template name="generate-class"> + <xsl:with-param name="f" select="."/> + </xsl:call-template> + </xsl:result-document> +</xsl:template> + +<!-- main class generation template --> +<xsl:template name="generate-class"> + <xsl:param name="f"/> +using Qpid.Buffer; +using System.Text; + +namespace Qpid.Framing +{ + /// + /// <summary>This class is autogenerated + /// Do not modify. + ///</summary> + /// @author Code Generator Script by robert.j.greig@jpmorgan.com + public class <xsl:value-of select="$f/@name"/> : AMQMethodBody , IEncodableAMQDataBlock + { + public const int CLASS_ID = <xsl:value-of select="$f/@class-id"/>; + public const int METHOD_ID = <xsl:value-of select="$f/@method-id"/>; + + <xsl:for-each select="$f/field"> + <xsl:text>public </xsl:text><xsl:value-of select="@csharp-type"/> + <xsl:text> </xsl:text> + <xsl:value-of select="@name"/>; + </xsl:for-each> + + protected override ushort Clazz + { + get + { + return <xsl:value-of select="$f/@class-id"/>; + } + } + + protected override ushort Method + { + get + { + return <xsl:value-of select="$f/@method-id"/>; + } + } + + protected override uint BodySize + { + get + { + <xsl:choose> + <xsl:when test="$f/field"> + return (uint) + <xsl:for-each select="$f/field"> + <xsl:if test="position() != 1">+ + </xsl:if> + <xsl:value-of select="amq:field-length(.)"/> + </xsl:for-each> + ; + </xsl:when> + <xsl:otherwise>return 0;</xsl:otherwise> + </xsl:choose> + } + } + + protected override void WriteMethodPayload(ByteBuffer buffer) + { + <xsl:for-each select="$f/field"> + <xsl:if test="@type != 'bit'"> + <xsl:value-of select="amq:encoder(.)"/>; + </xsl:if> + <xsl:if test="@type = 'bit' and @boolean-index = 1"> + <xsl:text>EncodingUtils.WriteBooleans(buffer, new bool[]{</xsl:text> + <xsl:value-of select="$f/field[@type='bit']/@name" separator=", "/>}); + </xsl:if> + </xsl:for-each> + } + + protected override void PopulateMethodBodyFromBuffer(ByteBuffer buffer) + { + <xsl:for-each select="$f/field"> + <xsl:value-of select="amq:decoder(.)"/>; + </xsl:for-each> + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder(base.ToString()); + <xsl:for-each select="$f/field"> + <xsl:text>buf.Append(" </xsl:text><xsl:value-of select="@name"/>: ").Append(<xsl:value-of select="@name"/>); + </xsl:for-each> + return buf.ToString(); + } + + public static AMQFrame CreateAMQFrame(ushort channelId<xsl:if test="$f/field">, </xsl:if><xsl:value-of select="$f/field/concat(@csharp-type, ' ', @name)" separator=", "/>) + { + <xsl:value-of select="@name"/> body = new <xsl:value-of select="@name"/>(); + <xsl:for-each select="$f/field"> + <xsl:value-of select="concat('body.', @name, ' = ', @name)"/>; + </xsl:for-each> + AMQFrame frame = new AMQFrame(); + frame.Channel = channelId; + frame.BodyFrame = body; + return frame; + } +} +} +</xsl:template> + +<xsl:template match="/" mode="generate-registry"> + <xsl:text>Matching root for registry mode!</xsl:text> + <xsl:value-of select="."/> + <xsl:apply-templates select="frames" mode="generate-registry"/> +</xsl:template> + +<xsl:template match="registries" mode="generate-registry"> +Wrote MethodBodyDecoderRegistry.cs + <xsl:result-document href="MethodBodyDecoderRegistry.cs" format="textFormat"> +using System; +using System.Collections; +using log4net; + +namespace Qpid.Framing +{ + + + /// + /// <summary>This class is autogenerated + /// Do not modify. + /// </summary> + /// @author Code Generator Script by robert.j.greig@jpmorgan.com + + public class MethodBodyDecoderRegistry + { + private static readonly ILog _log = LogManager.GetLogger(typeof(MethodBodyDecoderRegistry)); + + private static readonly Hashtable _classMethodProductToMethodBodyMap = new Hashtable(); + + static MethodBodyDecoderRegistry() + { + <xsl:for-each select="registry"> + <xsl:value-of select="concat(@name, '.Register(_classMethodProductToMethodBodyMap)')"/>; + </xsl:for-each> + } + + public static AMQMethodBody Get(int clazz, int method) + { + Type bodyClass = (Type) _classMethodProductToMethodBodyMap[clazz * 1000 + method]; + if (bodyClass != null) + { + try + { + return (AMQMethodBody) Activator.CreateInstance(bodyClass); + } + catch (Exception e) + { + throw new AMQFrameDecodingException(_log, "Unable to instantiate body class for class " + clazz + " and method " + method + ": " + e, e); + } + } + else + { + throw new AMQFrameDecodingException(_log, "Unable to find a suitable decoder for class " + clazz + " and method " + method); + } + } + } + } + </xsl:result-document> +</xsl:template> + +<xsl:template match="frames" mode="list-registry"> + <xsl:if test="$registry_name"> + + <xsl:variable name="file" select="concat($registry_name, '.cs')"/> + wrote <xsl:value-of select="$file"/> + <xsl:result-document href="{$file}" format="textFormat"> + +using System.Collections; +namespace Qpid.Framing +{ + /** + * This class is autogenerated, do not modify. [From <xsl:value-of select="@protocol"/>] + */ + class <xsl:value-of select="$registry_name"/> + { + internal static void Register(Hashtable map) + { + <xsl:for-each select="frame"> + <xsl:text>map[</xsl:text> + <xsl:value-of select="@class-id"/> + <xsl:text> * 1000 + </xsl:text> + <xsl:value-of select="@method-id"/> + <xsl:text>] = typeof(</xsl:text> + <xsl:value-of select="@name"/>); + </xsl:for-each> + } +} +} + </xsl:result-document> + + </xsl:if> +</xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/framing.xsl b/dotnet/Qpid.Common/stylesheets/framing.xsl new file mode 100644 index 0000000000..e015d4c40b --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/framing.xsl @@ -0,0 +1,44 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<xsl:import href="prepare1.xsl"/> +<xsl:import href="prepare2.xsl"/> +<xsl:import href="prepare3.xsl"/> +<xsl:import href="csharp.xsl"/> + +<xsl:output indent="yes"/> +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:template match="/"> + <xsl:variable name="prepare1"> + <xsl:apply-templates mode="prepare1" select="."/> + </xsl:variable> + + <xsl:variable name="prepare2"> + <xsl:apply-templates mode="prepare2" select="$prepare1"/> + </xsl:variable> + + <xsl:variable name="model"> + <xsl:apply-templates mode="prepare3" select="$prepare2"/> + </xsl:variable> + + <xsl:apply-templates mode="generate-multi" select="$model"/> + <xsl:apply-templates mode="list-registry" select="$model"/> + + <!-- dump out the intermediary files for debugging --> + <!-- + <xsl:result-document href="prepare1.out"> + <xsl:copy-of select="$prepare1"/> + </xsl:result-document> + + <xsl:result-document href="prepare2.out"> + <xsl:copy-of select="$prepare2"/> + </xsl:result-document> + + <xsl:result-document href="model.out"> + <xsl:copy-of select="$model"/> + </xsl:result-document> + --> +</xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/java.xsl b/dotnet/Qpid.Common/stylesheets/java.xsl new file mode 100644 index 0000000000..f9904c9e94 --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/java.xsl @@ -0,0 +1,209 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<!-- this class contains the templates for generating java source code for a given framing model --> +<xsl:import href="utils.xsl"/> +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:param name="registry_name"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="generate-multi" select="frames"/> + <xsl:apply-templates mode="generate-registry" select="frames"/> +</xsl:template> + +<!-- processes all frames outputting the classes in a single stream --> +<!-- (useful for debugging etc) --> +<xsl:template match="frame" mode="generate-single"> + <xsl:call-template name="generate-class"> + <xsl:with-param name="f" select="."/> + </xsl:call-template> +</xsl:template> + +<!-- generates seperate file for each class/frame --> +<xsl:template match="frame" mode="generate-multi"> + <xsl:variable name="uri" select="concat(@name, '.java')"/> + wrote <xsl:value-of select="$uri"/> + <xsl:result-document href="{$uri}" format="textFormat"> + <xsl:call-template name="generate-class"> + <xsl:with-param name="f" select="."/> + </xsl:call-template> + </xsl:result-document> +</xsl:template> + +<!-- main class generation template --> +<xsl:template name="generate-class"> + <xsl:param name="f"/> +package org.openamq.framing; + +import org.apache.mina.common.ByteBuffer; + +/** + * This class is autogenerated, do not modify. [From <xsl:value-of select="$f/parent::frames/@protocol"/>] + */ +public class <xsl:value-of select="$f/@name"/> extends AMQMethodBody implements EncodableAMQDataBlock +{ + public static final int CLASS_ID = <xsl:value-of select="$f/@class-id"/>; + public static final int METHOD_ID = <xsl:value-of select="$f/@method-id"/>; + + <xsl:for-each select="$f/field"> + <xsl:text>public </xsl:text><xsl:value-of select="@java-type"/> + <xsl:text> </xsl:text> + <xsl:value-of select="@name"/>; + </xsl:for-each> + + protected int getClazz() + { + return <xsl:value-of select="$f/@class-id"/>; + } + + protected int getMethod() + { + return <xsl:value-of select="$f/@method-id"/>; + } + + protected int getBodySize() + { + <xsl:choose> + <xsl:when test="$f/field"> + return + <xsl:for-each select="$f/field"> + <xsl:if test="position() != 1">+ + </xsl:if> + <xsl:value-of select="amq:field-length(.)"/> + </xsl:for-each> + ; + </xsl:when> + <xsl:otherwise>return 0;</xsl:otherwise> + </xsl:choose> + } + + protected void writeMethodPayload(ByteBuffer buffer) + { + <xsl:for-each select="$f/field"> + <xsl:if test="@type != 'bit'"> + <xsl:value-of select="amq:encoder(.)"/>; + </xsl:if> + <xsl:if test="@type = 'bit' and @boolean-index = 1"> + <xsl:text>EncodingUtils.writeBooleans(buffer, new boolean[]{</xsl:text> + <xsl:value-of select="$f/field[@type='bit']/@name" separator=", "/>}); + </xsl:if> + </xsl:for-each> + } + + public void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException + { + <xsl:for-each select="$f/field"> + <xsl:value-of select="amq:decoder(.)"/>; + </xsl:for-each> + } + + public String toString() + { + StringBuffer buf = new StringBuffer(super.toString()); + <xsl:for-each select="$f/field"> + <xsl:text>buf.append(" </xsl:text><xsl:value-of select="@name"/>: ").append(<xsl:value-of select="@name"/>); + </xsl:for-each> + return buf.toString(); + } + + public static AMQFrame createAMQFrame(int channelId<xsl:if test="$f/field">, </xsl:if><xsl:value-of select="$f/field/concat(@java-type, ' ', @name)" separator=", "/>) + { + <xsl:value-of select="@name"/> body = new <xsl:value-of select="@name"/>(); + <xsl:for-each select="$f/field"> + <xsl:value-of select="concat('body.', @name, ' = ', @name)"/>; + </xsl:for-each> + AMQFrame frame = new AMQFrame(); + frame.channel = channelId; + frame.bodyFrame = body; + return frame; + } +} +</xsl:template> + +<xsl:template match="/" mode="generate-registry"> + <xsl:text>Matching root for registry mode!</xsl:text> + <xsl:value-of select="."/> + <xsl:apply-templates select="frames" mode="generate-registry"/> +</xsl:template> + +<xsl:template match="registries" mode="generate-registry"> +Wrote MethodBodyDecoderRegistry.java + <xsl:result-document href="MethodBodyDecoderRegistry.java" format="textFormat">package org.openamq.framing; + +import java.util.Map; +import java.util.HashMap; +import org.apache.log4j.Logger; +import org.openamq.AMQException; + +/** + * This class is autogenerated, do not modify. + */ +public final class MethodBodyDecoderRegistry +{ + private static final Logger _log = Logger.getLogger(MethodBodyDecoderRegistry.class); + + private static final Map _classMethodProductToMethodBodyMap = new HashMap(); + + static + { + <xsl:for-each select="registry"> + <xsl:value-of select="concat(@name, '.register(_classMethodProductToMethodBodyMap)')"/>; + </xsl:for-each> + } + + public static AMQMethodBody get(int clazz, int method) throws AMQFrameDecodingException + { + Class bodyClass = (Class) _classMethodProductToMethodBodyMap.get(new Integer(clazz * 1000 + method)); + if (bodyClass != null) + { + try + { + return (AMQMethodBody) bodyClass.newInstance(); + } + catch (Exception e) + { + throw new AMQFrameDecodingException(_log, "Unable to instantiate body class for class " + clazz + " and method " + method + ": " + e, e); + } + } + else + { + throw new AMQFrameDecodingException(_log, "Unable to find a suitable decoder for class " + clazz + " and method " + method); + } + } +} +</xsl:result-document> +</xsl:template> + +<xsl:template match="frames" mode="list-registry"> + <xsl:if test="$registry_name"> + + <xsl:variable name="file" select="concat($registry_name, '.java')"/> + wrote <xsl:value-of select="$file"/> + <xsl:result-document href="{$file}" format="textFormat">package org.openamq.framing; + +import java.util.Map; + +/** + * This class is autogenerated, do not modify. [From <xsl:value-of select="@protocol"/>] + */ +class <xsl:value-of select="$registry_name"/> +{ + static void register(Map map) + { + <xsl:for-each select="frame"> + <xsl:text>map.put(new Integer(</xsl:text> + <xsl:value-of select="@class-id"/> + <xsl:text> * 1000 + </xsl:text> + <xsl:value-of select="@method-id"/> + <xsl:text>), </xsl:text> + <xsl:value-of select="concat(@name, '.class')"/>); + </xsl:for-each> + } +} + </xsl:result-document> + + </xsl:if> +</xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/prepare1.xsl b/dotnet/Qpid.Common/stylesheets/prepare1.xsl new file mode 100644 index 0000000000..9661fb47f6 --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/prepare1.xsl @@ -0,0 +1,88 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<xsl:import href="utils.xsl"/> + +<xsl:output indent="yes"/> +<xsl:param name="asl_base"/> + +<!-- pre-process, phase 1 --> + +<xsl:template match="/"> + <xsl:apply-templates select="protocol" mode="prepare1"/> +</xsl:template> + +<xsl:template match="amqp" mode="prepare1"> + <frames> + <xsl:attribute name="protocol"> + <xsl:value-of select="@comment"/> + <xsl:text> (</xsl:text> + <xsl:text>major=</xsl:text><xsl:value-of select="option[@name='protocol_major']/@value"/> + <xsl:text>, minor=</xsl:text><xsl:value-of select="option[@name='protocol_minor']/@value"/> + <xsl:text>)</xsl:text> + </xsl:attribute> + <xsl:apply-templates mode="prepare1" select="inherit"/> + <xsl:apply-templates mode="prepare1" select="include"/> + <xsl:apply-templates mode="prepare1" select="domain"/> + <xsl:apply-templates mode="prepare1" select="class"/> + </frames> +</xsl:template> + +<xsl:template match="include" mode="prepare1"> + <xsl:if test="@filename != 'asl_constants.asl'"> + <!-- skip asl_constants.asl, we don't need it and it is not well formed so causes error warnings --> + <xsl:apply-templates select="document(@filename)" mode="prepare1"/> + </xsl:if> +</xsl:template> + +<xsl:template match="inherit" mode="prepare1"> + <xsl:variable name="ibase" select="concat('file:///', $asl_base, '/', @name, '.asl')"/> + <xsl:choose> + <xsl:when test="document($ibase)"> + <xsl:apply-templates select="document($ibase)" mode="prepare1"/> + </xsl:when> + <xsl:otherwise> + <xsl:message> + Could not inherit from <xsl:value-of select="$ibase"/>; file not found. + </xsl:message> + </xsl:otherwise> + </xsl:choose> +</xsl:template> + +<xsl:template match="class[@index]" mode="prepare1"> + <xsl:apply-templates select="method" mode="prepare1"/> +</xsl:template> + +<xsl:template match="method" mode="prepare1"> + <xsl:if test="parent::class[@index]"><!-- there is a template class that has no index, which we want to skip --> + <frame> + <xsl:attribute name="name"><xsl:value-of select="amq:class-name(parent::class/@name, @name)"/></xsl:attribute> + <xsl:attribute name="class-id"><xsl:value-of select="parent::class/@index"/></xsl:attribute> + <xsl:if test="@index"> + <xsl:attribute name="method-id"><xsl:value-of select="@index"/></xsl:attribute> + </xsl:if> + <xsl:if test="not(@index)"> + <xsl:attribute name="method-id"><xsl:number count="method"/></xsl:attribute> + </xsl:if> + + <xsl:apply-templates select="field" mode="prepare1"/> + </frame> + </xsl:if> +</xsl:template> + +<xsl:template match="domain" mode="prepare1"> + <domain> + <name><xsl:value-of select="@name"/></name> + <type><xsl:value-of select="@type"/></type> + </domain> +</xsl:template> + +<xsl:template match="field" mode="prepare1"> + <field> + <xsl:copy-of select="@name"/> + <xsl:copy-of select="@type"/> + <xsl:copy-of select="@domain"/> + </field> +</xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/prepare2.xsl b/dotnet/Qpid.Common/stylesheets/prepare2.xsl new file mode 100644 index 0000000000..d98365d1f3 --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/prepare2.xsl @@ -0,0 +1,47 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<xsl:import href="utils.xsl"/> + +<xsl:output indent="yes"/> + +<!-- pre-process, phase 2 --> + +<xsl:key name="domain-lookup" match="domain" use="name"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="prepare2" select="frames"/> +</xsl:template> + +<xsl:template match="field[@domain]" mode="prepare2"> + <field> + <xsl:variable name="t1" select="key('domain-lookup', @domain)/type"/> + <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute> + <xsl:attribute name="type"><xsl:value-of select="$t1"/></xsl:attribute> + </field> +</xsl:template> + +<xsl:template match="field[@type]" mode="prepare2"> + <field> + <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute> + <xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute> + </field> +</xsl:template> + +<xsl:template match="frames" mode="prepare2"> + <frames> + <xsl:copy-of select="@protocol"/> + <xsl:apply-templates mode="prepare2"/> + </frames> +</xsl:template> + +<xsl:template match="frame" mode="prepare2"> + <xsl:element name="{name()}"> + <xsl:copy-of select="@*"/> + <xsl:apply-templates mode="prepare2" select="field"/> + </xsl:element> +</xsl:template> + +<xsl:template match="domain" mode="prepare2"></xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/prepare3.xsl b/dotnet/Qpid.Common/stylesheets/prepare3.xsl new file mode 100644 index 0000000000..92a2648cd6 --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/prepare3.xsl @@ -0,0 +1,43 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<xsl:import href="utils.xsl"/> + +<xsl:output indent="yes"/> + +<!-- final preparation of the model --> + +<xsl:template match="/"> + <xsl:apply-templates mode="prepare3"/> +</xsl:template> + +<xsl:template match="frames" mode="prepare3"> + <frames> + <xsl:copy-of select="@protocol"/> + <xsl:apply-templates mode="prepare3"/> + </frames> +</xsl:template> + +<xsl:template match="frame" mode="prepare3"> + <xsl:element name="frame"> + <xsl:copy-of select="@*"/> + <xsl:if test="field[@type='bit']"><xsl:attribute name="has-bit-field">true</xsl:attribute></xsl:if> + <xsl:apply-templates mode="prepare3"/> + </xsl:element> +</xsl:template> + + +<xsl:template match="field" mode="prepare3"> + <field> + <xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute> + <!-- ensure the field name is processed to be a valid java name --> + <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute> + <!-- add some attributes to make code generation easier --> + <xsl:attribute name="csharp-type"><xsl:value-of select="amq:csharp-type(@type)"/></xsl:attribute> + <xsl:if test="@type='bit'"> + <xsl:attribute name="boolean-index"><xsl:number count="field[@type='bit']"/></xsl:attribute> + </xsl:if> + </field> +</xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/readme.txt b/dotnet/Qpid.Common/stylesheets/readme.txt new file mode 100644 index 0000000000..c2f98050a6 --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/readme.txt @@ -0,0 +1,52 @@ +This directory contains the xsl stylesheets used to generate the code from the +OpenAMQ protocol specification. They require an XSLT2.0 processor, currently +Saxon 8 is used. + +The generation process is controlled by the framing.xsl stylesheet. This performs +several phases of transformation, using the other stylesheets. The transformation +in each phase is defined in a separate file, and these are designed to also allow +then to be run individually. + +The generation takes the amq.asl as input, it also requires that the path to the +directory where the base asl definitions reside (those definitions that the main +amq.asl defintion inherits from) be passed in via a paramter called asl_base. + +The files involved are as follows: + + framing.xsl The control file for the entire generation process + + prepare1.xsl Resolves the separate files that make up the protocol + definition, building a single tree containing all the + information as a set of 'frame' elements, each of which + has attributes for its name, and ids for the class and + method it refers to and contains zero or more field + elements. + + A method id is generated based on the order of the + method elements within the class elements in the original + specification. The class id is taken from the enclosing + class element. + + prepare2.xsl Resolves domains into their corresponding types. (This is + much easier when all the information is in a single tree, + hence the separate frame). + + prepare3.xsl Converts names into valid java names and augments the + tree to include information that makes the subsequent + generation phase simpler e.g. the index of boolean + fields as several boolean flags are combined into a + single byte. (This is easier once the domains have been + resolved, hence the separate phase). + + java.xsl Generates java classes for each frame, and a registry of + all the frames to a 'magic' number generated from their + class and method id. + + utils.xsl Contains some utility methods for e.g. producing valid + java names. + +For debugging the framing.xsl can output the intermediary files. This can be +enabled by uncommenting the relevant lines (a comment explaining this is +provided inline). + +
\ No newline at end of file diff --git a/dotnet/Qpid.Common/stylesheets/registry.xsl b/dotnet/Qpid.Common/stylesheets/registry.xsl new file mode 100644 index 0000000000..ae2a25a792 --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/registry.xsl @@ -0,0 +1,12 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<xsl:import href="csharp.xsl"/> + +<xsl:output method="text" indent="yes" name="textFormat"/> + +<xsl:template match="/"> + <xsl:apply-templates mode="generate-registry" select="registries"/> +</xsl:template> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Common/stylesheets/utils.xsl b/dotnet/Qpid.Common/stylesheets/utils.xsl new file mode 100644 index 0000000000..5bcd646aeb --- /dev/null +++ b/dotnet/Qpid.Common/stylesheets/utils.xsl @@ -0,0 +1,164 @@ +<?xml version='1.0'?> +<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org"> + +<!-- This file contains functions that are used in the generation of the java classes for framing --> + +<!-- retrieve the java type of a given amq type --> +<xsl:function name="amq:csharp-type"> + <xsl:param name="t"/> + <xsl:choose> + <xsl:when test="$t='char'">char</xsl:when> + <xsl:when test="$t='octet'">byte</xsl:when> + <xsl:when test="$t='short'">ushort</xsl:when> + <xsl:when test="$t='shortstr'">string</xsl:when> + <xsl:when test="$t='longstr'">byte[]</xsl:when> + <xsl:when test="$t='bit'">bool</xsl:when> + <xsl:when test="$t='long'">uint</xsl:when> + <xsl:when test="$t='longlong'">ulong</xsl:when> + <xsl:when test="$t='table'">FieldTable</xsl:when> + <xsl:otherwise>Object /*WARNING: undefined type*/</xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- retrieve the code to get the field size of a given amq type --> +<xsl:function name="amq:field-length"> + <xsl:param name="f"/> + <xsl:choose> + <xsl:when test="$f/@type='bit' and $f/@boolean-index=1"> + <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='bit' and $f/@boolean-index > 1"> + <xsl:value-of select="concat('0 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='char'"> + <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='octet'"> + <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='short'"> + <xsl:value-of select="concat('2 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='long'"> + <xsl:value-of select="concat('4 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='longlong'"> + <xsl:value-of select="concat('8 /*', $f/@name, '*/')"/> + </xsl:when> + <xsl:when test="$f/@type='shortstr'"> + <xsl:value-of select="concat('(uint)EncodingUtils.EncodedShortStringLength(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='longstr'"> + <xsl:value-of select="concat('4 + (uint) (', $f/@name, ' == null ? 0 : ', $f/@name, '.Length)')"/> + </xsl:when> + <xsl:when test="$f/@type='table'"> + <xsl:value-of select="concat('(uint)EncodingUtils.EncodedFieldTableLength(', $f/@name, ')')"/> + </xsl:when> + <xsl:otherwise><xsl:text>/* WARNING: COULD NOT DETERMINE FIELD SIZE */</xsl:text></xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- retrieve the code to encode a field of a given amq type --> +<!-- Note: + This method will not provide an encoder for a bit field. + Bit fields should be encoded together separately. --> + +<xsl:function name="amq:encoder"> + <xsl:param name="f"/> + <xsl:choose> + <xsl:when test="$f/@type='char'"> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='octet'"> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='short'"> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='long'"> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='longlong'"> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='shortstr'"> + <xsl:value-of select="concat('EncodingUtils.WriteShortStringBytes(buffer, ', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='longstr'"> + <xsl:value-of select="concat('EncodingUtils.WriteLongstr(buffer, ', $f/@name, ')')"/> + </xsl:when> + <xsl:when test="$f/@type='table'"> + <xsl:value-of select="concat('EncodingUtils.WriteFieldTableBytes(buffer, ', $f/@name, ')')"/> + </xsl:when> + <xsl:otherwise><xsl:text>/* WARNING: COULD NOT DETERMINE ENCODER */</xsl:text></xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- retrieve the code to decode a field of a given amq type --> +<xsl:function name="amq:decoder"> + <xsl:param name="f"/> + <xsl:choose> + <xsl:when test="$f/@type='bit'"> + <xsl:if test="$f/@boolean-index = 1"> + <xsl:text>bool[] bools = EncodingUtils.ReadBooleans(buffer);</xsl:text> + </xsl:if> + <xsl:value-of select="concat($f/@name, ' = bools[', $f/@boolean-index - 1 , ']')"/> + </xsl:when> + <xsl:when test="$f/@type='char'"> + <xsl:value-of select="concat($f/@name, ' = buffer.GetChar()')"/> + </xsl:when> + <xsl:when test="$f/@type='octet'"> + <xsl:value-of select="concat($f/@name, ' = buffer.Get()')"/> + </xsl:when> + <xsl:when test="$f/@type='short'"> + <xsl:value-of select="concat($f/@name, ' = buffer.GetUnsignedShort()')"/> + </xsl:when> + <xsl:when test="$f/@type='long'"> + <xsl:value-of select="concat($f/@name, ' = buffer.GetUnsignedInt()')"/> + </xsl:when> + <xsl:when test="$f/@type='longlong'"> + <xsl:value-of select="concat($f/@name, ' = buffer.GetUnsignedLong()')"/> + </xsl:when> + <xsl:when test="$f/@type='shortstr'"> + <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadShortString(buffer)')"/> + </xsl:when> + <xsl:when test="$f/@type='longstr'"> + <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadLongstr(buffer)')"/> + </xsl:when> + <xsl:when test="$f/@type='table'"> + <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadFieldTable(buffer)')"/> + </xsl:when> + <xsl:otherwise><xsl:text>/* WARNING: COULD NOT DETERMINE DECODER */</xsl:text></xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- create the class name for a frame, based on class and method (passed in) --> +<xsl:function name="amq:class-name"> + <xsl:param name="class"/> + <xsl:param name="method"/> + <xsl:value-of select="concat(amq:upper-first($class),amq:upper-first(amq:field-name($method)), 'Body')"/> +</xsl:function> + +<!-- get a valid field name, processing spaces and '-'s where appropriate --> +<xsl:function name="amq:field-name"> + <xsl:param name="name"/> + <xsl:choose> + <xsl:when test="contains($name, ' ')"> + <xsl:value-of select="amq:upper-first(concat(substring-before($name, ' '), amq:upper-first(substring-after($name, ' '))))"/> + </xsl:when> + <xsl:when test="contains($name, '-')"> + <xsl:value-of select="amq:upper-first(concat(substring-before($name, '-'), amq:upper-first(substring-after($name, '-'))))"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="amq:upper-first($name)"/> + </xsl:otherwise> + </xsl:choose> +</xsl:function> + +<!-- convert the first character of the input to upper-case --> +<xsl:function name="amq:upper-first"> + <xsl:param name="in"/> + <xsl:value-of select="concat(upper-case(substring($in, 1, 1)), substring($in, 2))"/> +</xsl:function> + +</xsl:stylesheet> diff --git a/dotnet/Qpid.Messaging/AcknowledgeMode.cs b/dotnet/Qpid.Messaging/AcknowledgeMode.cs new file mode 100644 index 0000000000..efd9e8493c --- /dev/null +++ b/dotnet/Qpid.Messaging/AcknowledgeMode.cs @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public enum AcknowledgeMode + { + AutoAcknowledge, + ClientAcknowledge, + DupsOkAcknowledge, + SessionTransacted, + + /// <summary> + /// Indicates that no client acknowledgements are required. Broker assumes that once it has + /// delivered a message packet successfully it is acknowledged. + /// </summary> + NoAcknowledge, + + /// <summary> + /// Pre acknowledge means that an ack is sent per message but sent before user code has processed + /// the message (i.e. before the onMessage() call or the receive() method has returned). + /// </summary> + PreAcknowledge + } +} diff --git a/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs b/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs new file mode 100644 index 0000000000..645c0d0cdd --- /dev/null +++ b/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs @@ -0,0 +1,43 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class ChannelLimitReachedException : ResourceAllocationException + { + private long _limit; + + public ChannelLimitReachedException(long limit) + : base("Unable to create session since maximum number of sessions per connection is " + + limit + ". Either close one or more sessions or increase the " + + "maximum number of sessions per connection (or contact your OpenAMQ administrator.") + { + _limit = limit; + } + + public long Limit + { + get + { + return _limit; + } + } + } +} diff --git a/dotnet/Qpid.Messaging/DeliveryMode.cs b/dotnet/Qpid.Messaging/DeliveryMode.cs new file mode 100644 index 0000000000..af706260a5 --- /dev/null +++ b/dotnet/Qpid.Messaging/DeliveryMode.cs @@ -0,0 +1,28 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public enum DeliveryMode + { + NonPersistent, + Persistent + } +} diff --git a/dotnet/Qpid.Messaging/ExchangeClassConstants.cs b/dotnet/Qpid.Messaging/ExchangeClassConstants.cs new file mode 100644 index 0000000000..2e36a7b920 --- /dev/null +++ b/dotnet/Qpid.Messaging/ExchangeClassConstants.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class ExchangeClassConstants + { + public readonly static string TOPIC = "topic"; + public readonly static string DIRECT = "direct"; + public readonly static string HEADERS = "headers"; + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs b/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs new file mode 100644 index 0000000000..13d0d73f84 --- /dev/null +++ b/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class ExchangeNameDefaults + { + public readonly static string TOPIC = "amq.topic"; + public readonly static string DIRECT = "amq.direct"; + public readonly static string HEADERS = "amq.match"; + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Messaging/IBytesMessage.cs b/dotnet/Qpid.Messaging/IBytesMessage.cs new file mode 100644 index 0000000000..0d19e9c523 --- /dev/null +++ b/dotnet/Qpid.Messaging/IBytesMessage.cs @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public interface IBytesMessage : IMessage + { + long BodyLength { get; } + + bool ReadBoolean(); + void WriteBoolean(bool value); + + byte ReadByte(); + int ReadBytes(byte[] array); + int ReadBytes(byte[] array, int length); + void WriteByte(byte value); + void WriteBytes(byte[] value); + void WriteBytes(byte[] value, int offset, int length); + + char ReadChar(); + void WriteChar(char value); + + double ReadDouble(); + void WriteDouble(double value); + + float ReadFloat(); + void WriteFloat(float value); + + int ReadInt(); + void WriteInt(int value); + + long ReadLong(); + void WriteLong(long value); + + short ReadShort(); + void WriteShort(short value); + + short ReadSignedByte(); + void WriteSignedByte(short value); + + string ReadUTF(); + void WriteUTF(string value); + + void Reset(); + } +} diff --git a/dotnet/Qpid.Messaging/IChannel.cs b/dotnet/Qpid.Messaging/IChannel.cs new file mode 100644 index 0000000000..247d164ae7 --- /dev/null +++ b/dotnet/Qpid.Messaging/IChannel.cs @@ -0,0 +1,95 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Messaging +{ + public delegate void MessageReceivedDelegate(IMessage msg); + + public interface IChannel : IDisposable + { + AcknowledgeMode AcknowledgeMode { get; } + bool Transacted { get; } + + /// <summary> + /// Prefetch value to be used as the default for consumers created on this channel. + /// </summary> + int DefaultPrefetch + { + get; + set; + } + + void DeclareExchange(string exchangeName, string exchangeClass); + void DeleteExchange(string exchangeName); + + void DeclareQueue(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete); + void DeleteQueue(); + + string GenerateUniqueName(); + IFieldTable CreateFieldTable(); + + void Bind(string queueName, string exchangeName, string routingKey); + void Bind(string queueName, string exchangeName, string routingKey, IFieldTable args); + + IMessage CreateMessage(); + IBytesMessage CreateBytesMessage(); + ITextMessage CreateTextMessage(); + ITextMessage CreateTextMessage(string initialValue); + + #region Consuming + + MessageConsumerBuilder CreateConsumerBuilder(string queueName); + + IMessageConsumer CreateConsumer(string queueName, + int prefetch, + bool noLocal, + bool exclusive, + bool durable, + string subscriptionName); + + void Unsubscribe(string subscriptionName); + + #endregion + + #region Publishing + + MessagePublisherBuilder CreatePublisherBuilder(); + + IMessagePublisher CreatePublisher(string exchangeName, + string routingKey, + DeliveryMode deliveryMode, + long timeToLive, + bool immediate, + bool mandatory, + int priority); + + #endregion + + #region Transactions + + void Recover(); + void Commit(); + void Rollback(); + + #endregion + } +} diff --git a/dotnet/Qpid.Messaging/IConnection.cs b/dotnet/Qpid.Messaging/IConnection.cs new file mode 100644 index 0000000000..25c3ae968d --- /dev/null +++ b/dotnet/Qpid.Messaging/IConnection.cs @@ -0,0 +1,54 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Messaging +{ + public delegate void ExceptionListenerDelegate(Exception ex); + + public interface IConnection : IDisposable + { + /// <summary> + /// The connection listener that has been registered with this connection. + /// </summary> + IConnectionListener ConnectionListener + { + get; + set; + } + + ExceptionListenerDelegate ExceptionListener { get; set; } + + string ClientID { get; set; } + + /// <return>the maximum number of sessions supported by this Connection</return> + int MaximumChannelCount + { + get; + } + + IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode); + IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode, int prefetch); + + void Start(); + void Stop(); + } +} diff --git a/dotnet/Qpid.Messaging/IConnectionFactory.cs b/dotnet/Qpid.Messaging/IConnectionFactory.cs new file mode 100644 index 0000000000..682bd9eb54 --- /dev/null +++ b/dotnet/Qpid.Messaging/IConnectionFactory.cs @@ -0,0 +1,28 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public interface IConnectionFactory + { + IConnection CreateConnection(); + IConnection CreateConnection(string userId, string password); + } +} diff --git a/dotnet/Qpid.Messaging/IConnectionListener.cs b/dotnet/Qpid.Messaging/IConnectionListener.cs new file mode 100644 index 0000000000..a8112bd8e9 --- /dev/null +++ b/dotnet/Qpid.Messaging/IConnectionListener.cs @@ -0,0 +1,59 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public interface IConnectionListener + { + /// <summary> + /// Called when bytes have been transmitted to the server + /// </summary> + /// <param>count the number of bytes sent in total since the connection was opened</param> + void BytesSent(long count); + + /// <summary> + /// Called when some bytes have been received on a connection + /// </summary> + /// <param>count the number of bytes received in total since the connection was opened</param> + void BytesReceived(long count); + + /// <summary> + /// Called after the infrastructure has detected that failover is required but before attempting failover. + /// </summary> + /// <param>redirect true if the broker requested redirect. false if failover is occurring due to a connection error.</param> + /// <return>true to continue failing over, false to veto failover and raise a connection exception</return> + bool PreFailover(bool redirect); + + /// <summary> + /// Called after connection has been made to another broker after failover has been started but before + /// any resubscription has been done. + /// <return> true to continue with resubscription, false to prevent automatic resubscription. This is useful in + /// cases where the application wants to handle resubscription. Note that in the latter case all sessions, producers + /// and consumers are invalidated. + /// </return + bool PreResubscribe(); + + /// <summary> + /// Called once failover has completed successfully. This is called irrespective of whether the client has + /// vetoed automatic resubscription. + /// </summary> + void FailoverComplete(); + } +} diff --git a/dotnet/Qpid.Messaging/IFieldTable.cs b/dotnet/Qpid.Messaging/IFieldTable.cs new file mode 100644 index 0000000000..50d47e6769 --- /dev/null +++ b/dotnet/Qpid.Messaging/IFieldTable.cs @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ +using System.Collections; + +namespace Qpid.Messaging +{ + public interface IFieldTable : IEnumerable + { + int Count { get; } + + object this[string key] { get; set; } + + /// <summary> + /// Adds all the items from another field table in this one. + /// Will overwrite any items in the current table with the same key. + /// </summary> + /// <param name="source">the source field table</param> + void AddAll(IFieldTable source); + + bool Contains(string s); + void Clear(); + void Remove(string key); + } +} diff --git a/dotnet/Qpid.Messaging/IHeaders.cs b/dotnet/Qpid.Messaging/IHeaders.cs new file mode 100644 index 0000000000..fb1514f24d --- /dev/null +++ b/dotnet/Qpid.Messaging/IHeaders.cs @@ -0,0 +1,53 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public interface IHeaders + { + bool Contains(string name); + + string this[string name] { get; set; } + + bool GetBoolean(string name); + void SetBoolean(string name, bool value); + + byte GetByte(string name); + void SetByte(string name, byte value); + + short GetShort(string name); + void SetShort(string name, short value); + + int GetInt(string name); + void SetInt(string name, int value); + + long GetLong(string name); + void SetLong(string name, long value); + + float GetFloat(string name); + void SetFloat(string name, float value); + + double GetDouble(string name); + void SetDouble(string name, double value); + + string GetString(string name); + void SetString(string name, string value); + } +} diff --git a/dotnet/Qpid.Messaging/IMessage.cs b/dotnet/Qpid.Messaging/IMessage.cs new file mode 100644 index 0000000000..60febc942a --- /dev/null +++ b/dotnet/Qpid.Messaging/IMessage.cs @@ -0,0 +1,47 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public interface IMessage + { + string ContentType { get; set;} + string ContentEncoding { get; set; } + string CorrelationId { get; set; } + byte[] CorrelationIdAsBytes { get; set; } + DeliveryMode DeliveryMode { get; set; } + long Expiration { get; set; } + string MessageId { get; set; } + int Priority { get; set; } + bool Redelivered { get; set; } + string ReplyToExchangeName { get; set; } + string ReplyToRoutingKey { get; set; } + long Timestamp { get; set; } + string Type { get; set; } + IHeaders Headers { get; } + + // XXX: UserId? + // XXX: AppId? + // XXX: ClusterId? + + void Acknowledge(); + void ClearBody(); + } +} diff --git a/dotnet/Qpid.Messaging/IMessageConsumer.cs b/dotnet/Qpid.Messaging/IMessageConsumer.cs new file mode 100644 index 0000000000..20e9bd4b38 --- /dev/null +++ b/dotnet/Qpid.Messaging/IMessageConsumer.cs @@ -0,0 +1,33 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Messaging +{ + public interface IMessageConsumer : IDisposable + { + MessageReceivedDelegate OnMessage { get; set; } + + IMessage Receive(); + IMessage Receive(long delay); + IMessage ReceiveNoWait(); + } +} diff --git a/dotnet/Qpid.Messaging/IMessagePublisher.cs b/dotnet/Qpid.Messaging/IMessagePublisher.cs new file mode 100644 index 0000000000..ba9b9a2d14 --- /dev/null +++ b/dotnet/Qpid.Messaging/IMessagePublisher.cs @@ -0,0 +1,55 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Messaging +{ + public interface IMessagePublisher : IDisposable + { + DeliveryMode DeliveryMode { get; set; } + string ExchangeName { get; } + string RoutingKey { get; } + bool DisableMessageID { get; set; } + bool DisableMessageTimestamp { get; set; } + int Priority { get; set; } + long TimeToLive { get; set; } + + /// <summary> + /// Set the default MIME type for messages produced by this producer. This reduces the overhead of each message. + /// </summary> + /// <param>mimeType</param> + string MimeType + { + set; + } + + /// <summary> + /// Set the default encoding for messages produced by this producer. This reduces the overhead of each message. + /// </summary> + string Encoding + { + set; + } + + void Send(IMessage msg); + void Send(IMessage msg, DeliveryMode deliveryMode, int priority, long timeToLive); + } +} diff --git a/dotnet/Qpid.Messaging/ITextMessage.cs b/dotnet/Qpid.Messaging/ITextMessage.cs new file mode 100644 index 0000000000..7b3b5305a6 --- /dev/null +++ b/dotnet/Qpid.Messaging/ITextMessage.cs @@ -0,0 +1,27 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public interface ITextMessage : IMessage + { + string Text { get; set; } + } +} diff --git a/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs b/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs new file mode 100644 index 0000000000..6699d63a79 --- /dev/null +++ b/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs @@ -0,0 +1,74 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class MessageConsumerBuilder + { + private int _prefetch = 0; + private bool _noLocal = false; + private bool _exclusive = false; + private bool _durable = false; + private string _subscriptionName = null; + private IChannel _channel; + private readonly string _queueName; + + public MessageConsumerBuilder(IChannel channel, string queueName) + { + _channel = channel; + _queueName = queueName; + } + + public MessageConsumerBuilder withPrefetch(int prefetch) + { + _prefetch = prefetch; + return this; + } + + public MessageConsumerBuilder withNoLocal(bool noLocal) + { + _noLocal = noLocal; + return this; + } + + public MessageConsumerBuilder withExclusive(bool exclusive) + { + _exclusive = exclusive; + return this; + } + + public MessageConsumerBuilder withDurable(bool durable) + { + _durable = durable; + return this; + } + + public MessageConsumerBuilder withSubscriptionName(string subscriptionName) + { + _subscriptionName = subscriptionName; + return this; + } + + public IMessageConsumer Create() + { + return _channel.CreateConsumer(_queueName, _prefetch, _noLocal, _exclusive, _durable, _subscriptionName); + } + } +} diff --git a/dotnet/Qpid.Messaging/MessageNotReadableException.cs b/dotnet/Qpid.Messaging/MessageNotReadableException.cs new file mode 100644 index 0000000000..077a15e719 --- /dev/null +++ b/dotnet/Qpid.Messaging/MessageNotReadableException.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class MessageNotReadableException : QpidException + { + public MessageNotReadableException(string reason) : base(reason) + { + } + } +} diff --git a/dotnet/Qpid.Messaging/MessageNotWritableException.cs b/dotnet/Qpid.Messaging/MessageNotWritableException.cs new file mode 100644 index 0000000000..26905e28f3 --- /dev/null +++ b/dotnet/Qpid.Messaging/MessageNotWritableException.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class MessageNotWriteableException : QpidException + { + public MessageNotWriteableException(string reason) : base(reason) + { + } + } +} diff --git a/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs b/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs new file mode 100644 index 0000000000..ecee1b5c57 --- /dev/null +++ b/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs @@ -0,0 +1,91 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class MessagePublisherBuilder + { + /// <summary> + /// Default value for immediate flag is false, i.e. a consumer does not need to be attached to a queue + /// </summary> + const bool DEFAULT_IMMEDIATE = false; + + /// <summary> + /// Default value for mandatory flag is true, i.e. server will not silently drop messages where no queue is + /// connected to the exchange for the message + /// </summary> + const bool DEFAULT_MANDATORY = true; + + IChannel _channel; + string _exchangeName = null; + string _routingKey = null; + DeliveryMode _deliveryMode = DeliveryMode.Persistent; + long _timeToLive; + bool _immediate = DEFAULT_IMMEDIATE; + bool _mandatory = DEFAULT_MANDATORY; + int _priority = 0; + + public MessagePublisherBuilder(IChannel channel) + { + _channel = channel; + } + + public MessagePublisherBuilder withRoutingKey(string routingKey) + { + _routingKey = routingKey; + return this; + } + + public MessagePublisherBuilder withExchangeName(string exchangeName) + { + _exchangeName = exchangeName; + return this; + } + + public MessagePublisherBuilder withDeliveryMode(DeliveryMode deliveryMode) + { + _deliveryMode = deliveryMode; + return this; + } + + public MessagePublisherBuilder withTimeToLive(long timeToLive) + { + _timeToLive = timeToLive; + return this; + } + + public MessagePublisherBuilder withImmediate(bool immediate) + { + _immediate = immediate; + return this; + } + + public MessagePublisherBuilder withMandatory(bool mandatory) + { + _mandatory = mandatory; + return this; + } + + public IMessagePublisher Create() + { + return _channel.CreatePublisher(_exchangeName, _routingKey, _deliveryMode, _timeToLive, _immediate, _mandatory, _priority); + } + } +}
\ No newline at end of file diff --git a/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs b/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..8b37576c42 --- /dev/null +++ b/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* + * + * 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. + * + */ +using System; +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.Messaging")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Qpid")] +[assembly: AssemblyProduct("Qpid.Messaging")] +[assembly: AssemblyCopyright("Copyright (c) 2006 The Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e74f1805-b355-42e0-ba70-afc7c8570f03")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: CLSCompliant(true)]
\ No newline at end of file diff --git a/dotnet/Qpid.Messaging/Qpid.Messaging.csproj b/dotnet/Qpid.Messaging/Qpid.Messaging.csproj new file mode 100644 index 0000000000..b61d40e90a --- /dev/null +++ b/dotnet/Qpid.Messaging/Qpid.Messaging.csproj @@ -0,0 +1,69 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Messaging</RootNamespace>
+ <AssemblyName>Qpid.Messaging</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AcknowledgeMode.cs" />
+ <Compile Include="ChannelLimitReachedException.cs" />
+ <Compile Include="DeliveryMode.cs" />
+ <Compile Include="ExchangeClassConstants.cs" />
+ <Compile Include="ExchangeNameDefaults.cs" />
+ <Compile Include="IBytesMessage.cs" />
+ <Compile Include="IConnection.cs" />
+ <Compile Include="IConnectionFactory.cs" />
+ <Compile Include="IConnectionListener.cs" />
+ <Compile Include="IFieldTable.cs" />
+ <Compile Include="IHeaders.cs" />
+ <Compile Include="IMessage.cs" />
+ <Compile Include="IMessageConsumer.cs" />
+ <Compile Include="IMessagePublisher.cs" />
+ <Compile Include="IChannel.cs" />
+ <Compile Include="ITextMessage.cs" />
+ <Compile Include="MessageConsumerBuilder.cs" />
+ <Compile Include="MessageNotReadableException.cs" />
+ <Compile Include="MessageNotWritableException.cs" />
+ <Compile Include="MessagePublisherBuilder.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="QpidException.cs" />
+ <Compile Include="ResourceAllocationException.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/dotnet/Qpid.Messaging/QpidException.cs b/dotnet/Qpid.Messaging/QpidException.cs new file mode 100644 index 0000000000..7f0c9873e5 --- /dev/null +++ b/dotnet/Qpid.Messaging/QpidException.cs @@ -0,0 +1,36 @@ +/* + * + * 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. + * + */ +using System; + +namespace Qpid.Messaging +{ + public class QpidException : Exception + { + public QpidException(string reason) : base(reason) + { + } + + public QpidException(string reason, Exception e) + : base(reason, e) + { + } + } +} diff --git a/dotnet/Qpid.Messaging/ResourceAllocationException.cs b/dotnet/Qpid.Messaging/ResourceAllocationException.cs new file mode 100644 index 0000000000..076e374d60 --- /dev/null +++ b/dotnet/Qpid.Messaging/ResourceAllocationException.cs @@ -0,0 +1,29 @@ +/* + * + * 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. + * + */ +namespace Qpid.Messaging +{ + public class ResourceAllocationException : QpidException + { + public ResourceAllocationException(string reason) : base(reason) + { + } + } +} diff --git a/dotnet/Qpid.NET.sln b/dotnet/Qpid.NET.sln new file mode 100644 index 0000000000..a58028c413 --- /dev/null +++ b/dotnet/Qpid.NET.sln @@ -0,0 +1,61 @@ +Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Messaging", "Qpid.Messaging\Qpid.Messaging.csproj", "{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Common.Tests", "Qpid.Common.Tests\Qpid.Common.Tests.csproj", "{F83624B0-762B-4D82-900D-FF4C1B36E36E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Buffer", "Qpid.Buffer\Qpid.Buffer.csproj", "{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Client.Transport.Socket.Blocking", "Qpid.Client.Transport.Socket.Blocking\Qpid.Client.Transport.Socket.Blocking.csproj", "{52AC4940-2077-4104-A753-29A9C8C16957}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Codec", "Qpid.Codec\Qpid.Codec.csproj", "{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Client", "Qpid.Client\Qpid.Client.csproj", "{68987C05-3768-452C-A6FC-6BA1D372852F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Common", "Qpid.Common\Qpid.Common.csproj", "{77064C42-24D2-4CEB-9EA2-0EF481A43205}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Client.Tests", "Qpid.Client.Tests\Qpid.Client.Tests.csproj", "{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Release|Any CPU.Build.0 = Release|Any CPU
+ {52AC4940-2077-4104-A753-29A9C8C16957}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {52AC4940-2077-4104-A753-29A9C8C16957}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {52AC4940-2077-4104-A753-29A9C8C16957}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {52AC4940-2077-4104-A753-29A9C8C16957}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Release|Any CPU.Build.0 = Release|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/dotnet/README.txt b/dotnet/README.txt new file mode 100644 index 0000000000..8e3ee11525 --- /dev/null +++ b/dotnet/README.txt @@ -0,0 +1,55 @@ +Info +==== + +AMQP version currently 0.8 (see /Qpid.Common/amqp.xml) + + +Setup +===== + +Install: + Microsoft Visual Studio 2005 (VS2005) + MsBee 1.0 (Visual Studio plugin for targetting .NET 1.1) - only required if you want to build .NET 1.1. binaries. + Ant 1.6.5 + Cygwin (or alternatively build via cmd but alter instructions below accordingly) + +Set up PATH to include MSBuild.exe: + + $ PATH=/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:$PATH + +Set up PATH to include ant: + + $ PATH=$ANT_HOME/bin:$PATH + + +Building +======== + +Generate framing from /Qpid.Common/amqp.xml specificiation file: + + $ build-framing + +To build .NET 2.0 executables (to bin/Release): + + $ build + +To build .NET 1.1 executables via MsBee (to bin/FX_1_1/Debug): + + $ build-dotnet11 + + +Releasing +========= + +For .NET 1.1 + + $ release-dotnet 1.1 1.0M1 + +Generates ./build/Qpid.NET-1.0M1-FX1.1.zip + +For .NET 2.0 + + $ release-dotnet 2.0 1.0M1 + +Generates ./build/Qpid.NET-1.0M1-FX2.0.zip + diff --git a/dotnet/TODO.txt b/dotnet/TODO.txt new file mode 100644 index 0000000000..839853f4f9 --- /dev/null +++ b/dotnet/TODO.txt @@ -0,0 +1,28 @@ + +* Failover. + * record and replay necessary commands. + * Review new API methods for fail over requirements. + i.e. lock on mutex for non-blocking methods, FailoverSupport (for blocking methods) + +* transactions Tx.Select and Tx.Commit + * Do the TxSelect message after opening a transactional channel + +* createSession with prefetch (warning: prefetch partly added) + * Do the BasicQos message after opening channel (sets up prefetch). + +* Port Connection URL support. + +* .NET currently only supports no-ack mode. Allow acknowledgement support. + * Implement the PreAcknowledge ack mode. Add preDeliver/postDeliver methods in AmqSession like the Java client. + * Implement Recover() with Basic.Recover. + +* Blocking receive i.e. Basic.Get + +* Implement durable subscriptions. + +* SSL. SSLStream composed over NetworkStream. + +* Implement a Async IO socket transport. + Compare against blocking socket transport and configure default appropriately. + +* support multiple versions of AMQP from the same client. diff --git a/dotnet/build-dotnet11 b/dotnet/build-dotnet11 new file mode 100644 index 0000000000..95471686f9 --- /dev/null +++ b/dotnet/build-dotnet11 @@ -0,0 +1,7 @@ +pfPath=$(cygpath -m "/cygdrive/c/Program Files") + +MSBuild.exe Qpid.NET.sln \ + /p:Configuration=Release \ + /t:rebuild \ + /p:TargetFX1_1=true \ + "/p:CustomAfterMicrosoftCommonTargets=${pfPath}\MSBuild\MSBee\MSBuildExtras.Fx1_1.CSharp.targets" diff --git a/dotnet/build-dotnet11.bat b/dotnet/build-dotnet11.bat new file mode 100644 index 0000000000..ae832ef043 --- /dev/null +++ b/dotnet/build-dotnet11.bat @@ -0,0 +1 @@ +MSBuild Qpid.NET.sln /p:Configuration=Release /t:rebuild /p:TargetFX1_1=true "/p:CustomAfterMicrosoftCommonTargets=%ProgramFiles%\MSBuild\MSBee\MSBuildExtras.Fx1_1.CSharp.targets"
diff --git a/dotnet/build-dotnet20 b/dotnet/build-dotnet20 new file mode 100644 index 0000000000..713a7aa55a --- /dev/null +++ b/dotnet/build-dotnet20 @@ -0,0 +1,3 @@ +MSBuild.exe Qpid.NET.sln \ + /p:Configuration=Release \ + /t:rebuild diff --git a/dotnet/build-framing b/dotnet/build-framing new file mode 100644 index 0000000000..315a1a1cb2 --- /dev/null +++ b/dotnet/build-framing @@ -0,0 +1,2 @@ +cd Qpid.Common +ant diff --git a/dotnet/build-framing.bat b/dotnet/build-framing.bat new file mode 100644 index 0000000000..bc5aa23ab7 --- /dev/null +++ b/dotnet/build-framing.bat @@ -0,0 +1,2 @@ +cd Qpid.Common
+ant
diff --git a/dotnet/release-dotnet b/dotnet/release-dotnet new file mode 100644 index 0000000000..2d875ca1cd --- /dev/null +++ b/dotnet/release-dotnet @@ -0,0 +1,42 @@ +#!/bin/bash
+
+Usage()
+{
+ echo "usage: $0 1.1|2.0 release-number (e.g. 2.0.1)"
+ exit 2
+}
+
+if [[ $# -ne 2 ]]; then
+ Usage
+fi
+
+dotNetVersion=$1
+releaseName=Qpid.NET-$2-FX$dotNetVersion
+
+if [[ $dotNetVersion == "1.1" ]]; then
+ binDir=Qpid.Client.Tests/bin/FX1_1/Release
+elif [[ $dotNetVersion == "2.0" ]]; then
+ binDir=Qpid.Client.Tests/bin/Release
+else
+ Usage
+fi
+
+filesToRelease="
+ Qpid.Buffer.dll
+ Qpid.Client.Transport.Socket.Blocking.dll
+ Qpid.Client.dll
+ Qpid.Codec.dll
+ Qpid.Common.dll
+ Qpid.Messaging.dll
+ log4net.dll
+ log4net.xml"
+
+releaseDir=build/$releaseName
+mkdir -p $releaseDir
+
+for file in $filesToRelease; do
+ cp $binDir/$file $releaseDir
+done
+
+cd build
+jar -cvMf $releaseName.zip $releaseName
|
