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