24ba6f00ddccc1b98219505eaf2b5576871518d8
[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 using System.Xml;
39
40 namespace System.Web.UI {
41
42         // CAS
43         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
44         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45 #if NET_2_0
46         public abstract class TemplateControl : Control, INamingContainer, IFilterResolutionService {
47 #else
48         public abstract class TemplateControl : Control, INamingContainer {
49 #endif
50                 static readonly Assembly _System_Web_Assembly = typeof (TemplateControl).Assembly;
51                 static object abortTransaction = new object ();
52                 static object commitTransaction = new object ();
53                 static object error = new object ();
54                 static string [] methodNames = { "Page_Init",
55 #if NET_2_0
56                                                  "Page_PreInit",
57                                                  "Page_PreLoad",
58                                                  "Page_LoadComplete",
59                                                  "Page_PreRenderComplete",
60                                                  "Page_SaveStateComplete",
61                                                  "Page_InitComplete",
62 #endif
63                                                  "Page_Load",
64                                                  "Page_DataBind",
65                                                  "Page_PreRender",
66                                                  "Page_Disposed",
67                                                  "Page_Error",
68                                                  "Page_Unload",
69                                                  "Page_AbortTransaction",
70                                                  "Page_CommitTransaction"};
71
72                 const BindingFlags bflags = BindingFlags.Public |
73                                             BindingFlags.NonPublic |
74                                             BindingFlags.Instance;
75
76 #if NET_2_0
77                 string _appRelativeVirtualPath;
78 #endif
79                 
80                 #region Constructor
81                 protected TemplateControl ()
82                 {
83                         Construct ();
84                 }
85
86                 #endregion
87
88                 #region Properties
89                 [EditorBrowsable (EditorBrowsableState.Never)]
90 #if NET_2_0
91                 [Obsolete]
92 #endif
93                 protected virtual int AutoHandlers {
94                         get { return 0; }
95                         set { }
96                 }
97
98                 [EditorBrowsable (EditorBrowsableState.Never)]
99                 protected virtual bool SupportAutoEvents {
100                         get { return true; }
101                 }
102
103 #if NET_2_0
104                 public string AppRelativeVirtualPath {
105                         get { return _appRelativeVirtualPath; }
106                         set { _appRelativeVirtualPath = value; }
107                 }
108 #endif
109
110                 #endregion
111
112                 #region Methods
113
114                 protected virtual void Construct ()
115                 {
116                 }
117
118                 [MonoTODO ("Not implemented")]
119                 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
120                                                                                     int size,
121                                                                                     bool fAsciiOnly)
122                 {
123                         return null;
124                 }
125
126                 internal void WireupAutomaticEvents ()
127                 {
128                         if (!SupportAutoEvents || !AutoEventWireup)
129                                 return;
130
131                         foreach (string methodName in methodNames) {
132                                 MethodInfo method = null;
133                                 Type type;
134                                 for (type = GetType (); type.Assembly != _System_Web_Assembly; type = type.BaseType) {
135                                         method = type.GetMethod (methodName, bflags);
136                                         if (method != null)
137                                                 break;
138                                 }
139                                 if (method == null)
140                                         continue;
141
142                                 if (method.DeclaringType != type) {
143                                         if (!method.IsPublic && !method.IsFamilyOrAssembly &&
144                                             !method.IsFamilyAndAssembly && !method.IsFamily)
145                                                 continue;
146                                 }
147
148                                 if (method.ReturnType != typeof (void))
149                                         continue;
150
151                                 ParameterInfo [] parms = method.GetParameters ();
152                                 int length = parms.Length;
153                                 bool noParams = (length == 0);
154                                 if (!noParams && (length != 2 ||
155                                     parms [0].ParameterType != typeof (object) ||
156                                     parms [1].ParameterType != typeof (EventArgs)))
157                                     continue;
158
159                                 int pos = methodName.IndexOf ("_");
160                                 string eventName = methodName.Substring (pos + 1);
161                                 EventInfo evt = type.GetEvent (eventName);
162                                 if (evt == null) {
163                                         /* This should never happen */
164                                         continue;
165                                 }
166
167                                 if (noParams) {
168                                         NoParamsInvoker npi = new NoParamsInvoker (this, method);
169                                         evt.AddEventHandler (this, npi.FakeDelegate);
170                                 } else {
171                                         evt.AddEventHandler (this, Delegate.CreateDelegate (
172 #if NET_2_0
173                                                         typeof (EventHandler), this, method));
174 #else
175                                                         typeof (EventHandler), this, methodName));
176 #endif
177                                 }
178                         }
179                 }
180
181                 [EditorBrowsable (EditorBrowsableState.Never)]
182                 protected virtual void FrameworkInitialize ()
183                 {
184                 }
185
186                 Type GetTypeFromControlPath (string virtualPath)
187                 {
188                         if (virtualPath == null)
189                                 throw new ArgumentNullException ("virtualPath");
190
191                         string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
192                         string realpath = Context.Request.MapPath (vpath);
193                         return UserControlParser.GetCompiledType (vpath, realpath, Context);
194                 }
195
196                 public Control LoadControl (string virtualPath)
197                 {
198 #if NET_2_0
199                         if (virtualPath == null)
200                                 throw new ArgumentNullException ("virtualPath");
201 #else
202                         if (virtualPath == null)
203                                 throw new HttpException ("virtualPath is null");
204 #endif
205                         Type type = GetTypeFromControlPath (virtualPath);
206                         return LoadControl (type, null);
207                 }
208
209                 public Control LoadControl (Type type, object[] parameters) 
210                 {
211                         object [] attrs = type.GetCustomAttributes (typeof (PartialCachingAttribute), true);
212                         if (attrs != null && attrs.Length == 1) {
213                                 PartialCachingAttribute attr = (PartialCachingAttribute) attrs [0];
214                                 PartialCachingControl ctrl = new PartialCachingControl (type, parameters);
215                                 ctrl.VaryByParams = attr.VaryByParams;
216                                 ctrl.VaryByControls = attr.VaryByControls;
217                                 ctrl.VaryByCustom = attr.VaryByCustom;
218                                 return ctrl;
219                         }
220
221                         object control = Activator.CreateInstance (type, parameters);
222                         if (control is UserControl)
223                                 ((UserControl) control).InitializeAsUserControl (Page);
224
225                         return (Control) control;
226                 }
227
228                 public ITemplate LoadTemplate (string virtualPath)
229                 {
230 #if NET_2_0
231                         if (virtualPath == null)
232                                 throw new ArgumentNullException ("virtualPath");
233 #else
234                         if (virtualPath == null)
235                                 throw new HttpException ("virtualPath is null");
236 #endif
237                         Type t = GetTypeFromControlPath (virtualPath);
238                         return new SimpleTemplate (t);
239                 }
240
241                 protected virtual void OnAbortTransaction (EventArgs e)
242                 {
243                         EventHandler eh = Events [abortTransaction] as EventHandler;
244                         if (eh != null)
245                                 eh (this, e);
246                 }
247
248                 protected virtual void OnCommitTransaction (EventArgs e)
249                 {
250                         EventHandler eh = Events [commitTransaction] as EventHandler;
251                         if (eh != null)
252                                 eh (this, e);
253                 }
254
255                 protected virtual void OnError (EventArgs e)
256                 {
257                         EventHandler eh = Events [error] as EventHandler;
258                         if (eh != null)
259                                 eh (this, e);
260                 }
261
262                 [MonoTODO ("Not implemented, always returns null")]
263                 public Control ParseControl (string content)
264                 {
265                         if (content == null)
266                                 throw new ArgumentNullException ("content");
267
268                         return null;
269                 }
270
271                 [EditorBrowsable (EditorBrowsableState.Never)]
272                 public 
273 #if !NET_2_0
274                 static
275 #endif
276                 object ReadStringResource ()
277                 {
278                         throw new NotSupportedException ();
279                 }
280
281 #if NET_2_0
282                 protected object GetGlobalResourceObject (string className, string resourceKey)
283                 {
284                         return HttpContext.GetGlobalResourceObject (className, resourceKey);
285                 }
286
287                 [MonoTODO ("Not implemented")]
288                 protected object GetGlobalResourceObject (string className, string resourceKey, Type objType, string propName)
289                 {
290                         // FIXME: not sure how to implement that one yet
291                         throw new NotSupportedException();
292                 }
293
294                 protected object GetLocalResourceObject (string resourceKey)
295                 {
296                         return HttpContext.GetLocalResourceObject (VirtualPathUtility.ToAbsolute (this.AppRelativeVirtualPath),
297                                                                    resourceKey);
298                 }
299                 
300                 protected object GetLocalResourceObject (string resourceKey, Type objType, string propName)
301                 {
302                         // FIXME: not sure how to implement that one yet
303                         throw new NotSupportedException();
304                 }
305 #endif
306                 
307                 [EditorBrowsable (EditorBrowsableState.Never)]
308                 public static object ReadStringResource (Type t)
309                 {
310                         throw new NotSupportedException ();
311                 }
312
313                 [MonoTODO ("Not implemented, does nothing")]
314                 [EditorBrowsable (EditorBrowsableState.Never)]
315                 protected void SetStringResourcePointer (object stringResourcePointer,
316                                                          int maxResourceOffset)
317                 {
318                 }
319
320                 [MonoTODO ("Not implemented, does nothing")]
321                 [EditorBrowsable (EditorBrowsableState.Never)]
322                 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
323                                                         int size, bool fAsciiOnly)
324                 {
325                 }
326
327                 #endregion
328
329                 #region Events
330
331                 [WebSysDescription ("Raised when the user aborts a transaction.")]
332                 public event EventHandler AbortTransaction {
333                         add { Events.AddHandler (abortTransaction, value); }
334                         remove { Events.RemoveHandler (abortTransaction, value); }
335                 }
336
337                 [WebSysDescription ("Raised when the user initiates a transaction.")]
338                 public event EventHandler CommitTransaction {
339                         add { Events.AddHandler (commitTransaction, value); }
340                         remove { Events.RemoveHandler (commitTransaction, value); }
341                 }
342
343                 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
344                 public event EventHandler Error {
345                         add { Events.AddHandler (error, value); }
346                         remove { Events.RemoveHandler (error, value); }
347                 }
348
349                 #endregion
350
351                 class SimpleTemplate : ITemplate
352                 {
353                         Type type;
354
355                         public SimpleTemplate (Type type)
356                         {
357                                 this.type = type;
358                         }
359
360                         public void InstantiateIn (Control control)
361                         {
362                                 Control template = Activator.CreateInstance (type) as Control;
363                                 template.SetBindingContainer (false);
364                                 control.Controls.Add (template);
365                         }
366                 }
367
368 #if NET_2_0
369                 protected internal object Eval (string expression)
370                 {
371                         return DataBinder.Eval (Page.GetDataItem(), expression);
372                 }
373         
374                 protected internal string Eval (string expression, string format)
375                 {
376                         return DataBinder.Eval (Page.GetDataItem(), expression, format);
377                 }
378         
379                 protected internal object XPath (string xpathexpression)
380                 {
381                         return XPathBinder.Eval (Page.GetDataItem(), xpathexpression);
382                 }
383         
384                 protected internal object XPath (string xpathexpression, IXmlNamespaceResolver resolver)
385                 {
386                         return XPathBinder.Eval (Page.GetDataItem (), xpathexpression, null, resolver);
387                 }
388
389                 protected internal string XPath (string xpathexpression, string format)
390                 {
391                         return XPathBinder.Eval (Page.GetDataItem(), xpathexpression, format);
392                 }
393         
394                 protected internal string XPath (string xpathexpression, string format, IXmlNamespaceResolver resolver)
395                 {
396                         return XPathBinder.Eval (Page.GetDataItem (), xpathexpression, format, resolver);
397                 }
398
399                 protected internal IEnumerable XPathSelect (string xpathexpression)
400                 {
401                         return XPathBinder.Select (Page.GetDataItem(), xpathexpression);
402                 }
403
404                 protected internal IEnumerable XPathSelect (string xpathexpression, IXmlNamespaceResolver resolver)
405                 {
406                         return XPathBinder.Select (Page.GetDataItem (), xpathexpression, resolver);
407                 }
408
409                 // IFilterResolutionService
410
411                 [MonoTODO ("Not implemented")]
412                 int IFilterResolutionService.CompareFilters (string filter1, string filter2)
413                 {
414                         throw new NotImplementedException ();
415                 }
416
417                 [MonoTODO ("Not implemented")]
418                 bool IFilterResolutionService.EvaluateFilter (string filterName)
419                 {
420                         throw new NotImplementedException ();
421                 }
422 #endif
423         }
424 }