Add few more missing references
[mono.git] / mcs / class / System.Web.DynamicData / System.Web.DynamicData / DynamicDataManager.cs
1 //
2 // DynamicDataManager.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Marek Habersack <mhabersack@novell.com>
7 //
8 // Copyright (C) 2008-2009 Novell Inc. http://novell.com
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 using System;
32 using System.Collections;
33 using System.Collections.Generic;
34 using System.Collections.Specialized;
35 using System.ComponentModel;
36 using System.Drawing;
37 using System.Globalization;
38 using System.Security.Permissions;
39 using System.Security.Principal;
40 using System.Web.Caching;
41 using System.Web.UI;
42 using System.Web.UI.WebControls;
43 using System.Web.DynamicData.ModelProviders;
44
45 namespace System.Web.DynamicData
46 {
47         [ToolboxBitmap (typeof(DynamicDataManager), "DynamicDataManager.ico")]
48         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
50         [NonVisualControl]
51         [ParseChildren (true)]
52         [PersistChildren (false)]
53         public class DynamicDataManager : Control
54         {
55                 private class AutoFieldGenerator : IAutoFieldGenerator
56                 {
57                         MetaTable table;
58                         
59                         public AutoFieldGenerator (MetaTable table)
60                         {
61                                 this.table = table;
62                         }
63                         
64                         public ICollection GenerateFields (Control ctl)
65                         {
66                                 var ret = new List <DynamicField> ();
67                                 foreach (MetaColumn column in table.Columns) {
68                                         if (!column.Scaffold)
69                                                 continue;
70                                         
71                                         var field = new DynamicField ();
72                                         field.DataField = column.Name;
73                                         ret.Add (field);
74                                 }
75                                 
76                                 return ret;
77                         }
78                 }
79
80                 Dictionary <IDynamicDataSource, bool> knownDataSources;
81                 
82                 public DynamicDataManager ()
83                 {
84                 }
85
86                 public bool AutoLoadForeignKeys {
87                         get;
88                         set;
89                 }
90
91                 [Browsable (false)]
92                 public override bool Visible {
93                         get { return true; }
94
95                         // NOTE: it is supposed to throw the exception
96                         set { throw new NotImplementedException (); }
97                 }
98
99                 protected override void OnLoad (EventArgs e)
100                 {
101                         base.OnLoad (e);
102
103                         // http://forums.asp.net/p/1257004/2339034.aspx
104                         // http://forums.asp.net/t/1297860.aspx
105                         // http://forums.asp.net/p/1396453/3005197.aspx#3005197
106                         if (knownDataSources != null) {
107                                 foreach (var de in knownDataSources) {
108                                         IDynamicDataSource dds = de.Key;
109                                         if (dds == null)
110                                                 continue;
111
112                                         dds.ExpandDynamicWhereParameters ();
113                                 }
114                         }
115                 }
116
117                 public void RegisterControl (Control control)
118                 {
119                         RegisterControl (control, false);
120                 }
121
122                 public void RegisterControl (Control control, bool setSelectionFromUrl)
123                 {
124                         // .NET doesn't check for null here, but since I don't like such code, we
125                         // will do the check and throw the same exception as .NET
126                         if (control == null)
127                                 throw new NullReferenceException ();
128
129                         if (!ControlIsValid (control))
130                                 throw new Exception ("Controls of type " + control.GetType () + " are not supported.");
131
132                         // http://forums.asp.net/p/1257004/2339034.aspx
133                         // http://forums.asp.net/p/1383908/2936065.aspx
134                         DataBoundControl dbc = control as DataBoundControl;
135                         if (dbc != null) {
136                                 IDynamicDataSource dds = dbc.DataSourceObject as IDynamicDataSource;
137                                 if (dds == null)
138                                         return;
139
140                                 RegisterDataSource (dds);
141                                 MetaTable table = dds.GetTable ();
142                                 if (table == null)
143                                         return;
144
145                                 if (String.IsNullOrEmpty (dds.Where))
146                                         dds.AutoGenerateWhereClause = true;
147                                 else
148                                         dds.AutoGenerateWhereClause = false;
149
150                                 Type contextType = dds.ContextType;
151                                 if (contextType == null)
152                                         dds.ContextType = table.DataContextType;
153
154                                 string entityName = dds.EntitySetName;
155                                 if (String.IsNullOrEmpty (entityName))
156                                         dds.EntitySetName = table.DataContextPropertyName;
157
158                                 if (AutoLoadForeignKeys) {
159                                         var ldds = dds as LinqDataSource;
160                                         if (ldds != null)
161                                                 ldds.LoadWithForeignKeys (table.EntityType);
162                                 }
163                                 
164                                 var gv = control as GridView;
165                                 if (gv != null) {
166                                         gv.ColumnsGenerator = new AutoFieldGenerator (table);
167                                         return;
168                                 }
169
170                                 var dv = control as DetailsView;
171                                 if (dv != null) {
172                                         dv.RowsGenerator = new AutoFieldGenerator (table);
173                                         return;
174                                 }
175                         }
176                 }
177
178                 void RegisterDataSource (IDynamicDataSource dds)
179                 {
180                         if (knownDataSources == null) {
181                                 knownDataSources = new Dictionary <IDynamicDataSource, bool> ();
182                                 knownDataSources.Add (dds, true);
183                                 return;
184                         }
185                         
186                         if (knownDataSources.ContainsKey (dds))
187                                 return;
188
189                         knownDataSources.Add (dds, true);
190                 }
191                 
192                 bool ControlIsValid (Control control)
193                 {
194                         if (control is Repeater) {
195                                 if (control.NamingContainer == null)
196                                         throw new HttpException ("The Repeater control '" + control.ID + "' does not have a naming container.");
197                                 return true;
198                         }
199                         
200                         DataBoundControl dbc = control as DataBoundControl;
201                         if (dbc == null)
202                                 return false;
203                         
204                         return true;
205                 }
206         }
207 }