New tests, update
[mono.git] / mcs / class / System.Web / System.Web / TraceData.cs
1 //
2 // System.Web.TraceData
3 //
4 // Author(s):
5 //  Jackson Harper (jackson@ximian.com)
6 //
7 // (C) 2004 Novell, Inc (http://www.novell.com)
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.IO;
35 using System.Text;
36 using System.Web.UI;
37 using System.Web.UI.WebControls;
38
39 #if NET_2_0
40 using System.Collections.Generic;
41 #endif
42
43 namespace System.Web {
44
45         class InfoTraceData
46         {
47                 public string Category;
48                 public string Message;
49                 public string Exception;
50                 public double TimeSinceFirst;
51                 public bool IsWarning;
52
53                 public InfoTraceData (string category, string message, string exception, double timeSinceFirst, bool isWarning)
54                 {
55                         this.Category = category;
56                         this.Message = message;
57                         this.Exception = exception;
58                         this.TimeSinceFirst = timeSinceFirst;
59                         this.IsWarning = isWarning;
60                 }
61         }
62
63         class ControlTraceData
64         {
65                 public string ControlId;
66                 public Type Type;
67                 public int RenderSize;
68                 public int ViewstateSize;
69                 public int Depth;
70
71                 public ControlTraceData (string controlId, Type type, int renderSize, int viewstateSize, int depth)
72                 {
73                         this.ControlId = controlId;
74                         this.Type = type;
75                         this.RenderSize = renderSize;
76                         this.ViewstateSize = viewstateSize;
77                         this.Depth = depth;
78                 }
79         }
80
81         class NameValueTraceData
82         {
83                 public string Name;
84                 public string Value;
85
86                 public NameValueTraceData (string name, string value)
87                 {
88                         this.Name = name;
89                         this.Value = value;
90                 }
91         }
92         
93         internal class TraceData {
94
95                 private bool is_first_time;
96                 private DateTime first_time;
97                 private double prev_time;
98
99 #if NET_2_0
100                 private Queue <InfoTraceData> info;
101                 private Queue <ControlTraceData> control_data;
102                 private Queue <NameValueTraceData> cookie_data;
103                 private Queue <NameValueTraceData> header_data;
104                 private Queue <NameValueTraceData> servervar_data;
105 #else
106                 private Queue info;
107                 private Queue control_data;
108                 private Queue cookie_data;
109                 private Queue header_data;
110                 private Queue servervar_data;
111                 //private DataTable viewstate_data;
112 #endif
113                 
114                 private string request_path;
115                 private string session_id;
116                 private DateTime request_time;
117                 private Encoding request_encoding;
118                 private Encoding response_encoding;
119                 private string request_type;
120                 private int status_code;
121                 private Page page;
122
123                 public TraceData ()
124                 {
125 #if NET_2_0
126                         info = new Queue <InfoTraceData> ();
127                         control_data = new Queue <ControlTraceData> ();
128                         cookie_data = new Queue <NameValueTraceData> ();
129                         header_data = new Queue <NameValueTraceData> ();
130                         servervar_data = new Queue <NameValueTraceData> ();
131 #else
132                         info = new Queue ();
133                         control_data = new Queue ();
134                         cookie_data = new Queue ();
135                         header_data = new Queue ();
136                         servervar_data = new Queue ();
137 #endif
138
139                         /* TODO
140                         viewstate_data = new DataTable ();
141                         viewstate_data.Columns.Add (new DataColumn ("ControlId", typeof (string)));
142                         viewstate_data.Columns.Add (new DataColumn ("Data", typeof (string)));
143                         */
144
145                         is_first_time = true;
146                 }
147
148                 public string RequestPath {
149                         get { return request_path; }
150                         set { request_path = value; }
151                 }
152                 
153                 public string SessionID {
154                         get { return session_id; }
155                         set { session_id = value; }
156                 }
157
158                 public DateTime RequestTime {
159                         get { return request_time; }
160                         set { request_time = value; }
161                 }
162
163                 public Encoding RequestEncoding {
164                         get { return request_encoding; }
165                         set { request_encoding = value; }
166                 }
167
168                 public Encoding ResponseEncoding {
169                         get { return response_encoding; }
170                         set { response_encoding = value; }
171                 }
172
173                 public string RequestType {
174                         get { return request_type; }
175                         set { request_type = value; }
176                 }
177
178                 public int StatusCode {
179                         get { return status_code; }
180                         set { status_code = value; }
181                 }
182
183                 public void Write (string category, string msg, Exception error, bool Warning)
184                 {
185                         double time;
186                         if (is_first_time) {
187                                 time = 0;
188                                 is_first_time = false;
189                                 first_time = DateTime.Now;
190                         } else
191                                 time = (DateTime.Now - first_time).TotalSeconds;
192
193                         info.Enqueue (
194                                 new InfoTraceData (category,
195                                                    HtmlEncode (msg),
196                                                    (error != null ? error.ToString () : null),
197                                                    time,
198                                                    Warning));
199                 }
200
201                 static string HtmlEncode (string s)
202                 {
203                         if (s == null)
204                                 return "";
205
206                         string res = HttpUtility.HtmlEncode (s);
207                         res = res.Replace ("\n", "<br>");
208                         return res.Replace (" ", "&nbsp;");
209                 }
210                 
211                 public void AddControlTree (Page page, Hashtable ctrl_vs, Hashtable sizes)
212                 {
213                         this.page = page;
214                         this.ctrl_vs = ctrl_vs;
215                         this.sizes = sizes;
216                         AddControl (page, 0);
217                 }
218
219                 Hashtable sizes;
220                 Hashtable ctrl_vs;
221                 void AddControl (Control c, int control_pos)
222                 {
223                         control_data.Enqueue (
224                                 new ControlTraceData (
225                                         c.UniqueID,
226                                         c.GetType (),
227                                         GetRenderSize (c),
228                                         GetViewStateSize (c, (ctrl_vs != null) ? ctrl_vs [c] : null),
229                                         control_pos));
230                         
231                         if (c.HasControls ()) {
232                                 foreach (Control child in c.Controls)
233                                         AddControl (child, control_pos + 1);
234                         }
235                 }
236
237                 int GetRenderSize (Control ctrl)
238                 {
239                         if (sizes == null)
240                                 return 0;
241
242                         object s = sizes [ctrl];
243                         return s == null ? 0 : (int) s;
244                 }
245
246                 static int GetViewStateSize (Control ctrl, object vs)
247                 {
248                         if (vs == null)
249                                 return 0;
250
251                         StringWriter sr = new StringWriter ();
252                         LosFormatter fmt = new LosFormatter ();
253                         fmt.Serialize (sr, vs);
254                         return sr.GetStringBuilder ().Length;
255                 }
256
257                 public void AddCookie (string name, string value)
258                 {
259                         cookie_data.Enqueue (new NameValueTraceData (name, value));
260                 }
261
262                 public void AddHeader (string name, string value)
263                 {
264                         header_data.Enqueue (new NameValueTraceData (name, value));
265                 }
266
267                 public void AddServerVar (string name, string value)
268                 {
269                         servervar_data.Enqueue (new NameValueTraceData (name, value));
270                 }
271                 
272                 public void Render (HtmlTextWriter output)
273                 {
274                         output.AddAttribute ("id", "__asptrace");
275                         output.RenderBeginTag (HtmlTextWriterTag.Div);
276                         
277                         RenderStyleSheet (output);
278                         
279                         output.AddAttribute ("class", "tracecontent");
280                         output.RenderBeginTag (HtmlTextWriterTag.Span);
281                         
282                         RenderRequestDetails (output);
283                         RenderTraceInfo (output);
284                         RenderControlTree (output);
285                         RenderCookies (output);
286                         RenderHeaders (output);
287                         RenderServerVars (output);
288                         
289                         output.RenderEndTag ();
290                         output.RenderEndTag ();
291                 }
292                 
293                 private void RenderRequestDetails (HtmlTextWriter output)
294                 {
295                         Table table = CreateTable ();
296                         
297                         table.Rows.Add (AltRow ("Request Details:"));
298                         table.Rows.Add (InfoRow2 ("Session Id:", session_id,
299                                                         "Request Type", request_type));
300                         table.Rows.Add (InfoRow2 ("Time of Request:", request_time.ToString (),
301                                                         "State Code:", status_code.ToString ()));
302                         table.Rows.Add (InfoRow2 ("Request Encoding:", request_encoding.EncodingName,
303                                                    "Response Encoding:", response_encoding.EncodingName));           
304                         table.RenderControl (output);
305                 }
306                 
307                 private void RenderTraceInfo (HtmlTextWriter output)
308                 {
309                         Table table = CreateTable ();
310                         
311                         table.Rows.Add (AltRow ("Trace Information"));
312                         table.Rows.Add (SubHeadRow ("Category", "Message", "From First(s)", "From Lasts(s)"));
313                         
314                         int pos = 0;
315 #if NET_2_0
316                         foreach (InfoTraceData i in info)
317                                 RenderTraceInfoRow (table, i, pos++);
318 #else
319                         foreach (object o in info)
320                                 RenderTraceInfoRow (table, o as InfoTraceData, pos++);
321 #endif
322                         table.RenderControl (output);
323                 }
324                 
325                 private void RenderControlTree (HtmlTextWriter output)
326                 {
327                         Table table = CreateTable ();
328                         
329                         int page_vs_size = page == null ? 0 : GetViewStateSize (page, page.GetSavedViewState ());
330                         table.Rows.Add (AltRow ("Control Tree"));
331                         table.Rows.Add (SubHeadRow ("Control Id", "Type",
332                                                 "Render Size Bytes (including children)",
333                                                 String.Format ("View state Size (total: {0} bytes)(excluding children)",
334                                                                 page_vs_size)));
335                         
336                         int pos = 0;
337 #if NET_2_0
338                         foreach (ControlTraceData r in control_data)
339                                 RenderControlTraceDataRow (table, r, pos++);
340 #else
341                         foreach (object o in control_data)
342                                 RenderControlTraceDataRow (table, o as ControlTraceData, pos++);
343 #endif
344                         table.RenderControl (output);
345                 }
346
347                 void RenderControlTraceDataRow (Table table, ControlTraceData r, int pos)
348                 {
349                         if (r == null)
350                                 return;
351                         
352                         int depth = r.Depth;
353                         string prefix = String.Empty;
354                         for (int i=0; i<depth; i++)
355                                 prefix += "&nbsp;&nbsp;&nbsp;&nbsp;";
356                         RenderAltRow (table, pos, prefix + r.ControlId,
357                                       r.Type.ToString (), r.RenderSize.ToString (),
358                                       r.ViewstateSize.ToString ());
359                 }
360                 
361                 private void RenderCookies (HtmlTextWriter output)
362                 {
363                         Table table = CreateTable ();
364                         
365                         table.Rows.Add (AltRow ("Cookies Collection"));
366                         table.Rows.Add (SubHeadRow ("Name", "Value", "Size"));
367                         
368                         int pos = 0;
369 #if NET_2_0
370                         foreach (NameValueTraceData r in cookie_data)
371                                 RenderCookieDataRow (table, r, pos++);
372 #else
373                         foreach (object o in cookie_data)
374                                 RenderCookieDataRow (table, o as NameValueTraceData, pos++);
375 #endif          
376                         
377                         table.RenderControl (output);
378                 }
379
380                 void RenderCookieDataRow (Table table, NameValueTraceData r, int pos)
381                 {
382                         if (r == null)
383                                 return;
384                         
385                         int length = r.Name.Length + (r.Value == null ? 0 : r.Value.Length);
386                         RenderAltRow (table, pos++, r.Name, r.Value, length.ToString ());
387                 }
388                 
389                 private void RenderHeaders (HtmlTextWriter output)
390                 {
391                         Table table = CreateTable ();
392                         
393                         table.Rows.Add (AltRow ("Headers Collection"));
394                         table.Rows.Add (SubHeadRow ("Name", "Value"));
395                         
396                         int pos = 0;
397 #if NET_2_0
398                         foreach (NameValueTraceData r in header_data)
399                                 RenderAltRow (table, pos++, r.Name, r.Value);
400 #else
401                         NameValueTraceData r;
402                         foreach (object o in header_data) {
403                                 r = o as NameValueTraceData;
404                                 if (r == null)
405                                         continue;
406                                 
407                                 RenderAltRow (table, pos++, r.Name, r.Value);
408                         }
409 #endif
410                         table.RenderControl (output);
411                 }
412                 
413                 private void RenderServerVars (HtmlTextWriter output)
414                 {
415                         Table table = CreateTable ();
416                         
417                         table.Rows.Add (AltRow ("Server Variables"));
418                         table.Rows.Add (SubHeadRow ("Name", "Value"));
419                         
420                         int pos = 0;
421 #if NET_2_0
422                         foreach (NameValueTraceData r in servervar_data)
423                                 RenderAltRow (table, pos++, r.Name, r.Value);
424 #else
425                         NameValueTraceData r;
426                         foreach (object o in servervar_data) {
427                                 r = o as NameValueTraceData;
428                                 if (r == null)
429                                         continue;
430                                 
431                                 RenderAltRow (table, pos++, r.Name, r.Value);
432                         }
433 #endif                  
434                         table.RenderControl (output);
435                 }
436
437                 internal static TableRow AltRow (string title)
438                 {
439                         TableRow row = new TableRow ();
440                         TableHeaderCell header = new TableHeaderCell ();
441                         header.CssClass = "alt";
442                         header.HorizontalAlign = HorizontalAlign.Left;
443                         header.Attributes [" colspan"] = "10";
444                         header.Text = "<h3><b>" + title + "</b></h3>";
445
446                         row.Cells.Add (header);
447                         return row;
448                 }
449                 
450                 private void RenderTraceInfoRow (Table table, InfoTraceData i, int pos)
451                 {
452                         if (i == null)
453                                 return;
454                         
455                         string open, close;
456                         open = close = String.Empty;
457                         if ((bool) i.IsWarning) {
458                                 open = "<font color=\"Red\">";
459                                 close = "</font>";
460                         }
461                         
462                         double t = (double) i.TimeSinceFirst;
463                         string t1, t2;
464                         if (t == 0) {
465                                 t1 = t2 = String.Empty;
466                                 prev_time = 0;
467                         } else {
468                                 t1 = t.ToString ("0.000000");
469                                 t2 = (t - prev_time).ToString ("0.000000");
470                                 prev_time = t;
471                         }
472                         
473                         RenderAltRow (table, pos, open + (string) i.Category + close,
474                                       open + (string) i.Message + close, t1, t2);
475                 }
476            
477                 internal static TableRow SubHeadRow (params string[] cells)
478                 {
479                         TableRow row = new TableRow ();
480                         foreach (string s in cells) {
481                                 TableHeaderCell cell = new TableHeaderCell ();
482                                 cell.Text = s;
483                                 row.Cells.Add (cell);
484                         }
485                         
486                         row.CssClass = "subhead";
487                         row.HorizontalAlign = HorizontalAlign.Left;
488                         
489                         return row;
490                 }
491                 
492                 internal static TableRow RenderAltRow (Table table, int pos, params string[] cells)
493                 {
494                         TableRow row = new TableRow ();
495                         foreach (string s in cells) {
496                                 TableCell cell = new TableCell ();
497                                 cell.Text = s;
498                                 row.Cells.Add (cell);
499                    }
500                         
501                         if ((pos % 2) != 0)
502                                 row.CssClass = "alt";
503                         
504                         table.Rows.Add (row);
505                         return row;
506                 }
507            
508                 private TableRow InfoRow2 (string title1, string info1, string title2, string info2)
509                 {
510                         TableRow row = new TableRow ();
511                         TableHeaderCell header1 = new TableHeaderCell ();
512                         TableHeaderCell header2 = new TableHeaderCell ();
513                         TableCell cell1 = new TableCell ();
514                         TableCell cell2 = new TableCell ();
515                         
516                         header1.Text = title1;
517                         header2.Text = title2;
518                         cell1.Text = info1;
519                         cell2.Text = info2;
520                         
521                         row.Cells.Add (header1);
522                         row.Cells.Add (cell1);
523                         row.Cells.Add (header2);
524                         row.Cells.Add (cell2);
525
526                         row.HorizontalAlign = HorizontalAlign.Left;
527                         
528                         return row;
529                 }
530                 
531                 internal static Table CreateTable ()
532                 {
533                         Table table = new Table ();
534                         
535                         table.Width = Unit.Percentage (100);
536                         table.CellSpacing = 0;
537                         table.CellPadding = 0;
538                         
539                         return table;
540                 }
541                 
542                 internal static void RenderStyleSheet (HtmlTextWriter o)
543                 {
544                         o.WriteLine ("<style type=\"text/css\">");
545                         o.Write ("span.tracecontent { background-color:white; ");
546                         o.WriteLine ("color:black;font: 10pt verdana, arial; }");
547                         o.Write ("span.tracecontent table { font: 10pt verdana, ");
548                         o.WriteLine ("arial; cellspacing:0; cellpadding:0; margin-bottom:25}");
549                         o.WriteLine ("span.tracecontent tr.subhead { background-color:cccccc;}");
550                         o.WriteLine ("span.tracecontent th { padding:0,3,0,3 }");
551                         o.WriteLine ("span.tracecontent th.alt { background-color:black; color:white; padding:3,3,2,3; }");
552                         o.WriteLine ("span.tracecontent td { padding:0,3,0,3 }");
553                         o.WriteLine ("span.tracecontent tr.alt { background-color:eeeeee }");
554                         o.WriteLine ("span.tracecontent h1 { font: 24pt verdana, arial; margin:0,0,0,0}");
555                         o.WriteLine ("span.tracecontent h2 { font: 18pt verdana, arial; margin:0,0,0,0}");
556                         o.WriteLine ("span.tracecontent h3 { font: 12pt verdana, arial; margin:0,0,0,0}");
557                         o.WriteLine ("span.tracecontent th a { color:darkblue; font: 8pt verdana, arial; }");
558                         o.WriteLine ("span.tracecontent a { color:darkblue;text-decoration:none }");
559                         o.WriteLine ("span.tracecontent a:hover { color:darkblue;text-decoration:underline; }");
560                         o.WriteLine ("span.tracecontent div.outer { width:90%; margin:15,15,15,15}");
561                         o.Write ("span.tracecontent table.viewmenu td { background-color:006699; ");
562                         o.WriteLine ("color:white; padding:0,5,0,5; }");
563                         o.WriteLine ("span.tracecontent table.viewmenu td.end { padding:0,0,0,0; }");
564                         o.WriteLine ("span.tracecontent table.viewmenu a {color:white; font: 8pt verdana, arial; }");
565                         o.WriteLine ("span.tracecontent table.viewmenu a:hover {color:white; font: 8pt verdana, arial; }");
566                         o.WriteLine ("span.tracecontent a.tinylink {color:darkblue; font: 8pt verdana, ");
567                         o.WriteLine ("arial;text-decoration:underline;}");
568                         o.WriteLine ("span.tracecontent a.link {color:darkblue; text-decoration:underline;}");
569                         o.WriteLine ("span.tracecontent div.buffer {padding-top:7; padding-bottom:17;}");
570                         o.WriteLine ("span.tracecontent .small { font: 8pt verdana, arial }");
571                         o.WriteLine ("span.tracecontent table td { padding-right:20 }");
572                         o.WriteLine ("span.tracecontent table td.nopad { padding-right:5 }");
573                         o.WriteLine ("</style>");
574                 }
575         }
576 }
577