79904212eec5ba077d9ef1151c07bddbe576318b
[mono.git] / mcs / class / System / System.Diagnostics / TraceImpl.cs
1 //
2 // System.Diagnostics.TraceImpl.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2002, 2005 Jonathan Pryor
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31
32 using System;
33 using System.Collections;
34 using System.Diagnostics;
35 using System.Configuration;
36 using System.Threading;
37
38 namespace System.Diagnostics {
39
40 #if !MOBILE
41         internal class TraceImplSettings {
42                 public const string Key = ".__TraceInfoSettingsKey__.";
43
44         // Disable warning that AutoFlush is not used
45 #pragma warning disable 649
46                 public bool AutoFlush;
47 #pragma warning restore
48                 //public int IndentLevel;
49                 public int IndentSize = 4;
50                 public TraceListenerCollection Listeners = new TraceListenerCollection (false);
51
52                 public TraceImplSettings ()
53                 {
54                         Listeners.Add (new DefaultTraceListener (), this);
55                 }
56         }
57 #endif
58
59         static class TraceImpl {
60
61 #if !MOBILE
62                 private static object initLock = new object ();
63 #endif
64
65                 private static bool autoFlush;
66
67                 [ThreadStatic]
68                 private static int indentLevel;
69
70                 [ThreadStatic]
71                 private static int indentSize;
72
73 #if MOBILE
74                 static TraceListenerCollection listeners = new TraceListenerCollection (true);
75 #else
76                 static TraceListenerCollection listeners;
77 #endif
78
79                 static bool use_global_lock;
80                 static CorrelationManager correlation_manager = new CorrelationManager ();
81
82                 public static bool AutoFlush {
83                         get {
84                                 InitOnce ();
85                                 return autoFlush;
86                         }
87                         set {
88                                 InitOnce ();
89                                 autoFlush = value;
90                         }
91                 }
92
93                 public static int IndentLevel {
94                         get {
95                                 InitOnce ();
96                                 return indentLevel;
97                         }
98                         set {
99                                 lock (ListenersSyncRoot) {
100                                         indentLevel = value;
101
102                                         foreach (TraceListener t in Listeners) {
103                                                 t.IndentLevel = indentLevel;
104                                         }
105                                 }
106                         }
107                 }
108
109                 public static int IndentSize {
110                         get {
111                                 InitOnce ();
112                                 return indentSize;
113                         }
114                         set {
115                                 lock (ListenersSyncRoot) {
116                                         indentSize = value;
117
118                                         foreach (TraceListener t in Listeners) {
119                                                 t.IndentSize = indentSize;
120                                         }
121                                 }
122                         }
123                 }
124
125                 public static TraceListenerCollection Listeners {
126                         get {
127                                 InitOnce ();
128
129                                 return listeners;
130                         }
131                 }
132
133                 private static object ListenersSyncRoot {
134                         get {
135                                 return ((ICollection) Listeners).SyncRoot;
136                         }
137                 }
138
139                 public static CorrelationManager CorrelationManager {
140                         get {
141                                 InitOnce ();
142                                 return correlation_manager;
143                         }
144                 }
145
146                 [MonoLimitation ("the property exists but it does nothing.")]
147                 public static bool UseGlobalLock {
148                         get {
149                                 InitOnce ();
150                                 return use_global_lock;
151                         }
152                         set {
153                                 InitOnce ();
154                                 use_global_lock = value;
155                         }
156                 }
157
158                 // Initialize the world.
159                 //
160                 // This logically belongs in the static constructor (as it only needs
161                 // to be done once), except for one thing: if the .config file has a
162                 // syntax error, .NET throws a ConfigurationException.  If we read the
163                 // .config file in the static ctor, we throw a ConfigurationException
164                 // from the static ctor, which results in a TypeLoadException.  Oops.
165                 // Reading the .config file here will allow the static ctor to
166                 // complete successfully, allowing us to throw a normal
167                 // ConfigurationException should the .config file contain an error.
168                 //
169                 // There are also some ordering issues.
170                 //
171                 // DiagnosticsConfigurationHandler doesn't store values within TraceImpl,
172                 // but instead stores values it reads from the .config file within a
173                 // TraceImplSettings object (accessible via the TraceImplSettings.Key key
174                 // in the IDictionary returned).
175                 private static void InitOnce ()
176                 {
177 #if !MOBILE
178                         if (initLock != null) {
179                                 lock (initLock) {
180                                         if (listeners == null) {
181                                                 IDictionary       d = DiagnosticsConfiguration.Settings;
182                                                 TraceImplSettings s = (TraceImplSettings) d [TraceImplSettings.Key];
183
184                                                 d.Remove (TraceImplSettings.Key);
185
186                                                 autoFlush   = s.AutoFlush;
187 //                                              indentLevel = s.IndentLevel;
188                                                 indentSize  = s.IndentSize;
189                                                 listeners   = s.Listeners;
190                                         }
191                                 }
192                                 initLock = null;
193                         }
194 #endif
195                 }
196
197                 public static void Assert (bool condition)
198                 {
199                         if (!condition)
200                                 Fail ("");
201                 }
202
203                 public static void Assert (bool condition, string message)
204                 {
205                         if (!condition)
206                                 Fail (message);
207                 }
208
209                 public static void Assert (bool condition, string message, 
210                         string detailMessage)
211                 {
212                         if (!condition)
213                                 Fail (message, detailMessage);
214                 }
215
216                 public static void Close ()
217                 {
218                         lock (ListenersSyncRoot) {
219                                 foreach (TraceListener listener in Listeners) {
220                                         listener.Close ();
221                                 }
222                         }
223                 }
224
225                 // FIXME: From testing .NET, this method should display a dialog
226                 //(it probably depends on the listener)p
227                 [MonoTODO]
228                 public static void Fail (string message)
229                 {
230                         lock (ListenersSyncRoot) {
231                                 foreach (TraceListener listener in Listeners) {
232                                         listener.Fail (message);
233                                 }
234                         }
235                 }
236
237                 // FIXME: From testing .NET, this method should display a dialog
238                 // (it probably depends on the listener)p
239                 [MonoTODO]
240                 public static void Fail (string message, string detailMessage)
241                 {
242                         lock (ListenersSyncRoot) {
243                                 foreach (TraceListener listener in Listeners) {
244                                         listener.Fail (message, detailMessage);
245                                 }
246                         }
247                 }
248
249                 public static void Flush ()
250                 {
251                         lock (ListenersSyncRoot) {
252                                 foreach (TraceListener listener in Listeners){
253                                         listener.Flush ();
254                                 }
255                         }
256                 }
257
258                 public static void Indent ()
259                 {
260                         IndentLevel ++;
261                 }
262
263                 public static void Unindent ()
264                 {
265                         IndentLevel --;
266                 }
267
268                 public static void Write (object value)
269                 {
270                         lock (ListenersSyncRoot) {
271                                 foreach (TraceListener listener in Listeners) {
272                                         listener.Write (value);
273
274                                         if (AutoFlush)
275                                                 listener.Flush ();
276                                 }
277                         }
278                 }
279
280                 public static void Write (string message)
281                 {
282                         lock (ListenersSyncRoot) {
283                                 foreach (TraceListener listener in Listeners) {
284                                         listener.Write (message);
285
286                                         if (AutoFlush)
287                                                 listener.Flush ();
288                                 }
289                         }
290                 }
291
292                 public static void Write (object value, string category)
293                 {
294                         lock (ListenersSyncRoot) {
295                                 foreach (TraceListener listener in Listeners) {
296                                         listener.Write (value, category);
297
298                                         if (AutoFlush)
299                                                 listener.Flush ();
300                                 }
301                         }
302                 }
303
304                 public static void Write (string message, string category)
305                 {
306                         lock (ListenersSyncRoot) {
307                                 foreach (TraceListener listener in Listeners) {
308                                         listener.Write (message, category);
309
310                                         if (AutoFlush)
311                                                 listener.Flush ();
312                                 }
313                         }
314                 }
315
316                 public static void WriteIf (bool condition, object value)
317                 {
318                         if (condition)
319                                 Write (value);
320                 }
321
322                 public static void WriteIf (bool condition, string message)
323                 {
324                         if (condition)
325                                 Write (message);
326                 }
327
328                 public static void WriteIf (bool condition, object value, 
329                         string category)
330                 {
331                         if (condition)
332                                 Write (value, category);
333                 }
334
335                 public static void WriteIf (bool condition, string message, 
336                         string category)
337                 {
338                         if (condition)
339                                 Write (message, category);
340                 }
341
342                 public static void WriteLine (object value)
343                 {
344                         lock (ListenersSyncRoot) {
345                                 foreach (TraceListener listener in Listeners) {
346                                         listener.WriteLine (value);
347
348                                         if (AutoFlush)
349                                                 listener.Flush ();
350                                 }
351                         }
352                 }
353
354                 public static void WriteLine (string message)
355                 {
356                         lock (ListenersSyncRoot) {
357                                 foreach (TraceListener listener in Listeners) {
358                                         listener.WriteLine (message);
359
360                                         if (AutoFlush)
361                                                 listener.Flush ();
362                                 }
363                         }
364                 }
365
366                 public static void WriteLine (object value, string category)
367                 {
368                         lock (ListenersSyncRoot) {
369                                 foreach (TraceListener listener in Listeners) {
370                                         listener.WriteLine (value, category);
371
372                                         if (AutoFlush)
373                                                 listener.Flush ();
374                                 }
375                         }
376                 }
377
378                 public static void WriteLine (string message, string category)
379                 {
380                         lock (ListenersSyncRoot) {
381                                 foreach (TraceListener listener in Listeners) {
382                                         listener.WriteLine (message, category);
383
384                                         if (AutoFlush)
385                                                 listener.Flush ();
386                                 }
387                         }
388                 }
389
390                 public static void WriteLineIf (bool condition, object value)
391                 {
392                         if (condition)
393                                 WriteLine (value);
394                 }
395
396                 public static void WriteLineIf (bool condition, string message)
397                 {
398                         if (condition)
399                                 WriteLine (message);
400                 }
401
402                 public static void WriteLineIf (bool condition, object value, 
403                         string category)
404                 {
405                         if (condition)
406                                 WriteLine (value, category);
407                 }
408
409                 public static void WriteLineIf (bool condition, string message, 
410                         string category)
411                 {
412                         if (condition)
413                                 WriteLine (message, category);
414                 }
415         }
416 }
417