1 #region Copyright & License
2 //
3 // Copyright 2001-2005 The Apache Software Foundation
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 #endregion
18 
19 using System;
20 using System.Collections;
21 
22 namespace log4net.Core
23 {
24 	/// <summary>
25 	/// Defines the default set of levels recognized by the system.
26 	/// </summary>
27 	/// <remarks>
28 	/// <para>
29 	/// Each <see cref="LoggingEvent"/> has an associated <see cref="Level"/>.
30 	/// </para>
31 	/// <para>
32 	/// Levels have a numeric <see cref="Level.Value"/> that defines the relative
33 	/// ordering between levels. Two Levels with the same <see cref="Level.Value"/>
34 	/// are deemed to be equivalent.
35 	/// </para>
36 	/// <para>
37 	/// The levels that are recognized by log4net are set for each <see cref="log4net.Repository.ILoggerRepository"/>
38 	/// and each repository can have different levels defined. The levels are stored
39 	/// in the <see cref="log4net.Repository.ILoggerRepository.LevelMap"/> on the repository. Levels are
40 	/// looked up by name from the <see cref="log4net.Repository.ILoggerRepository.LevelMap"/>.
41 	/// </para>
42 	/// <para>
43 	/// When logging at level INFO the actual level used is not <see cref="Level.Info"/> but
44 	/// the value of <c>LoggerRepository.LevelMap["INFO"]</c>. The default value for this is
45 	/// <see cref="Level.Info"/>, but this can be changed by reconfiguring the level map.
46 	/// </para>
47 	/// <para>
48 	/// Each level has a <see cref="DisplayName"/> in addition to its <see cref="Name"/>. The
49 	/// <see cref="DisplayName"/> is the string that is written into the output log. By default
50 	/// the display name is the same as the level name, but this can be used to alias levels
51 	/// or to localize the log output.
52 	/// </para>
53 	/// <para>
54 	/// Some of the predefined levels recognized by the system are:
55 	/// </para>
56 	/// <list type="bullet">
57 	///		<item>
58 	///			<description><see cref="Off"/>.</description>
59 	///		</item>
60 	///		<item>
61 	///			<description><see cref="Fatal"/>.</description>
62 	///		</item>
63 	///		<item>
64 	///			<description><see cref="Error"/>.</description>
65 	///		</item>
66 	///		<item>
67 	///			<description><see cref="Warn"/>.</description>
68 	///		</item>
69 	///		<item>
70 	///			<description><see cref="Info"/>.</description>
71 	///		</item>
72 	///		<item>
73 	///			<description><see cref="Debug"/>.</description>
74 	///		</item>
75 	///		<item>
76 	///			<description><see cref="All"/>.</description>
77 	///		</item>
78 	/// </list>
79 	/// </remarks>
80 	/// <author>Nicko Cadell</author>
81 	/// <author>Gert Driesen</author>
82 #if !NETCF
83 	[Serializable]
84 #endif
85 	sealed public class Level : IComparable
86 	{
87 		#region Public Instance Constructors
88 
89 		/// <summary>
90 		/// Constructor
91 		/// </summary>
92 		/// <param name="level">Integer value for this level, higher values represent more severe levels.</param>
93 		/// <param name="levelName">The string name of this level.</param>
94 		/// <param name="displayName">The display name for this level. This may be localized or otherwise different from the name</param>
95 		/// <remarks>
96 		/// <para>
97 		/// Initializes a new instance of the <see cref="Level" /> class with
98 		/// the specified level name and value.
99 		/// </para>
100 		/// </remarks>
Level(int level, string levelName, string displayName)101 		public Level(int level, string levelName, string displayName)
102 		{
103 			if (levelName == null)
104 			{
105 				throw new ArgumentNullException("levelName");
106 			}
107 			if (displayName == null)
108 			{
109 				throw new ArgumentNullException("displayName");
110 			}
111 
112 			m_levelValue = level;
113 			m_levelName = string.Intern(levelName);
114 			m_levelDisplayName = displayName;
115 		}
116 
117 		/// <summary>
118 		/// Constructor
119 		/// </summary>
120 		/// <param name="level">Integer value for this level, higher values represent more severe levels.</param>
121 		/// <param name="levelName">The string name of this level.</param>
122 		/// <remarks>
123 		/// <para>
124 		/// Initializes a new instance of the <see cref="Level" /> class with
125 		/// the specified level name and value.
126 		/// </para>
127 		/// </remarks>
Level(int level, string levelName)128 		public Level(int level, string levelName) : this(level, levelName, levelName)
129 		{
130 		}
131 
132 		#endregion Public Instance Constructors
133 
134 		#region Public Instance Properties
135 
136 		/// <summary>
137 		/// Gets the name of this level.
138 		/// </summary>
139 		/// <value>
140 		/// The name of this level.
141 		/// </value>
142 		/// <remarks>
143 		/// <para>
144 		/// Gets the name of this level.
145 		/// </para>
146 		/// </remarks>
147 		public string Name
148 		{
149 			get { return m_levelName; }
150 		}
151 
152 		/// <summary>
153 		/// Gets the value of this level.
154 		/// </summary>
155 		/// <value>
156 		/// The value of this level.
157 		/// </value>
158 		/// <remarks>
159 		/// <para>
160 		/// Gets the value of this level.
161 		/// </para>
162 		/// </remarks>
163 		public int Value
164 		{
165 			get { return m_levelValue; }
166 		}
167 
168 		/// <summary>
169 		/// Gets the display name of this level.
170 		/// </summary>
171 		/// <value>
172 		/// The display name of this level.
173 		/// </value>
174 		/// <remarks>
175 		/// <para>
176 		/// Gets the display name of this level.
177 		/// </para>
178 		/// </remarks>
179 		public string DisplayName
180 		{
181 			get { return m_levelDisplayName; }
182 		}
183 
184 		#endregion Public Instance Properties
185 
186 		#region Override implementation of Object
187 
188 		/// <summary>
189 		/// Returns the <see cref="string" /> representation of the current
190 		/// <see cref="Level" />.
191 		/// </summary>
192 		/// <returns>
193 		/// A <see cref="string" /> representation of the current <see cref="Level" />.
194 		/// </returns>
195 		/// <remarks>
196 		/// <para>
197 		/// Returns the level <see cref="Name"/>.
198 		/// </para>
199 		/// </remarks>
ToString()200 		override public string ToString()
201 		{
202 			return m_levelName;
203 		}
204 
205 		/// <summary>
206 		/// Compares levels.
207 		/// </summary>
208 		/// <param name="o">The object to compare against.</param>
209 		/// <returns><c>true</c> if the objects are equal.</returns>
210 		/// <remarks>
211 		/// <para>
212 		/// Compares the levels of <see cref="Level" /> instances, and
213 		/// defers to base class if the target object is not a <see cref="Level" />
214 		/// instance.
215 		/// </para>
216 		/// </remarks>
Equals(object o)217 		override public bool Equals(object o)
218 		{
219 			Level otherLevel = o as Level;
220 			if (otherLevel != null)
221 			{
222 				return m_levelValue == otherLevel.m_levelValue;
223 			}
224 			else
225 			{
226 				return base.Equals(o);
227 			}
228 		}
229 
230 		/// <summary>
231 		/// Returns a hash code
232 		/// </summary>
233 		/// <returns>A hash code for the current <see cref="Level" />.</returns>
234 		/// <remarks>
235 		/// <para>
236 		/// Returns a hash code suitable for use in hashing algorithms and data
237 		/// structures like a hash table.
238 		/// </para>
239 		/// <para>
240 		/// Returns the hash code of the level <see cref="Value"/>.
241 		/// </para>
242 		/// </remarks>
GetHashCode()243 		override public int GetHashCode()
244 		{
245 			return m_levelValue;
246 		}
247 
248 		#endregion Override implementation of Object
249 
250 		#region Implementation of IComparable
251 
252 		/// <summary>
253 		/// Compares this instance to a specified object and returns an
254 		/// indication of their relative values.
255 		/// </summary>
256 		/// <param name="r">A <see cref="Level"/> instance or <see langword="null" /> to compare with this instance.</param>
257 		/// <returns>
258 		/// A 32-bit signed integer that indicates the relative order of the
259 		/// values compared. The return value has these meanings:
260 		/// <list type="table">
261 		///		<listheader>
262 		///			<term>Value</term>
263 		///			<description>Meaning</description>
264 		///		</listheader>
265 		///		<item>
266 		///			<term>Less than zero</term>
267 		///			<description>This instance is less than <paramref name="r" />.</description>
268 		///		</item>
269 		///		<item>
270 		///			<term>Zero</term>
271 		///			<description>This instance is equal to <paramref name="r" />.</description>
272 		///		</item>
273 		///		<item>
274 		///			<term>Greater than zero</term>
275 		///			<description>
276 		///				<para>This instance is greater than <paramref name="r" />.</para>
277 		///				<para>-or-</para>
278 		///				<para><paramref name="r" /> is <see langword="null" />.</para>
279 		///				</description>
280 		///		</item>
281 		/// </list>
282 		/// </returns>
283 		/// <remarks>
284 		/// <para>
285 		/// <paramref name="r" /> must be an instance of <see cref="Level" />
286 		/// or <see langword="null" />; otherwise, an exception is thrown.
287 		/// </para>
288 		/// </remarks>
289 		/// <exception cref="ArgumentException"><paramref name="r" /> is not a <see cref="Level" />.</exception>
CompareTo(object r)290 		public int CompareTo(object r)
291 		{
292 			Level target = r as Level;
293 			if (target != null)
294 			{
295 				return Compare(this, target);
296 			}
297 			throw new ArgumentException("Parameter: r, Value: [" + r + "] is not an instance of Level");
298 		}
299 
300 		#endregion Implementation of IComparable
301 
302 		#region Operators
303 
304 		/// <summary>
305 		/// Returns a value indicating whether a specified <see cref="Level" />
306 		/// is greater than another specified <see cref="Level" />.
307 		/// </summary>
308 		/// <param name="l">A <see cref="Level" /></param>
309 		/// <param name="r">A <see cref="Level" /></param>
310 		/// <returns>
311 		/// <c>true</c> if <paramref name="l" /> is greater than
312 		/// <paramref name="r" />; otherwise, <c>false</c>.
313 		/// </returns>
314 		/// <remarks>
315 		/// <para>
316 		/// Compares two levels.
317 		/// </para>
318 		/// </remarks>
operator >(Level l, Level r)319 		public static bool operator > (Level l, Level r)
320 		{
321 			return l.m_levelValue > r.m_levelValue;
322 		}
323 
324 		/// <summary>
325 		/// Returns a value indicating whether a specified <see cref="Level" />
326 		/// is less than another specified <see cref="Level" />.
327 		/// </summary>
328 		/// <param name="l">A <see cref="Level" /></param>
329 		/// <param name="r">A <see cref="Level" /></param>
330 		/// <returns>
331 		/// <c>true</c> if <paramref name="l" /> is less than
332 		/// <paramref name="r" />; otherwise, <c>false</c>.
333 		/// </returns>
334 		/// <remarks>
335 		/// <para>
336 		/// Compares two levels.
337 		/// </para>
338 		/// </remarks>
operator <(Level l, Level r)339 		public static bool operator < (Level l, Level r)
340 		{
341 			return l.m_levelValue < r.m_levelValue;
342 		}
343 
344 		/// <summary>
345 		/// Returns a value indicating whether a specified <see cref="Level" />
346 		/// is greater than or equal to another specified <see cref="Level" />.
347 		/// </summary>
348 		/// <param name="l">A <see cref="Level" /></param>
349 		/// <param name="r">A <see cref="Level" /></param>
350 		/// <returns>
351 		/// <c>true</c> if <paramref name="l" /> is greater than or equal to
352 		/// <paramref name="r" />; otherwise, <c>false</c>.
353 		/// </returns>
354 		/// <remarks>
355 		/// <para>
356 		/// Compares two levels.
357 		/// </para>
358 		/// </remarks>
operator >=(Level l, Level r)359 		public static bool operator >= (Level l, Level r)
360 		{
361 			return l.m_levelValue >= r.m_levelValue;
362 		}
363 
364 		/// <summary>
365 		/// Returns a value indicating whether a specified <see cref="Level" />
366 		/// is less than or equal to another specified <see cref="Level" />.
367 		/// </summary>
368 		/// <param name="l">A <see cref="Level" /></param>
369 		/// <param name="r">A <see cref="Level" /></param>
370 		/// <returns>
371 		/// <c>true</c> if <paramref name="l" /> is less than or equal to
372 		/// <paramref name="r" />; otherwise, <c>false</c>.
373 		/// </returns>
374 		/// <remarks>
375 		/// <para>
376 		/// Compares two levels.
377 		/// </para>
378 		/// </remarks>
operator <=(Level l, Level r)379 		public static bool operator <= (Level l, Level r)
380 		{
381 			return l.m_levelValue <= r.m_levelValue;
382 		}
383 
384 		/// <summary>
385 		/// Returns a value indicating whether two specified <see cref="Level" />
386 		/// objects have the same value.
387 		/// </summary>
388 		/// <param name="l">A <see cref="Level" /> or <see langword="null" />.</param>
389 		/// <param name="r">A <see cref="Level" /> or <see langword="null" />.</param>
390 		/// <returns>
391 		/// <c>true</c> if the value of <paramref name="l" /> is the same as the
392 		/// value of <paramref name="r" />; otherwise, <c>false</c>.
393 		/// </returns>
394 		/// <remarks>
395 		/// <para>
396 		/// Compares two levels.
397 		/// </para>
398 		/// </remarks>
operator ==(Level l, Level r)399 		public static bool operator == (Level l, Level r)
400 		{
401 			if (((object)l) != null && ((object)r) != null)
402 			{
403 				return l.m_levelValue == r.m_levelValue;
404 			}
405 			else
406 			{
407 				return ((object) l) == ((object) r);
408 			}
409 		}
410 
411 		/// <summary>
412 		/// Returns a value indicating whether two specified <see cref="Level" />
413 		/// objects have different values.
414 		/// </summary>
415 		/// <param name="l">A <see cref="Level" /> or <see langword="null" />.</param>
416 		/// <param name="r">A <see cref="Level" /> or <see langword="null" />.</param>
417 		/// <returns>
418 		/// <c>true</c> if the value of <paramref name="l" /> is different from
419 		/// the value of <paramref name="r" />; otherwise, <c>false</c>.
420 		/// </returns>
421 		/// <remarks>
422 		/// <para>
423 		/// Compares two levels.
424 		/// </para>
425 		/// </remarks>
operator !=(Level l, Level r)426 		public static bool operator != (Level l, Level r)
427 		{
428 			return !(l==r);
429 		}
430 
431 		#endregion Operators
432 
433 		#region Public Static Methods
434 
435 		/// <summary>
436 		/// Compares two specified <see cref="Level"/> instances.
437 		/// </summary>
438 		/// <param name="l">The first <see cref="Level"/> to compare.</param>
439 		/// <param name="r">The second <see cref="Level"/> to compare.</param>
440 		/// <returns>
441 		/// A 32-bit signed integer that indicates the relative order of the
442 		/// two values compared. The return value has these meanings:
443 		/// <list type="table">
444 		///		<listheader>
445 		///			<term>Value</term>
446 		///			<description>Meaning</description>
447 		///		</listheader>
448 		///		<item>
449 		///			<term>Less than zero</term>
450 		///			<description><paramref name="l" /> is less than <paramref name="r" />.</description>
451 		///		</item>
452 		///		<item>
453 		///			<term>Zero</term>
454 		///			<description><paramref name="l" /> is equal to <paramref name="r" />.</description>
455 		///		</item>
456 		///		<item>
457 		///			<term>Greater than zero</term>
458 		///			<description><paramref name="l" /> is greater than <paramref name="r" />.</description>
459 		///		</item>
460 		/// </list>
461 		/// </returns>
462 		/// <remarks>
463 		/// <para>
464 		/// Compares two levels.
465 		/// </para>
466 		/// </remarks>
Compare(Level l, Level r)467 		public static int Compare(Level l, Level r)
468 		{
469 			// Reference equals
470 			if ((object)l == (object)r)
471 			{
472 				return 0;
473 			}
474 
475 			if (l == null && r == null)
476 			{
477 				return 0;
478 			}
479 			if (l == null)
480 			{
481 				return -1;
482 			}
483 			if (r == null)
484 			{
485 				return 1;
486 			}
487 
488 			return l.m_levelValue - r.m_levelValue;
489 		}
490 
491 		#endregion Public Static Methods
492 
493 		#region Public Static Fields
494 
495 		/// <summary>
496 		/// The <see cref="Off" /> level designates a higher level than all the rest.
497 		/// </summary>
498 		public readonly static Level Off = new Level(int.MaxValue, "OFF");
499 
500 		/// <summary>
501 		/// The <see cref="Emergency" /> level designates very severe error events.
502 		/// System unusable, emergencies.
503 		/// </summary>
504 		public readonly static Level Emergency = new Level(120000, "EMERGENCY");
505 
506 		/// <summary>
507 		/// The <see cref="Fatal" /> level designates very severe error events
508 		/// that will presumably lead the application to abort.
509 		/// </summary>
510 		public readonly static Level Fatal = new Level(110000, "FATAL");
511 
512 		/// <summary>
513 		/// The <see cref="Alert" /> level designates very severe error events.
514 		/// Take immediate action, alerts.
515 		/// </summary>
516 		public readonly static Level Alert = new Level(100000, "ALERT");
517 
518 		/// <summary>
519 		/// The <see cref="Critical" /> level designates very severe error events.
520 		/// Critical condition, critical.
521 		/// </summary>
522 		public readonly static Level Critical = new Level(90000, "CRITICAL");
523 
524 		/// <summary>
525 		/// The <see cref="Severe" /> level designates very severe error events.
526 		/// </summary>
527 		public readonly static Level Severe = new Level(80000, "SEVERE");
528 
529 		/// <summary>
530 		/// The <see cref="Error" /> level designates error events that might
531 		/// still allow the application to continue running.
532 		/// </summary>
533 		public readonly static Level Error = new Level(70000, "ERROR");
534 
535 		/// <summary>
536 		/// The <see cref="Warn" /> level designates potentially harmful
537 		/// situations.
538 		/// </summary>
539 		public readonly static Level Warn  = new Level(60000, "WARN");
540 
541 		/// <summary>
542 		/// The <see cref="Notice" /> level designates informational messages
543 		/// that highlight the progress of the application at the highest level.
544 		/// </summary>
545 		public readonly static Level Notice  = new Level(50000, "NOTICE");
546 
547 		/// <summary>
548 		/// The <see cref="Info" /> level designates informational messages that
549 		/// highlight the progress of the application at coarse-grained level.
550 		/// </summary>
551 		public readonly static Level Info  = new Level(40000, "INFO");
552 
553 		/// <summary>
554 		/// The <see cref="Debug" /> level designates fine-grained informational
555 		/// events that are most useful to debug an application.
556 		/// </summary>
557 		public readonly static Level Debug = new Level(30000, "DEBUG");
558 
559 		/// <summary>
560 		/// The <see cref="Fine" /> level designates fine-grained informational
561 		/// events that are most useful to debug an application.
562 		/// </summary>
563 		public readonly static Level Fine = new Level(30000, "FINE");
564 
565 		/// <summary>
566 		/// The <see cref="Trace" /> level designates fine-grained informational
567 		/// events that are most useful to debug an application.
568 		/// </summary>
569 		public readonly static Level Trace = new Level(20000, "TRACE");
570 
571 		/// <summary>
572 		/// The <see cref="Finer" /> level designates fine-grained informational
573 		/// events that are most useful to debug an application.
574 		/// </summary>
575 		public readonly static Level Finer = new Level(20000, "FINER");
576 
577 		/// <summary>
578 		/// The <see cref="Verbose" /> level designates fine-grained informational
579 		/// events that are most useful to debug an application.
580 		/// </summary>
581 		public readonly static Level Verbose = new Level(10000, "VERBOSE");
582 
583 		/// <summary>
584 		/// The <see cref="Finest" /> level designates fine-grained informational
585 		/// events that are most useful to debug an application.
586 		/// </summary>
587 		public readonly static Level Finest = new Level(10000, "FINEST");
588 
589 		/// <summary>
590 		/// The <see cref="All" /> level designates the lowest level possible.
591 		/// </summary>
592 		public readonly static Level All = new Level(int.MinValue, "ALL");
593 
594 		#endregion Public Static Fields
595 
596 		#region Private Instance Fields
597 
598 		private readonly int m_levelValue;
599 		private readonly string m_levelName;
600 		private readonly string m_levelDisplayName;
601 
602 		#endregion Private Instance Fields
603 	}
604 }
605