refactoring implementing Page.GetDataItem()
[mono.git] / mcs / class / System.Web / System.Web.UI / TemplateControl.cs
1 //
2 // System.Web.UI.TemplateControl.cs
3 //
4 // Authors:
5 //   Duncan Mak  (duncan@ximian.com)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (C) 2002 Ximian, Inc. (http://www.ximian.com)
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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
32 using System.Collections;
33 using System.ComponentModel;
34 using System.Reflection;
35 using System.Security.Permissions;
36 using System.Web.Compilation;
37 using System.Web.Util;
38
39 namespace System.Web.UI {
40
41         // CAS
42         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
43         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
44 #if NET_2_0
45         public abstract class TemplateControl : Control, INamingContainer, IFilterResolutionService {
46 #else
47         public abstract class TemplateControl : Control, INamingContainer {
48 #endif
49                 static object abortTransaction = new object ();
50                 static object commitTransaction = new object ();
51                 static object error = new object ();
52                 static string [] methodNames = { "Page_Init",
53                                                  "Page_Load",
54                                                  "Page_DataBind",
55                                                  "Page_PreRender",
56                                                  "Page_Disposed",
57                                                  "Page_Error",
58                                                  "Page_Unload",
59                                                  "Page_AbortTransaction",
60                                                  "Page_CommitTransaction" };
61
62                 const BindingFlags bflags = BindingFlags.Public |
63                                             BindingFlags.NonPublic |
64                                             BindingFlags.Instance;
65
66                 #region Constructor
67                 protected TemplateControl ()
68                 {
69                         Construct ();
70                 }
71
72                 #endregion
73
74                 #region Properties
75                 [EditorBrowsable (EditorBrowsableState.Never)]
76 #if NET_2_0
77                 [Obsolete]
78 #endif
79                 protected virtual int AutoHandlers {
80                         get { return 0; }
81                         set { }
82                 }
83
84                 [EditorBrowsable (EditorBrowsableState.Never)]
85                 protected virtual bool SupportAutoEvents {
86                         get { return true; }
87                 }
88
89                 #endregion
90
91                 #region Methods
92
93                 protected virtual void Construct ()
94                 {
95                 }
96
97                 [MonoTODO]
98                 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
99                                                                                     int size,
100                                                                                     bool fAsciiOnly)
101                 {
102                         return null;
103                 }
104
105                 internal void WireupAutomaticEvents ()
106                 {
107                         if (!SupportAutoEvents || !AutoEventWireup)
108                                 return;
109
110                         Type type = GetType ();
111                         foreach (string methodName in methodNames) {
112                                 MethodInfo method = type.GetMethod (methodName, bflags);
113                                 if (method == null)
114                                         continue;
115
116                                 if (method.DeclaringType != type) {
117                                         if (!method.IsPublic && !method.IsFamilyOrAssembly &&
118                                             !method.IsFamilyAndAssembly && !method.IsFamily)
119                                                 continue;
120                                 }
121
122                                 if (method.ReturnType != typeof (void))
123                                         continue;
124
125                                 ParameterInfo [] parms = method.GetParameters ();
126                                 int length = parms.Length;
127                                 bool noParams = (length == 0);
128                                 if (!noParams && (length != 2 ||
129                                     parms [0].ParameterType != typeof (object) ||
130                                     parms [1].ParameterType != typeof (EventArgs)))
131                                     continue;
132
133                                 int pos = methodName.IndexOf ("_");
134                                 string eventName = methodName.Substring (pos + 1);
135                                 EventInfo evt = type.GetEvent (eventName);
136                                 if (evt == null) {
137                                         /* This should never happen */
138                                         continue;
139                                 }
140
141                                 if (noParams) {
142                                         NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
143                                         evt.AddEventHandler (this, npi.FakeDelegate);
144                                 } else {
145                                         evt.AddEventHandler (this, Delegate.CreateDelegate (
146                                                         typeof (EventHandler), this, methodName));
147                                 }
148                         }
149                 }
150
151                 [EditorBrowsable (EditorBrowsableState.Never)]
152                 protected virtual void FrameworkInitialize ()
153                 {
154                 }
155
156                 Type GetTypeFromControlPath (string virtualPath)
157                 {
158                         if (virtualPath == null)
159                                 throw new ArgumentNullException ("virtualPath");
160
161                         string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
162                         string realpath = Context.Request.MapPath (vpath);
163                         return UserControlParser.GetCompiledType (vpath, realpath, Context);
164                 }
165
166                 public Control LoadControl (string virtualPath)
167                 {
168 #if NET_2_0
169                         if (virtualPath == null)
170                                 throw new ArgumentNullException ("virtualPath");
171 #else
172                         if (virtualPath == null)
173                                 throw new HttpException ("virtualPath is null");
174 #endif
175                         Type type = GetTypeFromControlPath (virtualPath);
176                         object [] attrs = type.GetCustomAttributes (typeof (PartialCachingAttribute), true);
177                         if (attrs != null && attrs.Length == 1) {
178                                 PartialCachingAttribute attr = (PartialCachingAttribute) attrs [0];
179                                 PartialCachingControl ctrl = new PartialCachingControl (type);
180                                 ctrl.VaryByParams = attr.VaryByParams;
181                                 ctrl.VaryByControls = attr.VaryByControls;
182                                 ctrl.VaryByCustom = attr.VaryByCustom;
183                                 return ctrl;
184                         }
185
186                         object control = Activator.CreateInstance (type);
187                         if (control is UserControl)
188                                 ((UserControl) control).InitializeAsUserControl (Page);
189
190                         return (Control) control;
191                 }
192
193                 public ITemplate LoadTemplate (string virtualPath)
194                 {
195 #if NET_2_0
196                         if (virtualPath == null)
197                                 throw new ArgumentNullException ("virtualPath");
198 #else
199                         if (virtualPath == null)
200                                 throw new HttpException ("virtualPath is null");
201 #endif
202                         Type t = GetTypeFromControlPath (virtualPath);
203                         return new SimpleTemplate (t);
204                 }
205
206                 protected virtual void OnAbortTransaction (EventArgs e)
207                 {
208                         EventHandler eh = Events [abortTransaction] as EventHandler;
209                         if (eh != null)
210                                 eh (this, e);
211                 }
212
213                 protected virtual void OnCommitTransaction (EventArgs e)
214                 {
215                         EventHandler eh = Events [commitTransaction] as EventHandler;
216                         if (eh != null)
217                                 eh (this, e);
218                 }
219
220                 protected virtual void OnError (EventArgs e)
221                 {
222                         EventHandler eh = Events [error] as EventHandler;
223                         if (eh != null)
224                                 eh (this, e);
225                 }
226
227                 [MonoTODO]
228                 public Control ParseControl (string content)
229                 {
230                         if (content == null)
231                                 throw new ArgumentNullException ("content");
232
233                         return null;
234                 }
235
236                 [EditorBrowsable (EditorBrowsableState.Never)]
237                 public 
238 #if !NET_2_0
239                 static
240 #endif
241                 object ReadStringResource ()
242                 {
243                         throw new NotSupportedException ();
244                 }
245
246                 [EditorBrowsable (EditorBrowsableState.Never)]
247                 public static object ReadStringResource (Type t)
248                 {
249                         throw new NotSupportedException ();
250                 }
251
252                 [MonoTODO]
253                 [EditorBrowsable (EditorBrowsableState.Never)]
254                 protected void SetStringResourcePointer (object stringResourcePointer,
255                                                          int maxResourceOffset)
256                 {
257                 }
258
259                 [MonoTODO]
260                 [EditorBrowsable (EditorBrowsableState.Never)]
261                 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
262                                                         int size, bool fAsciiOnly)
263                 {
264                 }
265
266                 #endregion
267
268                 #region Events
269
270                 [WebSysDescription ("Raised when the user aborts a transaction.")]
271                 public event EventHandler AbortTransaction {
272                         add { Events.AddHandler (abortTransaction, value); }
273                         remove { Events.RemoveHandler (abortTransaction, value); }
274                 }
275
276                 [WebSysDescription ("Raised when the user initiates a transaction.")]
277                 public event EventHandler CommitTransaction {
278                         add { Events.AddHandler (commitTransaction, value); }
279                         remove { Events.RemoveHandler (commitTransaction, value); }
280                 }
281
282                 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
283                 public event EventHandler Error {
284                         add { Events.AddHandler (error, value); }
285                         remove { Events.RemoveHandler (error, value); }
286                 }
287
288                 #endregion
289
290                 class SimpleTemplate : ITemplate
291                 {
292                         Type type;
293
294                         public SimpleTemplate (Type type)
295                         {
296                                 this.type = type;
297                         }
298
299                         public void InstantiateIn (Control control)
300                         {
301                                 Control template = Activator.CreateInstance (type) as Control;
302                                 template.SetBindingContainer (false);
303                                 control.Controls.Add (template);
304                         }
305                 }
306
307 #if NET_2_0
308                 protected object Eval (string expression)
309                 {
310                         return DataBinder.Eval (Page.GetDataItem(), expression);
311                 }
312         
313                 protected string Eval (string expression, string format)
314                 {
315                         return DataBinder.Eval (Page.GetDataItem(), expression, format);
316                 }
317         
318                 protected object XPath (string xpathexpression)
319                 {
320                         return XPathBinder.Eval (Page.GetDataItem(), xpathexpression);
321                 }
322         
323                 protected string XPath (string xpathexpression, string format)
324                 {
325                         return XPathBinder.Eval (Page.GetDataItem(), xpathexpression, format);
326                 }
327         
328                 protected IEnumerable XPathSelect (string xpathexpression)
329                 {
330                         return XPathBinder.Select (Page.GetDataItem(), xpathexpression);
331                 }
332
333                 // IFilterResolutionService
334
335                 [MonoTODO]
336                 int IFilterResolutionService.CompareFilters (string filter1, string filter2)
337                 {
338                         throw new NotImplementedException ();
339                 }
340
341                 [MonoTODO]
342                 bool IFilterResolutionService.EvaluateFilter (string filterName)
343                 {
344                         throw new NotImplementedException ();
345                 }
346 #endif
347         }
348 }